Note: I've been working on this problem for days in XCode 11.6 and testing on iOS 13.6. I just tested this with XCode 14 beta on an iPhone running iOS 14 beta and the problem with ScrollView went away. So I think its fair to say that this behavior was a bug in SwiftUI 1.0. However... and please feel free to correct me on this if I'm wrong, I still need to come up with some working solution for devices running older software, at least back through iOS 13. What is best solution here for iOS 13 users? Some kind of UIScrollView delegate?
Original problem follows:
I've been struggling with getting ScrollView to work with both .vertical and .horizontal when the child view content that is larger than the ScrollView. The problem was that the content was offset up and to the left, leaving much of it inaccessible and lot of empty space on the bottom and right. Now, I did fix that by using either .offset or .position, but that created a secondary issue of content in the bottom right corner no longer being interactive (i.e. gestures would no longer respond to content in the bottom right corner equivalent to the offset amount).
I've created some code below to help demonstrate the issue. There are 4 ScrollViews.
- Vertical ScrollView. (Works)
- Horizontal ScrollView (Works)
- V & H ScrollView (Doesn't work. Note the offset.)
- Separate V & H ScrollViews one inside the other. (Works... but it's not great. You can only scroll one direction at a time.
struct ContentView: View {
let array = [String].init(repeating: "🙂", count: 25)
var body: some View {
VStack {
ScrollView(.vertical) {
VStack {
ForEach(array, id:\.self) { text in
Text(text).padding()
}
}
}.border(Color.black)
ScrollView(.horizontal) {
HStack {
ForEach(array, id:\.self) { text in
Text(text).padding()
}
}
}.border(Color.black)
ScrollView([.horizontal, .vertical], showsIndicators: true) {
VStack {
ForEach(array,id:\.self) { _ in
HStack(spacing: 0) {
ForEach(self.array,id:\.self) { text in
Text(text).padding()
}
}
}
}
}.border(Color.black)
ScrollView(.horizontal, showsIndicators: true) {
ScrollView(.vertical, showsIndicators: true) {
VStack {
ForEach(array,id:\.self) { _ in
HStack(spacing: 0) {
ForEach(self.array,id:\.self) { text in
Text(text).padding()
}
}
}
}
}
}.border(Color.black)
}.padding()
}
}