Изменить свойство контроллера представления из метода делегата

Я использую Swift 4.2 и Xcode 10.2.

Я создал настраиваемое оповещение, которое UIViewController называется DialAlert. Он накладывается поверх текущего UIViewController и имеет две кнопки, Call и Cancel.

Когда нажимается Call, я сообщаю о касании базовому контроллеру представления с помощью метода делегата, называемого callTapped.. Этот метод выполняет настройку вызова с использованием различных других методов. Пока он выполняет настройку вызова, я хотел бы обновить DialAlert viewcontroller статусом. Но я не могу получить доступ к его свойствам из 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, которые выглядели многообещающими, но ничего нового и ничего важного.


person TM Lynch    schedule 10.06.2019    source источник


Ответы (1)


У меня есть решение ваших проблем, я не знаю, как вы кодируете свой 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
    }

    .....
    .....
}

После этого внутри вашего диалогового окна объявите протокол и создайте делегата, помимо этого проверьте делегат и вызовите метод делегата при нажатии кнопки.

DialAlertVC.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

Я надеюсь, что это поможет вам.

person Mayur Karmur    schedule 11.06.2019
comment
Похоже, это хороший подход. Я попробую и отправлю ответ. Спасибо! - person TM Lynch; 11.06.2019