这是我第一次尝试使用SwiftUI,我想创建一个SwiftUI视图,作为一个分割视图,在两个视图的中心有一个可调的手柄。
这是我目前的代码实现例子。
struct ContentView: View {
@State private var gestureTranslation = CGSize.zero
@State private var prevTranslation = CGSize.zero
var body: some View {
VStack {
Rectangle()
.fill(Color.red)
.frame(height: (UIScreen.main.bounds.height / 2) + self.gestureTranslation.height)
RoundedRectangle(cornerRadius: 5)
.frame(width: 40, height: 3)
.foregroundColor(Color.gray)
.padding(2)
.gesture(DragGesture()
.onChanged({ value in
self.gestureTranslation = CGSize(width: value.translation.width + self.prevTranslation.width, height: value.translation.height + self.prevTranslation.height)
})
.onEnded({ value in
self.gestureTranslation = CGSize(width: value.translation.width + self.prevTranslation.width, height: value.translation.height + self.prevTranslation.height)
self.prevTranslation = self.gestureTranslation
})
)
Rectangle()
.fill(Color.green)
.frame(height: (UIScreen.main.bounds.height / 2) - self.gestureTranslation.height)
}
}
}
现在看起来是这样的:[
这个还算好用,但是在拖动手柄的时候,很不稳定,似乎需要大量的拖动才能到达某个点。
请教我是哪里出了问题。谢谢您了。
根据我的观察,问题似乎来自于拖动手柄时手柄的重新定位。为了解决这个问题,我在句柄上设置了一个反向偏移,使其保持原位。我试图尽可能地掩盖持久的手柄位置,将其隐藏在其他视图(zIndex)之下。
我希望有其他人能对这个问题有更好的解决方法。 现在,这是我所得到的全部。
import PlaygroundSupport
import SwiftUI
struct SplitView<PrimaryView: View, SecondaryView: View>: View {
// MARK: Props
@GestureState private var offset: CGFloat = 0
@State private var storedOffset: CGFloat = 0
let primaryView: PrimaryView
let secondaryView: SecondaryView
// MARK: Initilization
init(
@ViewBuilder top: @escaping () -> PrimaryView,
@ViewBuilder bottom: @escaping () -> SecondaryView)
{
self.primaryView = top()
self.secondaryView = bottom()
}
// MARK: Body
var body: some View {
GeometryReader { proxy in
VStack(spacing: 0) {
self.primaryView
.frame(height: (proxy.size.height / 2) + self.totalOffset)
.zIndex(1)
self.handle
.gesture(
DragGesture()
.updating(self.$offset, body: { value, state, _ in
state = value.translation.height
})
.onEnded { value in
self.storedOffset += value.translation.height
}
)
.offset(y: -self.offset)
.zIndex(0)
self.secondaryView.zIndex(1)
}
}
}
// MARK: Computed Props
var handle: some View {
RoundedRectangle(cornerRadius: 5)
.frame(width: 40, height: 3)
.foregroundColor(Color.gray)
.padding(2)
}
var totalOffset: CGFloat {
storedOffset + offset
}
}
// MARK: - Playground
let splitView = SplitView(top: {
Rectangle().foregroundColor(.red)
}, bottom: {
Rectangle().foregroundColor(.green)
})
PlaygroundPage.current.setLiveView(splitView)
把代码贴在XCode Playground Swift Playgrounds里面就可以了
如果你发现了改进我的代码的方法,请告诉我。