从单视图控制器向多个ViewControllers发送“StringValue”的可能方法?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从单视图控制器向多个ViewControllers发送“StringValue”的可能方法?相关的知识,希望对你有一定的参考价值。

我正在尝试创建一个可重用的datePicker。在我的项目中,我在多个viewControllers中使用多个标签。为此,我创建了一个DatePicker类,我正在使用不同的地方。检查以下代码,它适用于Single viewController。这是我在这里显示日期的VC,我从CustomDatePickerViewController中选择了日期。

import UIKit

class SelectDateViewController: UIViewController {
    var dateString_fromCustomVC = String()

    override func viewDidLoad() {
        super.viewDidLoad()
        print("dateString_fromCustomVC",dateString_fromCustomVC)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func selectDateAction(_ sender: Any) {

        let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "CustomDatePickerViewController") as! CustomDatePickerViewController


        self.addChildViewController(popOverVC)
        self.view.addSubview(popOverVC.view)
        popOverVC.view.frame = view.bounds
        popOverVC.didMove(toParentViewController: self)

        self.navigationController?.navigationBar.isHidden = true
    }

} i am displaying date

    import UIKit

    class SelectDateViewController: UIViewController {
        var dateString_fromCustomVC = String()

        override func viewDidLoad() {
            super.viewDidLoad()
            print("dateString_fromCustomVC",dateString_fromCustomVC)

        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }


        @IBAction func selectDateAction(_ sender: Any) {

            let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "CustomDatePickerViewController") as! CustomDatePickerViewController


            self.addChildViewController(popOverVC)
            self.view.addSubview(popOverVC.view)
            popOverVC.view.frame = view.bounds
            popOverVC.didMove(toParentViewController: self)

            self.navigationController?.navigationBar.isHidden = true
        }

    }

这是我的CustomDatePickerViewController类。

import UIKit

class CustomDatePickerViewController: UIViewController {

    @IBOutlet var myDatePicker: UIDatePicker!
    override func viewDidLoad() {
        super.viewDidLoad()

        view.frame.size.height =  UIScreen.main.bounds.height
        self.view.backgroundColor = UIColor.black.withAlphaComponent(0.6)
    }

    @IBAction func saveDateAction(_ sender: Any) {

        myDatePicker.datePickerMode = UIDatePickerMode.date
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "dd MMM yyyy"
        let selectedDate = dateFormatter.string(from: myDatePicker.date)
        print("selectedDate",selectedDate)

         let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SelectDateViewController") as! SelectDateViewController
        popOverVC.dateString_fromCustomVC = selectedDate


        self.removeAnimate()
        self.navigationController?.navigationBar.isHidden = false

    }
    func showAnimate()
    {
        self.view.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
        self.view.alpha = 0.0;
        UIView.animate(withDuration: 0.10, animations: {
            self.view.alpha = 1.0
            self.view.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
        });
    }

    func removeAnimate()
    {
        UIView.animate(withDuration: 0.05, animations: {
            self.view.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
            self.view.alpha = 0.0;
        }, completion:{(finished : Bool)  in
            if (finished)
            {
                self.view.removeFromSuperview()
            }
        });
    }

}

我可以将CustomDatePickerViewController中的选定日期发送到SelectDateViewController,但是如何将所选日期发送到不同的视图控制器。

答案

发送通知可以是一个解决方案,但我认为从架构的角度来看,这是更好的(更容易维护,扩展等)。例如,使用观察者(多个代理)模式。创建这样的协议。实现后,考虑使用this来解析数组的保留周期。

protocol DatePickerProtocol {
    func dateStringChanged(to newString: String)
}

class CustomDatePickerViewController: UIViewController {
    ...
    var delegates: [DatePickerProtocol]?

    @IBAction func saveDateAction(_ sender: Any) {
        .....
        if let delegates {
            for delegate in delegates {
                delegate.dateStringChanged(to: "selectedDate string")
            }
        }
        ...
    }
}

class SelectDateViewController: UIViewController, DatePickerProtocol {
    ...
    // get a reference to CustomDatePickerViewController and register this class like:
    dataPickerViewController.delegates.append(self)

