Geo*_*org 5 uikit ios swift swiftui
我希望某个视图作为半屏工作表开始,但是当完成一些加载后,它应该转换为全屏工作表。
所以在 UIKit 中我的解决方案是:
let vc = UIViewController()
vc.view.backgroundColor = .red
vc.sheetPresentationController?.detents = [.medium(), .large()]
self.present(vc, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
vc.sheetPresentationController?.animateChanges {
vc.sheetPresentationController?.selectedDetentIdentifier = .large
}
}
Run Code Online (Sandbox Code Playgroud)
这在 UIKit 中工作得很好……但这在 SwiftUI 中也可能吗?
SwiftUI 中的类似内容可能如下所示:
struct ContentView: View {
@State var showSheet = false
var body: some View {
Button {
showSheet = true
} label: {
Text("Show-Sheet")
}
.sheet(isPresented: $showSheet, content: {
SheetView()
})
}
}
struct SheetView: View {
@State var showFullSheet = false
var body: some View {
Button {
withAnimation {
showFullSheet.toggle()
}
} label: {
Text("Toggle")
}
.presentationDetents(showFullSheet ? [.large] : [.medium, .large])
}
}
Run Code Online (Sandbox Code Playgroud)
这基本上是有效的,但问题是一半和完整之间的过渡不是动画的。不过我需要它动画。这在 SwiftUI 中可以解决吗?因为我猜想将我呈现的视图包装在 UIViewController 中,然后托管我现有的 SwiftUI 视图将不是一个选项,因为呈现部分仍然由 swift-ui 完成,对吧?
Nir*_*v D 11
首先使用selection绑定presentationDetents(_:selection:)
来跟踪您的selectedDetent状态。您面临此动画问题的原因是,当您设置sheet为large仅允许设置制动装置时[.large],它不会动画并直接跳到大。为了解决这个问题,我添加了@State属性来更新允许带有presentationDetents修饰符的制动装置。现在,如果您detents set在更新状态后立即更新selectedDetent,那么它也不会显示动画,因此为了解决此问题,我添加了一秒的更新延迟detents,这将解决您的动画问题。
struct SheetView: View {
@State var selectedDetent: PresentationDetent = .medium
@State var detents: Set<PresentationDetent> = [.large, .medium]
var body: some View {
Button {
selectedDetent = selectedDetent == .large ? .medium : .large
} label: {
Text("Toggle")
}
.presentationDetents(detents, selection: $selectedDetent)
.onChange(of: selectedDetent) { newValue in
if newValue == .large {
updateDetentsWithDelay()
} else {
detents = [.large, .medium]
}
}
}
func updateDetentsWithDelay() {
Task {
//(1 second = 1_000_000_000 nanoseconds)
try? await Task.sleep(nanoseconds: 100_000_000)
guard selectedDetent == .large else { return }
detents = [.large]
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2372 次 |
| 最近记录: |