无法从 @Published ObservableObject 或 @EnvironmentObject 变量中获取要更新的 SwiftUI 视图对象

问题描述

我已经进行了大量搜索并阅读了大量文章,但我无法让 SwiftUI 根据模型中的变量变化动态更新视图,至少是我正在做的那种事情。基本上我想根据应用程序的 UNNotificationSettings.UNAuthorizationStatus 更新视图。我让应用程序在启动时检查状态并显示状态。如果状态未确定,则点击文本将触发请求通知对话框。但是,在用户允许或拒绝通知后,视图不会更新。我确定我遗漏了一些基本的东西,因为我已经尝试了十几种方法包括 @Published ObservableObject@Observedobject@EnvironmentObject 等。

struct ContentView: View {
    @EnvironmentObject var theviewmodel : Testviewmodel
    
    var body: some View {
        vstack {
            Text(verbatim: "Notifications are: \(theviewmodel.notificationSettings.authorizationStatus)")
                .padding()
        }
        .onTapGesture {
            if theviewmodel.notificationSettings.authorizationStatus == .notDetermined {
                theviewmodel.requestNotificationPermissions()
            }
        }
    }
}

class Testviewmodel : ObservableObject {
    @Published var notificationSettings : UNNotificationSettings
    
    init() {
        notificationSettings = type(of:self).getNotificationSettings()!
    }
    
    
    func requestNotificationPermissions() {
        let permissionsToRequest : UNAuthorizationoptions = [.alert,.sound,.carPlay,.announcement,.badge]
        UNUserNotificationCenter.current().requestAuthorization(options: permissionsToRequest) { granted,error in
            if granted {
                print("notification request GRANTED")
            }
            else {
                print("notification request DENIED")
            }
            if let error = error {
                print("Error requesting notifications:\n\(error)")
            }
            else {
                dispatchQueue.main.sync {
                    self.notificationSettings = type(of:self).getNotificationSettings()!
                }
            }
        }
    }

    static func getNotificationSettings() -> UNNotificationSettings? {
        var settings : UNNotificationSettings?
        let start = Date()
        
        let semaphore = dispatchSemaphore(value: 0)
        UNUserNotificationCenter.current().getNotificationSettings { notificationSettings in
            settings = notificationSettings
            semaphore.signal()
        }
        semaphore.wait()
        
        while settings == nil {
            let elapsed = start.distance(to: Date())
            Thread.sleep(forTimeInterval: TimeInterval(0.001))
            if elapsed > TimeInterval(1) {
                print("ERROR: did not get notification settings in less than a second,giving up!")
                break
            }
        }
        if settings != nil {
            print("\(Date())  Notifications are: \(settings!.authorizationStatus)")
        }
            
        return settings
    }
}


func getUNAuthorizationStatusstring(_ authStatus : UNAuthorizationStatus) -> String {
    switch authStatus {
    case .notDetermined:    return "not determined"
    case .denied:           return "denied"
    case .authorized:       return "authorized"
    case .provisional:      return "provisional"
    case .ephemeral:        return "ephemeral"
    @unkNown default:       return "unkNown case with rawValue \(authStatus.rawValue)"
    }
}


extension UNAuthorizationStatus : customstringconvertible {
    public var description: String {
        return getUNAuthorizationStatusstring(self)
    }
}

extension String.StringInterpolation {
    mutating func appendInterpolation(_ authStatus: UNAuthorizationStatus) {
        appendLiteral(getUNAuthorizationStatusstring(authStatus))
    }
}

编辑:我尝试添加 objectwillChange 但视图仍未更新。

class Testviewmodel : ObservableObject {
    let objectwillChange = ObservableObjectPublisher()
    
    @Published var notificationSettings : UNNotificationSettings {
        willSet {
            objectwillChange.send()
        }
    }
    
    
    init() {
        notificationSettings = type(of:self).getNotificationSettings()!
    }

解决方法

根据苹果文档,像@Published 这样的属性包装器应该保存值。 UNNotificationSettings 是引用类型。由于类发生了变异并且指针永远不会改变,@Publushed 不知道您更改了任何内容。发布一个值(它创建一个结构并从他的类中初始化它)或手动手动发送 objectwillChange 消息。

,

虽然我无法使用 public class Customer { private String firstName,lastName; private Date birthday; private String address; public Customer() { firstName="Hans"; lastName = "Meier"; birthday = new Date(915195600000l); address = "-"; } public Customer(String firstName,String lastName,String address) { this.firstName = firstName; this.lastName = lastName; this.birthday = new Date(915195600000l); this.address = address; } public Customer (String firstName,Date birthday,String address) { this.firstName = firstName; this.lastName = lastName; this.birthday = birthday; this.address = address; } public Customer (Customer customer) { firstName = customer.firstName; lastName = customer.lastName; birthday = customer.birthday; address = customer.address; } } 手动使用它,但我确实创建了一个基本的工作系统,如下所示。上题部分功能不再赘述。

objectWillChange

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...