从单视图控制器向多个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”的可能方法?的主要内容,如果未能解决你的问题,请参考以下文章
Xcode:如何将对象从一个 viewControllers 视图移动到另一个 viewControllers 视图?