SwiftUI的Modifier实现Toast和Loading
2022-06-14 本文已影响0人
zjam9333
样例
通常要实现一个toast
弹出逻辑,嵌套一个zstack
,往原本的内容上方叠一个toast
就行了
struct TestToast: View {
@State var presentingToast = false
var body: some View {
ZStack {
Button("show toast") {
presentingToast = true
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
presentingToast = false
}
}
if presentingToast {
/// toastBody...
Text("hello toast")
}
}
}
}
如果要在一个很庞大的视图外侧中嵌套zstack
,必然要把原本的view
代码整体往右缩进一级,非常麻烦
其中一个简单的方案是使用ViewModifier
,使用起来就避免了直接嵌套zstack
带来的代码缩进麻烦
Button("show toast") {
presentingToast = true
}
.toast(isPresenting: $presentingToast, text: "Hello Toast")
声明这样一个类型遵循ViewModifier
协议,需要实现func body(content: Content) -> some View
方法,其中content
就是上文的老内容,在此基础上添加新内容
这里的实现是在ViewModifier
内间接嵌套ZStack
,使得外层保持美观
extension View {
public func toast(isPresenting: Binding<Bool>, text: String) -> some View {
modifier(ToastModifier(isPresent: isPresenting, text: text))
}
}
struct ToastModifier: ViewModifier {
@Binding var isPresent: Bool
var text: String
func body(content: Content) -> some View {
ZStack {
content
if isPresent {
/// toastBody
Text("hello toast")
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
isPresent = false
}
}
}
}
}
}
Loading
和Toast
同理,改动toastBody
的内容即可