简体   繁体   中英

EnvironmentObject in protocol of SwiftUI View

I want to make protocol like this :

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

To use in view like this for exemple :

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

First problem is that property wrapper @EnvironmentObject can't make me respond to protocol SubscriptionManagerView.

Finally I want to use for a custom modifier like this :

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

Any idea to work in this way ?

Here is a demo of possible approach - the idea is to use view modifier with explicitly injected subscription manager, so contract of interface guaranties that client view of modifier will provide us required object.

Tested with 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())
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM