Clifton Labrum
Clifton Labrum

Reputation: 14158

SwiftUI: Different Widths for Multiline Text Views in Boxes

Here is how two boxes with text are rendering in SwiftUI, but I want them to both be full-width:

enter image description here

Here is my code:

VStack(spacing: 20){
  //Help ---
  VStack(alignment: .leading, spacing:10){
    Text("Help").h2()
    Text("Please view our online user guide before contacting us since we answer most questions there.")
      .lineLimit(nil) //Make the text wrap
      .prefsText()
    
    Button("Online Help"){
      openURL(URL(string: "https://avid.pro/help")!)
    }.foregroundColor(Color(accentColor))
    .buttonStyle(PlainButtonStyle())
    .prefsLink()
    
  }.unoBoxRoundPad()
  .frame(maxWidth: .infinity)
  
  //Support ---
  VStack(alignment: .leading, spacing:10){
    Text("Support").h2()
    Text("Email us if you need to submit a bug or get specialized help. It may take us a few days to get back to you.")
      .lineLimit(nil) //Make the text wrap
      .prefsText()
  
    Button("Email Us"){
      openURL(URL(string: "mailto:[email protected]")!)
    }.foregroundColor(Color(accentColor))
    .buttonStyle(PlainButtonStyle())
    .prefsLink()
    
  }.unoBoxRoundPad()
  .frame(maxWidth: .infinity)

}.background(Color.yellow) //For testing

I can't for the life of me figure out why they aren't the same width. .unoBoxRoundPad() is a view modifier that adds these shared styles:

.padding(20)
.background(Color("UnoDark"))
.cornerRadius(7)

If I put .frame(maxWidth: .infinity) on the Text() instead of on the containing VStack, it seems to get a little closer, but then it disregards the containing view's padding():

enter image description here

Any ideas on what I'm doing wrong?

Upvotes: 2

Views: 682

Answers (1)

Dave DeLong
Dave DeLong

Reputation: 243156

There are two issues at play here:

  1. You've got two modifiers swapped (.frame(...) and .unoBoxRoundPad()); you want the roundedness to apply to the entire stretched thing. By putting .unoBoxRoundPad() first, you're saying "pad this thing" and then "place that rounded thing inside an infinitely-wide box"; you want the reverse: your thing should be placed inside an infinitely-wide box, and it's the infinitely wide box that should have the rounded corners and padding.

  2. You need to specify an alignment: when using that .frame() modifier; when the inner view is placed inside an infinitely-wide box, it's going to default to being centered vertically and horizontally inside it. Based on your screenshots, you probably want to use .topLeading so that the content ("Support", "Help", etc) start in the top-left corner (or top-right in RTL languages).

Upvotes: 6

Related Questions