簡體   English   中英

如何通過代碼或在 swiftui 中的自定義類中顯示警報

[英]How to present alert by code or in custom class in swiftui

我已經搜索了有關如何在 swiftui 中顯示警報的所有文檔,但它們都顯示如下代碼:

Button(action: {
            self.showingAlert = true
}) {
            Text("Show Alert")
}
.alert(isPresented:$showingAlert) {
    Alert(title: Text("title"))
}

這意味着警報必須用於按鈕。

如何在我的自定義類中使用警報,例如處理 http 請求,然后像這樣顯示錯誤警報:

class A{
    func getDate(){
        alert("error")
    }
}

創建一個類並符合ObservableObject協議(任何符合 ObservableObject 的東西都可以在 SwiftUI 中使用,並在其值發生變化時發布公告,以便更新用戶界面):

class A: ObservableObject {

    @Published var showAlert = false

    func buttonTapped() {
        //handle request and then set to true to show the alert
        self.showAlert = true
    }

}

您的觀點:

struct ContentView: View {

    @ObservedObject private var viewModel = A()

    var body: some View {

        Button(action: {
            self.viewModel.buttonTapped()
        }) {
            Text("Show Alert")
        }
        .alert(isPresented: $viewModel.showAlert, content: { () -> Alert in
            Alert(title: Text("Error"), message: Text("Please try again"), dismissButton: .default(Text("Okay")))
        })
    }

}

解決它的另一種方法,如果您想使用自定義錯誤描述,則創建符合如下可Identifiable協議的自定義錯誤:

enum NetworkError: LocalizedError, Identifiable {
    case notFound
    case serverError(responseCode: Int)
    case underlyingError(Error)
    case unknown

    var id: String { localizedDescription }

    var errorDescription: String? {
        switch self {
        case .notFound: return "Not found"
        case .serverError(let responseCode): return "Server error \(responseCode)"
        case .underlyingError(let error): return error.localizedDescription
        case .unknown: return "Unknown error"
        }
    }
}

視圖模型

在您的 viewModel 中,然后設置您將獲得的錯誤(來自您的 api 等)並將其設置為您發布的錯誤。

class YourViewModel: ObservableObject {
    @Published var persons: [Person]
    @Published var error: NetworkError? // <- Set your error from your api here

    private var subscriptions = Set<AnyCancellable>()

    init() {
        fetch()
    }

    func fetch() {
        api.people
            .sink(receiveCompletion: { [weak self] (completion) in
                if case .failure(let error) = completion {
                    self?.error = error // An error occured
                }
        }, receiveValue: { [weak self] (persons) in
            self?.onReceive(persons)
            self?.error = nil
        })
        .store(in: &subscriptions)
    }

   //...//
}

看法

發布的錯誤將觸發警報,您​​將能夠在閉包中顯示錯誤的localizedDescription

struct MainView: View {
    @ObservedObject var viewModel = YourViewModel()

    var body: some View {
        Text(viewModel.persons.first?.name ?? "N/A")
            .alert(item: self.$viewModel.error) { error in
                Alert(title: Text("Error"),
                      message: Text(error.localizedDescription),
                      dismissButton: .cancel())
        }
    }
}

我們需要創建一個 UserState 類並符合 ObservableObject 協議。 符合 ObservableObject 協議的類可以使用 SwiftUI 的 @Published 屬性包裝器來自動宣布對屬性的更改,這樣任何使用該對象的視圖都會重新調用它們的 body 屬性並與它們的數據保持同步。

//MARK:- Step:1 On SceneDelegate
// set environmentObject
let userState = UserState()
let contentView = ContentView().environmentObject(userState)


//MARK:- Step:2 Create UserState Class

class UserState: ObservableObject {
    @Published var sessionExpired: Bool = false
}

//MARK:- Step:3 Create a ContentView

struct ContentView: View {
    
    // Step:3 Create a userState EnvironmentObject
    @EnvironmentObject var userState: UserState
    @State private var isShowSecondView = false
    @State private var showingAlert = false
    
    var body: some View {
        NavigationView {
            NavigationLink(destination: SecondView(),  isActive: $isShowSecondView) {
                
                ZStack(alignment: .center) {
                    
                    Button("Show Second") {
                        isShowSecondView.toggle()
                        
                    }
                    
                }
                .alert(isPresented: $showingAlert) {
                    Alert(title: Text("Alert"), message: Text("Session Expired"), dismissButton: .default(Text("Got it!")))
                }
                .onChange(of:  userState.sessionExpired, perform: { value in // Step:4 in onChange we need to check sessionExpired or not
                    print("onChange")
                    if userState.sessionExpired {
                        showingAlert = true
                    }
                })
            }
        }
    }
}

//MARK:-

struct SecondView: View {
    
    @EnvironmentObject var userState: UserState
    
    var body: some View {
        ZStack(alignment: .center) {
            
            Button("Show Alert Message") {  // Step:5 -  Here I changed flag then alert will present
                userState.sessionExpired.toggle()
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM