2x Execute Statement Inside SwiftUI LazyVStack - swiftui

When I execute the code below in an iPhone Simulator w/Xcode 14, I see double the print statements. I had only expected to see one for each rectangle. The executing code only creates one indigo rectangle unit the available space is filled (7 in all on an iPhone 14 Pro). Am wondering why I get a 2x print statement (unexpected) but only one rect (expected)
ScrollView {
LazyVStack {
ForEach(0..<1000) { i in
let _ = print("Dang \(i)")
Rectangle().fill(.indigo)
.frame(width: 100, height: 100)
}
}
}
.padding()
And here's what the output to the console looks like:
Dang 0
Dang 0
Dang 1
Dang 1
...
Dang 6
Dang 6
Also - curiously, if I change the LazyVStack to just a VStack, then I see one line for each Rectangle created (1000 Dangs, which is expected). Not sure why I see the double with the LazyVStack.
And more curious - if I use a LazyVGrid rather than LazyVStack, I only see one print statement, as expected. Is this a bug or is there something happening with statement execution that I'm not understanding.

Related

Truncate selected value in SwiftUI Picker with limited width

I'm implementing a Picker in SwiftUI. The picker values are strings that vary in size, but the picker itself has a maxWidth due to UI limitations. Some of the strings won't fit, and that's fine with me. However, at the moment, the string is wrapped, increasing the height of the picker, like so:
I'd like to limit the string to just one line, truncating the string, and keeping the picker height the same.
I've tried
.frame(maxHeight: 20)
.clipped()
.contentShape(Rectangle())
on the picker, but that gives me this:
I'd like to truncate the string. How can I do this? NOTE: it should only truncate here, not in the dropdown list.
I've played around with .lineLimit(1), .multilineTextAlignment(.leading), .truncationMode(.tail), on both the text in the ForEach block, and on the picker itself, but no luck so far.
Here is the full code that I have now:
Picker("Theme", selection: $selectedThemeRawValue) {
ForEach(Theme.allCases.map({$0.rawValue}), id: \.self) { value in
Text(value)
.lineLimit(1)
.multilineTextAlignment(.leading)
.truncationMode(.tail)
}
}
.accentColor(.primary)
.frame(maxHeight: 20)
.clipped()
.contentShape(Rectangle())
.lineLimit(1)
.multilineTextAlignment(.leading)
.truncationMode(.tail)
Does anyone have an idea on how I can do this?

Why does decreasing y position by 1 point causes the Text view to jump by 47 points when having the IgnoringSafeArea enabled in SwiftUI?

I am trying to put a message on the blue line (the safe area box shown in the image). I need to have the .edgesIgnoringSafeArea(.all). The problem is that as soon as I change the Y position to anything under 11, the text jumps 47 points up to the position shown in the image. Does anybody know what is causing this jump?
I am putting both of the cases here with the resulting screenshot. I would appreciate it if anyone could help me understand why that 1-point difference in the Y position causes the "First" message to print 47 points higher than the "Second" message.
struct TestView: View {
var body: some View {
GeometryReader{ geo in
Text("First")
.edgesIgnoringSafeArea(.all)
.position(x: 50, y: 10)
Text("Second")
.edgesIgnoringSafeArea(.all)
.position(x: 50, y: 11)
}
}}
If I’m not mistaken it’s the order of the modifiers. Everything after edgesIgnoringSafeArea still ignores Safe area.
That modifier wrapped everything that came before it.

Animation ends abruptly. How do I make this smooth?

I have this code on ContentView
#State var animation: Bool = false
MyControl()
.scaleEffect(animation ? 1.3 : 1)
.animation(Animation.default.repeatCount(4, autoreverses: true))
Later on the code a button toggles the variable animation.
The result is
The end is abrupt and the final state is not the initial.
I want the view to scale up and down fast. Start with scale 1, scales up to 1.3 and back to 1, four times and ends with 1.
How do I do that?
Set autoreverses to false. It will keep the view at its last stopping point .

SwiftUI - Horizontal ScrollView becomes Vertically scrollable

I have a problem with SwiftUI's ScrollView. If you run the app on a smaller screen (iPhone SE 1st gen for example), the ScrollView (horizontal) goes out of the screen because it doesn't fit its height on it. Therefore it becomes scrollable vertically also. I have an outer scroll view (vertical) therefore I don't want the inner ScrollView to be able to scroll vertically. Any ideas on how can I fix this?
ScrollView(.vertical) { // <------ Outher one
Text("Welcome")
ScrollView(.horizontal) { // <------ Inner one (if it doesnt fit on screen it becomes vertically scrollable
HStack {
Content...
}
}
}
Thanks!

Combining and Breaking a Vertical scrollView Horizontally in SwiftUi?

does anyone have an idea how can i break Vertical ScrollView into small horizontal ScrollView using SwiftUi:
I have the code bellow which displays the youtubeResults vertically, since each item of the ForEach is smaller, so i want to group them by 3 itens Horizontally , then the following 3 itens goes bellow them vertically until the forEach ends.
I would like the results to be displayed like that(with images, this is just an example):
(Justin beiber) (Drake) (Omarion)
(Mandela) (Dj Khaled) (Nirvana)
(Justin beiber) (Prince) (Adele)
My code: Displaying the results one by one Vertically
ScrollView (.vertical, showsIndicators: false, content:{
LazyVStack(spacing : 25){
ForEach(getData.youtubeResults){ result in
SideItemView(youtubeResults: result, selectedTheme: self.$selectedTheme)
}
}
.padding()
.padding(.top)
})
As stated by Asperi, LazyVGrid or LazyHGrid was the soulution, introduced by Apple in IOS 14+.