I ran into a strange situation (bug?) today trying to resize the relative height of two views in a VStack on macOS. I accomplished this by inserting a thin rectangle between the two views and applying a DragGesture to it. It works fine... until it doesn't. It takes a lot of changing of the view heights before I hit the bug, but if I drag & release enough times, I will eventually hit it.
At some point, the code goes into an infinite loop and the program effectively freezes. os_log() is showing the .onChange value.height continuously flip flopping between -0.25 and +0.25.
I found a kludge/work-around. If the onChange's absolute value is less than 1, I don't update the frame hight. Then the code runs like a champ.
Am I doing something wrong? Is this a bug I should file?
Here is the SwiftUI test code:
import SwiftUI
import os.log
struct ResizableViews: View {
@State private var height: CGFloat = 200
let minHeight:CGFloat = 30
let maxHeight: CGFloat = 400
var body: some View {
Group {
VStack (spacing: 0) {
Rectangle()
.fill(Color.blue)
.frame(height: height)
// The draggable rectangle/handle
Rectangle()
.background(Color.gray)
.frame(height: 10)
.gesture(
DragGesture()
.onChanged { value in
os_log("CHANGE \(value.translation.height)")
// abs() > 1 is a kludge to avoid infinite loop
// with value changes flipping between -0.25 and
// 0.25
if abs(value.translation.height) >= 1 {
let tmpHeight = height + value.translation.height
height = min(max(tmpHeight, minHeight), maxHeight)
}
}
.onEnded{ value in
os_log("END \(value.translation.height)")
}
)
Rectangle()
.fill(Color.red)
}
}
}
}
Here is the console output showing the value.translation.height flip flopping between -0.25 and +0.25.
- Hardware: MacBook Pro with Apple M1 Pro
- OS: Ventura 13.5.1
Well, there is VSplitView
: https://developer.apple.com/documentation/SwiftUI/VSplitView. Is that something you could use instead?