SwiftUI : How to ignore NavigationView When Add ScrollView - swift

My previous code is
VStack {
MapView(coordinate: landmark.locationCoordinate)
.frame(height: 300, alignment: .center)
.edgesIgnoringSafeArea(.top)
CircleImageView(image: landmark.image)
VStack(alignment: .leading) {
Text("\(landmark.name)")
.font(.title)
.multilineTextAlignment(.center)
HStack {
Text("\(landmark.park)")
Spacer()
Text("\(landmark.state)")
}
.font(.subheadline)
.foregroundColor(.secondary)
Divider()
Text("\(landmark.category)")
.font(.title2)
Text("\(landmark.description)")
}
.padding()
Spacer()
}
My current build works fine. But when I add ScrollView as parent of my code, the map does not ignore the safe area.
Current build
After adding ScrollView
I used edgesIgnoringSafeArea(.all) but it didn't work. By the way, I am new to SwiftUI so I will appreciate any help.

Related

How to align text to the left and in the middle of a view

I have two Texts: Text("1") and Text("2") in an HStack. I want Text("1") to be in the leftmost part of ContentView and Text("2") to be in the exact horizontal center of ContentView.
Here's my code:
import SwiftUI
struct ContentView: View {
var body: some View {
HStack {
Text("1")
.multilineTextAlignment(.leading)
.frame(
alignment: .leading
)
Text("2")
.multilineTextAlignment(.center)
.frame(
alignment: .center
)
}
.frame(width: .infinity)
}
}
When I run this though, both Text("1") and Text("2") remain in the general horizontal center of ContentView. Not sure what I'm doing wrong.
Here's another way you can do this by using ZStack. Second text will always be in exact centre.
ZStack {
HStack {
Text("1")
Spacer()
}
HStack {
Spacer()
Text("2")
Spacer()
}
}
.padding()
Try the below code:
HStack {
Text("1")
.multilineTextAlignment(.leading)
Text("2")
.multilineTextAlignment(.center)
.frame(minWidth: 0, maxWidth: .infinity)
}
Add a Spacer to your HStack after each Text. This will give you the first Text at the left and the second starting in the middle
HStack {
Text("1")
.multilineTextAlignment(.leading)
.frame(alignment: .leading)
.padding(.leading)
Spacer()
Text("2")
.multilineTextAlignment(.center)
.frame(alignment: .center)
.padding(.trailing)
Spacer()
}

SwiftUI: Navigation link alignment with the newer navigation stack

I am using the new NavigationStack and I have a VStack with the code below:
VStack(alignment: .leading) {
NavigationLink(post.phrase, value: post)
.lineLimit(2)
.font(.system(size: 20))
.multilineTextAlignment(.leading)
.foregroundColor(.black)
Text(post.Translation.chinese)
.lineLimit(1)
}
The NavigationLink is always centrally aligned but the Text is ok which is left aligned. Is there a way to force the 2-line NavigationLink to align to the left?
The code below will correctly align the navigation link:
VStack(alignment: .leading) {
NavigationLink(value: post) {
Text(post.phrase)
.lineLimit(2)
.font(.system(size: 20))
.multilineTextAlignment(.leading)
.foregroundColor(.black)
}
Text(post.Translation.chinese)
.lineLimit(1)
}

My TextField in Swift UI is Unresponsive to taps and clicks, text cannot be input, is there an issue with the code?

