[英]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.