SwiftUI 中 DragGesture() 的高度计算不正确
Incorrect height calculation with DragGesture() in SwiftUI
我正在使用 SwiftUI 开发一个基于地图的应用程序,我需要通过拖动它来更改模态卡片(这是地图信息所在的视图)的高度 up/down,就像在 Apple 中一样地图。
这是我尝试与之交互的高度的卡片的屏幕截图
https://i.stack.imgur.com/mZX2m.png
我用 RoundedRectangle
实现了 ZStack
并添加了 DragGesture()
修饰符。
ZStack(alignment: .top){
RoundedRectangle(cornerRadius: 16.0)
.frame(height:currentHeight)
Text("Card")
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
.multilineTextAlignment(.center)
.padding(.top)
}.gesture(DragGesture()
.onChanged { value in
if (self.currentHeight + value.predictedEndLocation.y - value.startLocation.y > UIScreen.main.bounds.height) {
self.currentHeight = UIScreen.main.bounds.height
} else {
self.currentHeight += value.predictedEndLocation.y - value.startLocation.y
}
}
.onEnded { value in
if (self.currentHeight + value.predictedEndLocation.y - value.startLocation.y > UIScreen.main.bounds.height) {
self.currentHeight = UIScreen.main.bounds.height
} else {
self.currentHeight += value.predictedEndLocation.y - value.startLocation.y
}
})
第一个问题是向上拖动,卡片超过屏幕高度,我正在检查 UIScreen 边界高度以防止高度大于屏幕,但是计算有更多问题,卡片的高度很快变得不明确并且它不想拖累。
我从未使用过手势识别器。能告诉我正确的计算方法吗?
谢谢!
这是一种方法(下面代码中的一些有用的注释)
struct TestResizingCard: View {
static let kMinHeight: CGFloat = 100.0
@State var currentHeight: CGFloat = kMinHeight // << any initial
var body: some View {
GeometryReader { g in // << for top container height limit
ZStack(alignment: .bottom) {
Rectangle().fill(Color.yellow) // << just for demo
self.card()
.gesture(DragGesture()
.onChanged { value in
// as card is at bottom the offset is reversed
let newHeight = self.currentHeight - (value.location.y - value.startLocation.y)
if newHeight > Self.kMinHeight && newHeight < g.size.height {
self.currentHeight = newHeight
}
})
}
}
}
func card() -> some View {
ZStack(alignment: .top){
RoundedRectangle(cornerRadius: 16.0)
.frame(height:currentHeight)
Text("Card")
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
.multilineTextAlignment(.center)
.padding(.top)
}
}
}
struct TestResizingCard_Previews: PreviewProvider {
static var previews: some View {
TestResizingCard()
}
}
我正在使用 SwiftUI 开发一个基于地图的应用程序,我需要通过拖动它来更改模态卡片(这是地图信息所在的视图)的高度 up/down,就像在 Apple 中一样地图。
这是我尝试与之交互的高度的卡片的屏幕截图 https://i.stack.imgur.com/mZX2m.png
我用 RoundedRectangle
实现了 ZStack
并添加了 DragGesture()
修饰符。
ZStack(alignment: .top){
RoundedRectangle(cornerRadius: 16.0)
.frame(height:currentHeight)
Text("Card")
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
.multilineTextAlignment(.center)
.padding(.top)
}.gesture(DragGesture()
.onChanged { value in
if (self.currentHeight + value.predictedEndLocation.y - value.startLocation.y > UIScreen.main.bounds.height) {
self.currentHeight = UIScreen.main.bounds.height
} else {
self.currentHeight += value.predictedEndLocation.y - value.startLocation.y
}
}
.onEnded { value in
if (self.currentHeight + value.predictedEndLocation.y - value.startLocation.y > UIScreen.main.bounds.height) {
self.currentHeight = UIScreen.main.bounds.height
} else {
self.currentHeight += value.predictedEndLocation.y - value.startLocation.y
}
})
第一个问题是向上拖动,卡片超过屏幕高度,我正在检查 UIScreen 边界高度以防止高度大于屏幕,但是计算有更多问题,卡片的高度很快变得不明确并且它不想拖累。
我从未使用过手势识别器。能告诉我正确的计算方法吗?
谢谢!
这是一种方法(下面代码中的一些有用的注释)
struct TestResizingCard: View {
static let kMinHeight: CGFloat = 100.0
@State var currentHeight: CGFloat = kMinHeight // << any initial
var body: some View {
GeometryReader { g in // << for top container height limit
ZStack(alignment: .bottom) {
Rectangle().fill(Color.yellow) // << just for demo
self.card()
.gesture(DragGesture()
.onChanged { value in
// as card is at bottom the offset is reversed
let newHeight = self.currentHeight - (value.location.y - value.startLocation.y)
if newHeight > Self.kMinHeight && newHeight < g.size.height {
self.currentHeight = newHeight
}
})
}
}
}
func card() -> some View {
ZStack(alignment: .top){
RoundedRectangle(cornerRadius: 16.0)
.frame(height:currentHeight)
Text("Card")
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
.multilineTextAlignment(.center)
.padding(.top)
}
}
}
struct TestResizingCard_Previews: PreviewProvider {
static var previews: some View {
TestResizingCard()
}
}