Hi I'm an intermediate level engineer with swift and swift UI.
Currently, I am having problems with the TextField(), it is unresponsive to taps and clicks, and hence the keyboard does not show up,
However, it does show up when it is one of two main elements within a VStack, but anymore than that and it does not work,
Is there an issue with the code? and can anyone find a fix or a work around for this?
Thanks, Miles
{
#State var textField = ""
var body: some View {
returnJoinModalContent()
}
func returnJoinModalContent() -> some View{
let accentColor = Color.blue
return VStack(alignment: .center){
HStack{
Text("Join Game")
.bold()
.font(.largeTitle)
.padding()
Spacer()
Button(action:{
//self.hideModal()
}){
Image(systemName: "xmark.circle.fill")
.resizable()
.frame(width: 50,height: 50)
.foregroundColor(accentColor)
.padding()
}
}
.padding(.bottom,170)
VStack(alignment: .leading){
TextField("Enter Game Code",text: self.$textField)
.font(.largeTitle)
Rectangle()
.frame(height: 6)
.foregroundColor(accentColor)
}
.padding()
HStack{
Button(action:{
//self.joinGame()
}){
ZStack{
RoundedRectangle(cornerRadius: 90)
.frame(width: 200,height: 70)
.foregroundColor(accentColor)
Text("Ready!")
.bold()
.font(.title)
.foregroundColor(Color.white)
}
}
}
.padding(.vertical,20)
HStack{
Image(systemName: "info.circle")
.resizable()
.frame(width:60,height:60)
.foregroundColor(accentColor)
Text("Ask your host for the game code, it can be found at the bottom of the player lobby")
.padding()
Spacer()
}
.padding(.top,60)
.padding(.horizontal,20)
Spacer()
}
.padding()
}
}
This seems to be one of those things in swiftUI that is difficult to track down. I found the problem is your ready button. More specifically the label being a ZStack with a colored rounded rectangle as the background. If you replace your button's label with the following your text field should be selectable.
Text("Ready!")
.bold()
.font(.title)
.foregroundColor(Color.white)
.frame(width: 200,height: 70)
.background(accentColor)
.mask(RoundedRectangle(cornerRadius: 90))
I've found that overlay on the TextField or the container of TextField might cause it to be unresponsive
you should remove it and replace it with ZStack

testing swfitui body views

I would like to be able to write a unit test for a SwiftUI View.
I want to test the image and text.
I have tried using the inspector but it is not working.
Here is my code:
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Image("cat#2")
.resizable()
Text("Lily")
.font(.largeTitle)
.fontWeight(.bold)
.multilineTextAlignment(.center)
Text("A LIITEL GIRL")
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.gray)
HStack {
Text("Breed:")
.font(.largeTitle)
.fontWeight(.bold)
.padding(.horizontal, 11.0)
Text("English short hair")
.font(.largeTitle)
}
HStack {
Text("Color:")
.font(.largeTitle)
.fontWeight(.bold)
.padding(.horizontal, 11.0)
Text("Tabby")
.font(.largeTitle)
}
HStack {
Text("Size:")
.font(.largeTitle)
.fontWeight(.bold)
.padding(.horizontal, 11.0)
Text("Lager")
.font(.largeTitle)
}
}
}
}
Did you mean, that tried ViewInspector for SwiftUI? Here is the list of what you can test with this framework.
The other way is described in this video.
I think one of these options should be useful.

VStack inside ForEach loop not respecting alignment parameter in WatchOS

I have a VStack with alignment .leading inside of a ForEach loop inside a ScrollView and the alignment parameter is not being respected. If I have a single VStack outside of the ForEach loop the alignment parameter is being used and the view is displayed correctly.
ScrollView{
// THIS DISPLAYS CORRECTLY
VStack(alignment: .leading){
Text("namename")
.font(.headline)
.lineLimit(1)
Text("namename name")
.font(.subheadline)
.lineLimit(1)
}
.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.gray.opacity(0.20))
.cornerRadius(5)
.padding(.bottom)
ForEach(self.list_of_names, id: \.self) { item in
// THIS DOES NOT DISPLAY CORRECTLY
VStack(alignment: .leading){
Text(item)
.font(.headline)
.lineLimit(1)
Text(item + " name")
.font(.subheadline)
.lineLimit(1)
}
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.gray.opacity(0.20))
.cornerRadius(5)
.padding(.bottom)
}
}
.padding()
The first row has the correct alignment and it's outside the ForEach loop, meanwhile the other rows are inside the loop. The blue lines represent me highlighting each VStack inside the ForEach loop
The VStacks created in the ForEach loop do seem to be conforming to the alignment parameter. Aligning the text to the leading edge only applies to the shorter items in the VStack.
In the top VStack, "namename" at the top is only that far to the left because "namename name" below is that much wider from the center of the ScrollView. So the top VStack is not the proper way to fully achieve the alignment that you want to the ScrollView.
What you're looking for:
Leave the alignment parameter for VStack.
Add the alignment parameter to the frame of the VStack.
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
I'm a bit late, but another solution I usually use is wrapping the values in an HStack and adding a Spacer. Something like this will achieve the desired effect:
var body: some View {
ScrollView {
ForEach(self.list_of_names, id: \.self) { item in
HStack {
VStack(alignment: .leading) {
Text(item)
.font(.headline)
.lineLimit(1)
Text(item + " name")
.font(.subheadline)
.lineLimit(1)
}
Spacer()
}
.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.gray.opacity(0.20))
.cornerRadius(5)
.padding(.bottom)
}
}
.padding()
}