【发布时间】:2019-08-17 17:38:36
【问题描述】:
我正在尝试制作一个类似于 Slack 应用程序的导航 UI,其中我的主屏幕覆盖了菜单导航屏幕。我创建了一个 ViewModifier,它使主屏幕可拖动。现在我需要添加一些功能,这样当在蓝色菜单屏幕上点击“主页”时,白色的主页视图会动画回到中心。我的想法是在全局 AppState 中跟踪 NavigationState:
enum NavigationSelection {
case menu
case home
}
final class AppState: ObservableObject {
let objectWillChange = PassthroughSubject<Void, Never>()
@Published var currentNavigationSelection: NavigationSelection = .home
}
然后当用户点击“Home”时,让它更新 AppState 的 currentNavigationSelection,并让 Draggable 视图根据 currentNavigationSelection 确定它的偏移量。我真的不确定这种方法,而且我很难在新的 SwiftUI 样式中考虑它。任何建议将不胜感激。
视图层次结构如下所示:
var body: some View {
ZStack {
Menu()
HomeTabView()
}
}
并且 HomeTabView 应用了一个可拖动的 ViewModifier:
struct Slidable: ViewModifier {
@EnvironmentObject var app: AppState
@State private var viewState = SlidableViewDragState.normal.defaultPosition
@State private var currentPosition: SlidableViewDragState = .normal {
didSet {
self.viewState = self.currentPosition.defaultPosition
}
}
func body(content: Content) -> some View {
return content
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight:
.infinity, alignment: Alignment.topLeading)
.offset(self.viewState)
.animation(.interactiveSpring())
.gesture(
DragGesture()
.onChanged({ (value) in
self.viewState = self.currentPosition.applyXTranslation(x: value.translation.width)
})
.onEnded({ (value) in
if value.translation.width < 0 && self.currentPosition == .normal {
return
}
if abs(value.translation.width) > self.currentPosition.switchThreshold {
self.currentPosition = self.currentPosition.oppositePosition
if self.currentPosition == .menuVisible {
self.app.currentNavigationSelection = .menu
}
} else {
self.viewState = self.currentPosition.defaultPosition
}
})
)
}
}
【问题讨论】:
-
我了解有趣的技术挑战! :) 对我来说也很有趣!但总的来说,不是所有的用户体验专家都建议不要使用汉堡包解决方案吗?