    func dateStringChanged(to newString: String) {
        // Do whatever with the new date string
    }
}
另一答案

您可以使用NotificationCenter触发通知,并且可以在viewController中添加观察者并更新标签。

如果您想发送日期,可以发布如下通知:

NotificationCenter.default.post(name: "SelectedDate", object: nil, userInfo: ["selectedDate": Date that you selected])

之后,您可以在要接收该通知的其他viewController中添加观察者。

NotificationCenter.default.addObserver(self, selector: #selector(datePicked(notification:)), name: "SelectedDate", object: nil)


@objc func datePicked(notification: Notification) {
      //get the date here
      print(notification.userInfo?["selectedDate"])
}
另一答案

最后我通过@Bence Pattogato建议解决了我的问题。请参阅我的以下更新代码。

我创建了一个协议类。文件名是CustomDatePickerDelegate.swift

protocol CustomDatePickerDelegate {
        func CustomDateSeletced(value: String)
}

现在这是我在CustomDatePickerViewController类中更新的代码。

import UIKit

class CustomDatePickerViewController: UIViewController {


    @IBOutlet var myDatePicker: UIDatePicker!
    var delegate: CustomDatePickerDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()

        view.frame.size.height =  UIScreen.main.bounds.height
        self.view.backgroundColor = UIColor.black.withAlphaComponent(0.6)
    }


    @IBAction func saveDateAction(_ sender: Any) {

        myDatePicker.datePickerMode = UIDatePickerMode.date
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "dd MMM yyyy"
        let saveDate = dateFormatter.string(from: myDatePicker.date)
        print("selectedDate",saveDate)
        delegate?.CustomDateSeletced(value: saveDate) **//This is the way i am saving date value  from date picker**
        self.removeAnimate()
        self.navigationController?.navigationBar.isHidden = false

    }
    func showAnimate()
    {
        self.view.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
        self.view.alpha = 0.0;
        UIView.animate(withDuration: 0.10, animations: {
            self.view.alpha = 1.0
            self.view.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
        });
    }

    func removeAnimate()
    {
        UIView.animate(withDuration: 0.05, animations: {
            self.view.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
            self.view.alpha = 0.0;
        }, completion:{(finished : Bool)  in
            if (finished)
            {
                self.view.removeFromSuperview()
            }
        });
    }

}

现在我在SelectDateViewController中使用此委托。请参阅我的以下更新代码。

  import UIKit

class SelectDateViewController: UIViewController {

    @IBOutlet var selectedDateLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

    }
    @IBAction func selectDateAction(_ sender: Any) {

        let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "CustomDatePickerViewController") as! CustomDatePickerViewController
        self.addChildViewController(popOverVC)
        self.view.addSubview(popOverVC.view)
        popOverVC.view.frame = view.bounds
        popOverVC.delegate = self
        popOverVC.didMove(toParentViewController: self)

        self.navigationController?.navigationBar.isHidden = true
    }
}
extension SelectDateViewController:CustomDatePickerDelegate
{
    func CustomDateSeletced(value: String) {
        selectedDateLabel.text = value
    }    
}

代码清洁目的我在那边使用扩展。

另一答案

创建一个DataSource并在您需要的视图中读取它们:

class DateDataSource {
    var date : Date?
    static let sharedInstance = DateDataSource()
    private init() {}
}

当您从选择器中获取日期时,您将其设置为:

DateDataSouce.sharedInstance.date = theDate

然后在您需要显示它的视图中,您将调用

let theDate = DateDataSouce.sharedInstance.date

以上是关于从单视图控制器向多个ViewControllers发送“StringValue”的可能方法?的主要内容,如果未能解决你的问题,请参考以下文章

ios 如何从单视图 Segue 到拆分视图控制器

Xcode:如何将对象从一个 viewControllers 视图移动到另一个 viewControllers 视图?

跨多个视图控制器共享背景图像

如何刷新Scrollview内部的viewcontrollers?

在多个视图控制器、多个故事板上显示用户输入的文本

切换屏幕/视图控制器