【问题标题】:Possible ways to send "StringValue" from One View Controller to multiple ViewControllers?将“StringValue”从一个视图控制器发送到多个视图控制器的可能方法?
【发布时间】:2018-03-05 12:30:40
【问题描述】:

我正在尝试创建一个可重复使用的 datePicker。在我的项目中,我在多个视图控制器中使用多个标签。为此,我创建了一个 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,但是如何将选定的日期发送到不同的视图控制器。

【问题讨论】:

  • 使用通知中心
  • 为什么不想使用委托模式?

标签: ios swift datepicker uinavigationcontroller


【解决方案1】:

发送通知可能是一种解决方案,但我认为从架构的角度来看,这要好得多(更易于维护、扩展等)。 例如,使用观察者(多个委托)模式。创建这样的协议。实施后,考虑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
    }
}

【讨论】:

  • 嗨@Bence Pattogato 我接受了你的建议并实施了协议。请检查我的代码给我你的建议。
【解决方案2】:

您可以使用 NotificationCenter 触发 Notification,您可以在 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"])
}

【讨论】:

    【解决方案3】:

    最后我通过接受@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
        }    
    }
    

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

    【讨论】:

    • Make the var delegate --> weak var delegate,否则它们之间会相互强引用,永远不会从内存中释放出来。
    • 编码:为了快速起见,函数名总是用驼峰式大小写(首字母小写,然后每个新单词的首字母大写)。
    • 感谢您对编码的建议我正在做演示项目我不太专注于案例。
    【解决方案4】:

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

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

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

    DateDataSouce.sharedInstance.date = theDate

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

    let theDate = DateDataSouce.sharedInstance.date

    【讨论】:

    • 为什么还要继承NSObject?完全没有必要。
    • 我不会使用单例来实现这个功能,而是使用通知。
    • 1.为此,我不会使用应用程序终身存在的静态实例。 2. 有了这个,viewcontrollers 不会得到更新,只是可以获取数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多