SwiftUI Modal Alert

记录一个状态值,操作触发状态值的改变进而引发弹出动作

Modal

.sheet(isPresented: <Binding<Bool>>, content: <() -> View>)

// 如果仅在当前页面管理,则只需要声明成 @State 即可
@State var isModal = false

var body: some View {
    // ...
    Button("Modal") {
        // 改变状态值
        isModal = true
    }.sheet(isPresented: self.$isModal) {
         modalView()
    }
}

dimiss

法一:标志位传递

在内页中声明 @Binding var isModal: Bool,将外部标志位 isModal 传递到内页,内页操作触发标志位改变,引发界面刷新

法二:block(推荐)

在内页声明 @State var closeActionBlock: (()->())?,按钮点击时抛出事件让外部响应,改变标志位触发界面刷新

Button("Modal") {
    // 改变状态值
    isModal = true
}.sheet(isPresented: self.$isModal) {
    modalView {
        self.$isModal = false
    }         
}

法三:使用环境变量进行页面的自我管理

内页自我管理:

// iOS13:
@Environment (\.presentationMode) var presentationMode

Button("dimiss me") {    
presentationMode.wrappedValue.dismiss()
}

// iOS15:
@Environment (\.dismiss) var dismiss

Button("dismiss me") {    
    dismiss()
}

不过这种方法需要注意几点:

  • 消失整个界面的时候,只能引出来的界面(例如NavigationView或者弹出的Alert、Sheet、Popover),不然 .presentationMode.wrappedValue.isPresented 的值是 false,自然无法 dismiss()

  • 弹出的Alert、Sheet或者Popover之类的,使用这个方法消失的是激活弹出的那个界面,而不是弹出之后的界面。


Alert

.alert(isPresented: <Binding<Bool>>, actions: <() -> View>)

@State var isAlert = false

var body: some View {
    // ...
    Text("Tap")
        .onTapGesture {
            // 改变状态值
            isAlert = true
        }.alert(isPresented: self.$isAlert) {
            Alert(
                title: Text("Title"),
                message:Text("message"),
                primaryButton:
                    Alert.Button.default(Text("cancel")),
                secondaryButton:
                    Alert.Button.default(Text("copy"), action:{
                        UIPasteboard.general.string = "hello world"
                    })
            )
        }
}

.alert<Item>(item: Binding<Item?>, content: (Item) -> Alert) -> some View where Item : Identifiable

alert(item:content:) 接受一个 Identifiable? 的绑定,当这个绑定值不为 nil 时,显示一个弹框。

.alert(item: settingsBinding.loginError) { error in 
    Alert(title: Text(error.localizedDescription))
}

enum AppError: Error, Identifiable {
    var id: String { localizedDescription }
    case passwordWrong
}

extension AppError: LocalizedError {
    var localizedDescription: String {
        switch self {
        case .passwordWrong: return "密码错误"
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容