首页 > 解决方案 > 从委托方法修改视图控制器属性

问题描述

我正在使用 Swift 4.2 和 Xcode 10.2。

我创建了一个UIViewController名为的自定义警报DialAlert。它覆盖在当前的顶部UIViewController并有两个按钮CallCancel

Call被点击时,我使用一个名为该方法的委托方法将点击报告给底层视图控制器,callTapped. 该方法使用各种其他方法执行调用设置。在执行呼叫设置时,我想DialAlert用状态更新视图控制器。但是我无法从callTapped委托方法访问它的属性,因为它是在 tableView 方法中创建的,如下所示:

let dialAlert = self.storyboard?.instantiateViewController(withIdentifier: Constants.Storyboard.dialAlert) as! DialAlert

正是在这个 tableView 方法中,我设置了它的所有初始属性。

我在课程开始时尝试了这段代码:

var dialAlert = UIViewController() as! DialAlert

然后在整个代码中引用 self.dialAlert (确实编译),但在运行时我收到一个错误,我无法将类型的值UIViewController转换为DialAlert.

如何修改dialAlert创建实例的方法之外的方法中的属性?我在 SO 中找到了一些看起来很有希望的答案,但最近没有,也没有任何意义。

标签: swiftdelegatesviewcontrollersubview

解决方案


我有你的问题的解决方案,我不知道你如何编码来显示你的DialAlert,但根据我的说法,你可以理解如何实现它。

因此,首先在AppDelegate.swift方法中添加以下代码。

class AppDelegate: UIResponder, UIApplicationDelegate {

    static var shared  = UIApplication.shared.delegate as! AppDelegate
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        return true
    }

    .....
    .....
}

此后,在您的对话框警报中声明协议并创建委托,除了检查委托和单击按钮时调用委托方法。

拨号警报VC.swift

protocol DialAlertVCDelegate: class {
    func callButtonTapped(_ sender: UIButton)
    func cancelButtonTapped(_ sender: UIButton)
}


class DialAlertVC: UIViewController {

    @IBOutlet weak var dialAlertView: UIView!

    weak var delegate   : DialAlertVCDelegate?

    class func viewController() -> DialAlertVC {
        return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DialAlertVC") as! DialAlertVC
    }

    @IBAction func btnCallTapped(_ sender: UIButton) {

        if let selfDelegate = self.delegate {
            selfDelegate.callButtonTapped(sender)
        }
    }

    @IBAction func btnCancelTapped(_ sender: UIButton) {

        if let selfDelegate = self.delegate {
            selfDelegate.cancelButtonTapped(sender)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

现在,是时候显示/隐藏了DialoAlertVC,所以在里面ViewController添加以下代码。

ViewController.swift

class ViewController: UIViewController {

    @IBOutlet weak var lblButtonTapped: UILabel!

    var dialAlertVC         : DialAlertVC?

    @IBAction func btnShowDialAlert(_ sender: UIButton) {
        self.showDialAlert(true)
    }

    func showDialAlert(_ show: Bool) {

        if show {

            if self.dialAlertVC != nil {
                self.dialAlertVC?.view.removeFromSuperview()
                self.dialAlertVC = nil
            }

            dialAlertVC = DialAlertVC.viewController()
            dialAlertVC?.delegate = self
            AppDelegate.shared.window?.addSubview(dialAlertVC!.view)

        } else {

            if self.dialAlertVC != nil {
                self.dialAlertVC?.view.removeFromSuperview()
                self.dialAlertVC = nil
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

extension ViewController: DialAlertVCDelegate {

    func callButtonTapped(_ sender: UIButton) {
        self.showDialAlert(false)
        self.lblButtonTapped.text = "Call Button Tapped"
    }

    //------------------------------------------------------------------------------

    func cancelButtonTapped(_ sender: UIButton) {
        self.showDialAlert(false)
        self.lblButtonTapped.text = "Cancel Button Tapped"
    }
}

在此处查看演示项目:https ://gofile.io/?c=P2VKCl

我希望这能帮到您。


推荐阅读