Home > Software design >  Change View depending on dynamic widths (SwiftUI)
Change View depending on dynamic widths (SwiftUI)

Time:03-02

I'm struggling to make a View which changes depending on how large its contents' widths are. Perhaps I'm not approaching the problem correctly?

Take this example View, designed to be one of many items in a vertical List:

Hstack {
  Text(leftText)
  Spacer()
  Text(rightText)
}

Given that leftText and rightText are subject to change, how does one change this view to look cleaner if the Text Views become too large to fit on the same row? e.g.

VStack (alignment: .leading) {
  Text(leftText)
  HStack {
    Spacer()
    Text(rightText)
  }
}

The only solution I've come up with is measuring the rightText View by duplicating it and hiding it elsewhere (in a ZStack, so it doesn't mess up the UI spacing). This ends up being rather messy and wasteful, as the right View may not be as cheap as simple Text Views. Does anyone know a better way to approach this?

CodePudding user response:

I agree with Lorem that the question is a little vague, but here are a few suggestions that might (perhaps) fit your needs.

  1. Could you live with having both leftText and rightText multi-lined? The modifier is .lineLimit(n) where n is the maximum number of lines you want to allow.
  2. Would a different truncation pattern work? The default is to have the trailing end of the text truncated. However, you can specify an alternative mode, such as .truncationMode(.middle) instead.
  3. One caveat about combining these solutions, it seems to me that truncationMode only works when the lineLimit is exactly 1.

CodePudding user response:

In case you want some thing similar like this

List with 2 texts for each row

Here is the code

fileprivate let loremipsumText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
fileprivate func getRandomText() -> String {
    String(loremipsumText.prefix(Int.random(in: 1 ..< loremipsumText.count)))
}

struct TextContainer: View {
    var text: String
    var body: some View {
        ZStack {
            Color.orange.cornerRadius(4)
            Text(text)
                .frame(maxWidth: UIScreen.main.bounds.width * 0.4)
                .padding(3)
        }
    }
}

struct TestListViewDoubleText: View {
    var body: some View {
        List {
            ForEach(0..<20) { _ in
                HStack {
                    TextContainer(text: getRandomText())
                    Spacer()
                    TextContainer(text: getRandomText())
                }
            }
        }
    }
}
  • Related