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+.
Related
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?
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.
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.
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!
I am using TableView QML component, where each column width is set to the table total width divided by number of columns. This introduces some fraction parts and in result, a horizontal scrollbar is almost always visible in the bottom.
But I don't want to disable scrollbar as I have ability of changing column width and because of that scrollbar may be needed. So my problem is about initial showing of this TableView component. I want to get rid of that scrollbar when component is shown first time, but don't disable it for future usage.
I am new to QML and don't know all aspects of it, but solution that came to me is to set width of each column as I do, then for the last one get sum of all previous columns and set it's width to parent.width - that sum. Can you please help me to understand how can I implement this using QML?
columnWidthProvider is calculated once at adding column. I cant reproduce your bug with this. contentWidth become same as width
TableView {
id: table
anchors.fill: parent
columnWidthProvider: function (column) {
console.log(parent.width , columns, parent.width / columns)
// wdth is 0 here
return parent.width / columns
}
ScrollBar.horizontal: ScrollBar {
policy: ScrollBar.AsNeeded
}
//....
}
But i had same issue in another view. Solution was:
Flickable {
id:view
ScrollBar.horizontal: ScrollBar {
policy: (view.width - view.contentWidth < -3) ?
ScrollBar.AlwaysOff : ScrollBar.AsNeeded}
}
}