SwiftUI View 协议中的 EnvironmentObject

Posted

技术标签:

【中文标题】SwiftUI View 协议中的 EnvironmentObject【英文标题】:EnvironmentObject in protocol of SwiftUI View 【发布时间】:2020-10-29 17:12:35 【问题描述】:

我想制定这样的协议:

protocol SubscriptionManagerView: View 
    var subscriptionManager: EnvironmentObject<SubscriptionManager>  get set 

以在这样的视图中使用为例:

struct Shop: View, SubscriptionManager 
    @EnvironmentObject var subscriptionManager: SubscriptionManager

第一个问题是属性包装器@EnvironmentObject 不能让我响应协议 SubscriptionManagerView。

最后我想使用这样的自定义修饰符:

extension View where Self : SubscriptionManagerView 
    func subscriptionManagerAlert() -> some View 
        self.alert(isPresented: self.$subscriptionManager.stateShowAlert) 
            Alert(title: Text(self.subscriptionManager.transactionStateTitle)
                ...
                  ))
        
    

有没有办法以这种方式工作?

【问题讨论】:

@EnvironmentObject var subscriptionManager: SubscriptionManager 不等于 var subscriptionManager: EnvironmentObject&lt;SubscriptionManager&gt; 【参考方案1】:

这是一个可能方法的演示 - 想法是使用视图修饰符和显式注入的订阅管理器,因此接口合同保证客户端视图修饰符将为我们提供所需的对象。

使用 Xcode 12 / ios 14 测试。

class SubscriptionManager: ObservableObject 
    @Published var stateShowAlert: Bool = false
    @Published var transactionStateTitle = "Test"


struct SubscriptionManagerModifier: ViewModifier 
    @ObservedObject var subscriptionManager: SubscriptionManager
    func body(content: Content) -> some View 
        content
            .alert(isPresented: self.$subscriptionManager.stateShowAlert) 
                Alert(title: Text(self.subscriptionManager.transactionStateTitle))
            
    


extension View 
    func subscriptionManagerAlert(with subscriptionManager: SubscriptionManager) -> some View 
        self.modifier(SubscriptionManagerModifier(subscriptionManager: subscriptionManager))
    


struct Shop: View 
    
    @EnvironmentObject var subscriptionManager: SubscriptionManager
    
    var body: some View 
        Button("Test") 
            subscriptionManager.stateShowAlert.toggle()
        
        .subscriptionManagerAlert(with: subscriptionManager)
    


struct Shop_Previews: PreviewProvider 
    static var previews: some View 
        Shop().environmentObject(SubscriptionManager())
    


【讨论】:

非常感谢!我很想知道是否有任何方法可以使用协议... 这有点愚蠢;不是你执行它,而是需要它。这只是您无法将多个对象推入环境的问题,还是环境不可靠?

以上是关于SwiftUI View 协议中的 EnvironmentObject的主要内容,如果未能解决你的问题,请参考以下文章

类型“ContentView”不符合协议“View”(Xcode - Swift UI)

SwiftUI中Preferences的使用

SwiftUI 官方教程

SwiftUI - MVVM之ViewModel

声明内容符合 View 协议的结构数组

使用 SwiftUI 使自定义 UIView 方面比例适合/填充的麻烦