swift - 使用用户手势更改其值时高度卡顿
问题描述
我正在尝试构建一个底部表单 UI,就像 Apple Maps 应用程序中的 UI 一样。通常,这是通过将底部工作表视图放置在电话的可见区域之外来实现的。但是,因为我也在使用标签栏,所以这样做并不理想,因为它会破坏标签栏的透明度。
相反,我要做的是在用户的拖动事件中更改底部工作表内容的高度。这是一个简化的示例:
struct AnimationView2: View {
@State private var translation: CGFloat = 0
var body: some View {
VStack {
Spacer()
RoundedRectangle(cornerRadius: 10)
.fill(Color.green)
.frame(height: self.height())
.padding()
.gesture(self.gesture())
}
}
private func height() -> CGFloat {
return 100 + abs(self.translation)
}
private func gesture() -> some Gesture {
DragGesture()
.onChanged { action in
self.translation = action.translation.height
}
}
}
但是,前面的例子有两个问题:
- 运动与手指的位置不一致。如果您将绿色矩形移动得太快,而不是跟随您的手指,它就会被抛在后面。
- 运动动画不是流畅的,它会结结巴巴。
这是我正在谈论的一个例子。也许 GIF 不是显示动画如何卡顿的最佳选择,但我认为它或多或少是可见的:
有趣的是,使用完全相同的代码,但使用 offset 属性做运动动画似乎完美无缺:
struct AnimationView2: View {
@State private var translation: CGFloat = 0
var body: some View {
VStack {
Spacer()
RoundedRectangle(cornerRadius: 10)
.fill(Color.green)
.frame(height: 100)
.padding()
.offset(y: self.translation)
.gesture(self.gesture())
}
}
private func gesture() -> some Gesture {
DragGesture()
.onChanged { action in
self.translation = action.translation.height
}
}
}
知道为什么会这样吗?
解决方案
这是一个如何实现这一目标的示例。我.clipped()
在父视图上使用,以限制内部内容的大小,使其不会低于TabView
.
最小示例代码:
struct ContentView: View {
@State private var selection: Int = 1
var body: some View {
TabView(selection: $selection) {
AnimationView2()
.tabItem {
Label("1", systemImage: "1.circle")
}
.tag(1)
Text("Other view")
.tabItem {
Label("2", systemImage: "2.circle")
}
.tag(2)
}
}
}
struct AnimationView2: View {
@State private var offset: CGFloat = 0
private var height: CGFloat {
offset + 100 // Indicator you grab?
}
private var dragGesture: some Gesture {
DragGesture()
.onChanged { drag in
offset = -drag.translation.height
}
.onEnded { drag in
offset = 0
}
}
var body: some View {
GeometryReader { geo in
RoundedRectangle(cornerRadius: 10)
.fill(Color.green)
.frame(height: UIScreen.main.bounds.height)
.offset(y: geo.size.height - height)
.gesture(dragGesture)
.animation(.easeOut)
}
.clipped()
}
}
结果:
推荐阅读
- php - 根据php和sql server中的日期时间从表中查找活动记录
- algorithm - 这种光线投射算法有什么缺陷?
- c - printf 不会打印双精度类型的数组值
- c++ - 使用具有私有可访问性的重载继承函数声明
- python - 在 Python 中读取文件并打印出来
- python - Python中的表情符号
- powershell - 如何访问服务器 Powershell 实例中的特定脚本文件?
- mysql - docker在alpine linux中构建python django应用程序时出错
- javascript - 如何在 React js 中尚未安装的组件中显示通知
- google-app-engine - `gcloud app deploy index.yaml` 和 `gcloud datastore index create` 之间的任何区别