toolbar text item gets cropped - swift

There is a very weird behavior happening with the toolbar, I have the following:
.toolbar {
ToolbarItem(placement: .principal) {
HStack {
Imagegoeshere...
.frame(width: 20, height: 20)
Text("Polkadot")
// Text(coinInfo?.name ?? "-")
}
}
}
Just like that it displays correct the image and on the right the name "Polkadot" (that's for testing), if I replace that Text("Polkadot") with the real value (which contains the exact text with no spaces) it crops it: Text(coinInfo?.name ?? "-")
This is how it looks with the testing text:
and this is how it looks with the real value yet the same exact text:
Any idea what could be causing this?

By accident just now I found the solution, still I have no idea why this happens, this is how it got fixed:
Replace the HStack with LazyHStack

Related

Can you access Picker elements during runtime and change their color

I want to change the color of the current selected Element of the Picker. Is this possible? This is my code.
Picker("Select a Project", selection: $selectedProjectString){
ForEach(projects, id: \.self) {
Text($0).lineLimit(1).frame(height:120)
}
}.foregroundColor(Color.white)
.frame(height: 120)
The element that matches selectedProjectString should be a different color than all the others. Or is it possible to access specific elements like with an index or something?
I came up with this solution:
Picker("Select a Project", selection: $selectedProjectString){
ForEach(projects, id: \.self) {
if (startedProject == $0) {
Text($0).lineLimit(1).frame(height:120).foregroundColor(Color.red)
} else {
Text($0).lineLimit(1).frame(height:120)
}
}
}.foregroundColor(Color.white)
.frame(height: 120)
I check if the selected element equals some value and if, I change the style of the Text object it belongs.
Because i change the value of the variable, the view gets reloaded and it refreshes my picker. Now the selected element has color.

maxWidth infinity failure SwiftUI

I have the following code:
Button(action: {
}, label: {
Text("Save".uppercased())
.foregroundColor(.white)
.font(.headline)
.background(Color.accentColor)
.frame(height: 55)
.frame(maxWidth: .infinity)
.cornerRadius(10)
})
}
.padding(14)
I've checked it over and am clearly missing something because the max width is not working whatsoever. The button is still tightly confined around the "SAVE" text. I have also tried manually adjusting the width but this hasn't changed anything.
Any suggestions? I am running XCode 13.
Order matters a lot in view modifiers ;)
I suppose you want this:
Text("Save".uppercased())
.frame(maxWidth: .infinity)
.frame(height: 55)
.background(Color.accentColor)
.cornerRadius(10)
.foregroundColor(.white)
.font(.headline)
The Text itself is only as tall & wide as it needs to be, so first the frames to define the size, then the background color for that area, then the corner radius.
Foreground color and font can go anywhere.
You can see and check many of the (also if working) effects in the preview, where you can select single lines of code and see the resulting frame.

SwiftUI Form Label above Text field Section Spacing

