【问题标题】:Manage Delegate out UIViewController class管理委托出 UIViewController 类
【发布时间】:2020-07-03 01:47:33
【问题描述】:

我想了解在UIViewController 类中实现委托的最佳方式

如何在 AuthManager 中使用我的函数的 controller: UIViewController 参数来管理委托?

这是我正在使用的两个类 .. 我给你展示一些小例子,让你理解

 class StartController: UIViewController {

    @objc private func presentAuthFacebookController() {
        AuthManager.signInWithFacebook(controller: self)
    }
}

class AuthManager {
static func signInWithFacebook(controller: UIViewController) {

    let loginManager = LoginManager()
    loginManager.logIn(permissions: [.publicProfile, .email], viewController: controller) { (result) in

        switch result {
        case .cancelled : print("\n AuthFacebook: operazione annullata dall'utente \n")
        case .failed(let error) : print("\n AuthFacebook: \(error) \n")
        case .success(granted: _, declined: let declinedPermission, token: _):


            let authVC = ExistingEmailController()

            authVC.delegate = // ?????? (controller)

            UIApplication.shared.windows.first?.rootViewController?.present(authVC, animated: true, completion: nil)
        }
    }
}
}

【问题讨论】:

    标签: ios swift uiviewcontroller delegates


    【解决方案1】:

    我个人认为StartController 不应该知道/遵守ExistingEmailControllerDelegate。但如果你真的想要,你可以将controller 声明为组合类型:

    static func signInWithFacebook(controller: UIViewController & ExistingEmailControllerDelegate) {
        ...
        authVC.delegate = controller
    

    在我看来,拥有AuthManager 的全部意义在于ExistingEmailController 之上创建一个抽象层,并封装逻辑验证。因此,StartController 不应该知道或关心ExistingEmailControllerDelegate。它只知道AuthManager

    AuthManager 应该是ExistingEmailController 的代表,这意味着signInWithFacebook 不应该是静态的,并且AuthManager 可以有一个AuthManagerDelegateStartController 符合:

    class AuthManager : ExistingEmailControllerDelegate {
        weak var delegate: AuthManagerDelegate?
    
        func signInWithFacebook(controller: UIViewController) {
    
            ...
    
            let authVC = ExistingEmailController()
    
            authVC.delegate = self
    
            UIApplication.shared.windows.first?.rootViewController?.present(authVC, animated: true, completion: nil)
        }
    
        func someMethodFromExistingEmailControllerDelegate() {
            delegate?.someMethod() // delegating it self.delegate, which StartController conforms to
        }
    }
    
    protocol AuthManagerDelegate : class {
        func someMethod()
    }
    
     class StartController: UIViewController, AuthManagerDelegate {
    
        var authManager: AuthManager!
    
        override func viewDidLoad() {
            authManager = AuthManager()
            authManager.delegate = self
        }
    
        @objc private func presentAuthFacebookController() {
            authManager.signInWithFacebook(controller: self)
        }
    
        func someMethod() {
            // write here the code that you would have written in someMethodFromExistingEmailControllerDelegate
        }
    }
    

    【讨论】:

    • 感谢您的支持。您的建议对我来说似乎更合适和干净,但在这一点上我问您.. 当用户(在 StartController 中)单击 Facebook 按钮时,将调用 AuthManager 类.. 如果我使用 AuthManagerDelegate 委托,我将按钮的操作指向哪里? facebookBtn.addTarget(self, action: #selector(presentAuthFacebookController), for: .touchUpInside)
    • @kAiN 您将在StartController 中创建一个名为authManager 的属性,在viewDidLoad 中对其进行初始化,将authManager.delegate 设置为self,然后在按钮操作中执行authManager.signInWithFacebook(controller: self)
    • @kAiN 我添加了更多代码来说明我的意思。现在清楚了吗?
    • 是的,是的,我已经在尝试实现所有内容了......:D你非常友善......这真的很清楚!谢谢大家
    • 嗨,抱歉,到目前为止,代表我还没有遇到任何问题.. 但我不知道为什么现在如果我在解雇时从 StartController 提出 ViewControllerNavigationController这个新的 viewController 委托不起作用..它没有收到任何输入...我哪里错了..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 2017-07-02
    相关资源
    最近更新 更多