I am attempting to create a form in SwiftUI that has the Label above the text input field all the time.
A good example is looking at a contact on an iPhone 12. There are two standalone inputs (among others). Mobile and Notes respectively.
They look and space just how I would like mine.
No matter how I change the following code I always have a large space at the top and the fields themselves have huge spaces in between the Sections.
Form {
Section() {
VStack(alignment: .leading) {
Text("Field1")
TextField("...", text: $Field1)
}
.padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))
}
Section() {
VStack(alignment: .leading) {
Text("Field2")
TextField("...", text: $Field2)
}
.padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))
}
}
If the Form tag here is the issue is it better to remove it and do it all manually. Apple do seem to want you to use the Form tag for cross compatibility. In my case its for iPads and iPhones.
As I said in my comments, you could also put your field title in as the Section header. Also, this is your UI, make it how you want. My only comment about it was to think of the usability when designing it. Your answer gives what looks to be a large target for the user, but in reality is only half that size. I am not saying it is wrong for your app, only that you should consider it.
Form {
Section(header: Text("Field1") ) {
TextField("Required", text: $Field1)
// With padding that is equivalent to your padding.
.padding(.vertical, 10)
// .padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))
}
Section(header: Text("Field2") ) {
TextField("Optional", text: $Field2)
// Without padding...
}
Section(header: Text("Field3") ) {
TextField("Optional", text: $Field2)
// With padding that is determined by the system.
.padding(.vertical)
}
}
Obviously, this gives you a different look. As you will notice, I gave you three different .padding() looks. One is yours, instead using .vertical (sets .top and .bottom to be the same) with the same constant. The next is no padding around the field. The last in allowing the system to choose your padding.
My first answer to my own question. This is what I came up with (but decided not to use).
It's pretty much what I wanted in the look.
It seems that Apple really do want to force you to do it "their way".
It is difficult to alter the Form view format without everything you try having some unrequired knock on effect.
I agree with some of the comments that this does look correct but it doesn't have the best UI experience.
Form {
Section() {
VStack(alignment: .leading) {
Text("Field1")
.font(.headline)
TextField("Required", text: $Field1)
}
.padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))
VStack(alignment: .leading) {
Text("Field2")
.font(.headline)
TextField("Optional", text: $Field2)
}
.padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))
}
Section {
NavigationLink(destination: SomeView()) {
Text("Next")
.padding()
.foregroundColor(Color.blue)
}
}
}
.navigationBarTitle("Main Title")
My second answer to my own question. This is what I came up with.
I decided to go down the route of a separate label above a text input control using the header as the label. This does have a different look.
This is simply because the original look I was after didn't have the best UI experience.
It is possible to add extra code but it starts to get far to over complicated.
Form {
Section(header: Text("Field1") // Label
.font(.headline)
.foregroundColor(.black)
// The padding top is larger on the first control to make it stand out more from the navigation bar title.
.padding(EdgeInsets(top: 30, leading: 5, bottom: 0, trailing: 0))) {
TextField("Required", text: $Field1)
}
.textCase(nil) // I dont want the label to be all uppercase.
Section(header: Text("Field2") // Label
.font(.headline)
.foregroundColor(.black)
.padding(EdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 0))) {
TextField("Required", text: $Field1)
}
.textCase(nil)
Section {
NavigationLink(destination: SomeView()) {
Text("Next")
.padding()
.foregroundColor(Color.blue)
}
}
}
.navigationBarTitle("Main Title")

How do I access a custom color that is part of a struct?

I'm trying to assign a color to the following button that I gave to a member of a struct previously, yet I keep getting compiler errors. Here's what my code is:
var sampleGameView: gameViewState = gameViewState(
Outs: 2,
Balls: 1,
Strikes: 1,
Runner1: true,
Runner2: true,
Runner3: false,
HomeTeam: "MIA",
AwayTeam: "ATL",
HomeTeamColor: Color("SampleGameViewATL"),
AwayTeamColor: Color("SampleGameViewMIA"),
InningTop: false,
InningNumber: 4,
HomeTeamScore: 0,
AwayTeamScore: 1,
CurrentBatterFirst: "Starling",
CurrentBatterLast: "Marte",
CurrentPitcherFirst: "Max",
CurrentPitcherLast: "Fried"
)
As you can see, sampleGameView has two Color properties. However, when I try to assign them to a Button like so, I get errors:
Button(action: {}) {
VStack {
Text(sampleGameView.CurrentPitcherFirst)
Text(sampleGameView.CurrentPitcherLast)
.fontWeight(.bold)
.textCase(.uppercase)
}
.padding()
}
.foregroundColor(.white)
.frame(width: 170, height: 75)
.background(Color("sampleGameView.HomeTeamColor")) // error is on this line
.cornerRadius(10)
I've tried accessing the color without quotes at all, and also with string interpolation, neither of which works :/
Can someone tell me what the correct syntax is for a situation like this? Thank you!
Remove double quotes and Color object constructor.
.background(sampleGameView.HomeTeamColor)
Note: Struct and Class name start with capital character and properties start with small character.

SwiftUI Form Picker with text and Image

I am trying to create a form picker that shows the currently selected image resource at the top level and when the user selects it to show the detail, I want it to show all of the image resources available.
Here is the relevant section of code:
Picker("Background image:", selection: $task.background) {
ForEach(0 ..< backgroundImages.count) {
Image("Background\($0)").resizable().frame(width: 100, height: 35, alignment: .center)
Text("Background\($0)")
}
}
The problem with this is that in the detail screen I get:
The image is blank and the image and text appear on 2 different rows.
I have tried wrapping the Image and Text lines in an HStack, but that gives a compile time error on some other line. Any suggestions would be helpful.
The following should compile & work well (tested with replaced system images, Xcode 11.2)
Picker("Background image:", selection: $task.background) {
ForEach(0 ..< backgroundImages.count) { i in
HStack {
Image("Background\(i)").resizable().frame(width: 100, height: 35, alignment: .center)
Text("Background\(i)")
}
}
}