Ios 将值从自定义视图传递到主视图控制器-Swift

Ios 将值从自定义视图传递到主视图控制器-Swift,ios,swift,uistoryboard,xib,Ios,Swift,Uistoryboard,Xib,我正在开发一个基本的报警应用程序。这就是主故事板的样子 我添加了一个自定义视图控制器作为单独的xib文件,如下所示 这就是界面运行时的样子。(背景中的主ViewController和前景中的CustomAlertController) 它包含一个日期选择器。我的意思是,当用户单击主故事板中的addButton时,customAlertViewController将出现,用户可以选择添加为警报的日期和时间。当用户点击customAlertViewController中的Add时,应该将日期

我正在开发一个基本的报警应用程序。这就是主故事板的样子

我添加了一个自定义视图控制器作为单独的xib文件,如下所示

这就是界面运行时的样子。(背景中的主ViewController和前景中的CustomAlertController)

它包含一个日期选择器。我的意思是,当用户单击主故事板中的addButton时,customAlertViewController将出现,用户可以选择添加为警报的日期和时间。当用户点击customAlertViewController中的Add时,应该将日期和时间传递回数组并添加到主情节提要视图控制器中的tableView

这是我迄今为止编写的代码:

表视图的代码

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = UITableViewCell()
    let adate = alarmDate[indexPath.row].date
    print(adate)
    cell.textLabel?.text = String(adate)
    return cell
    }
报警类中的代码

import Foundation
class Alarm{
    var date : NSDate
    init (date : NSDate){
        self.date = date
    }
}
CustomAlertViewController中的代码

您不必通读整个代码。我尝试过使用prepare for segue,但我想当CustomAlertviewcontroller位于不同的情节提要(?)中时,这不是一个可行的解决方案

我采取的下一种方法是以某种方式将日期传递给ViewDidDemouse方法中Alarm类的实例,然后将其附加到alarmDate数组(在ViewController中声明)

这就是我被卡住的地方。ViewDidDemouse中的print语句将1输出到控制台,这显然是因为日期已被追加。但一旦CustomAlertViewController退出并且viewController返回,alarmDate数组就会重置,并且表视图中不会显示任何值。我曾试图解决这个问题,但没有结果

我意识到,如果我在故事板中使用一个新的视图控制器来代替一个单独的xib文件,我可以很容易地获得相同的结果

class CustomAlertViewController: UIViewController {
    //MARK: - Properties
    @IBOutlet weak var customAlertView: UIView!    
    @IBOutlet weak var alarmPicker: UIDatePicker!
    var destinationDate = NSDate()
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName : nibNameOrNil, bundle : nibBundleOrNil)
        self.modalPresentationStyle = .OverCurrentContext
    }
    convenience init(){
        self.init(nibName : "CustomAlertViewController", bundle: nil)
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("NSCoding not supported")
    }


    //MARK: - Methods
    override func viewDidLoad() {
        super.viewDidLoad()
        print ("View loaded")
        self.customAlertView.layer.borderColor = UIColor.darkGrayColor().CGColor
        self.customAlertView.layer.borderWidth = 2
        self.customAlertView.layer.cornerRadius = 8
        view.backgroundColor = UIColor(white: 1, alpha: 0.7)
        view.opaque = false
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    override func viewDidDisappear(animated: Bool) {
        let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("table") as! ViewController
        let alarm = Alarm( date : destinationDate)
        vc.alarmDate.append(alarm)
//        vc.alarmData.reloadData()
        print(vc.alarmDate.count)
    }
    // MARK: - Navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        let destinationVC = segue.destinationViewController as! ViewController
        let alarm = Alarm( date : destinationDate)
        destinationVC.alarmDate.append(alarm)
        destinationVC.alarmData.reloadData()
        print(destinationVC.alarmDate.count)
    }
    //MARK: - Actions
    @IBAction func cancelButton(sender: AnyObject) {
        self.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
    }
    @IBAction func addButton(sender: AnyObject) {
        //Code to correct the time zone difference
        let sourceDate = alarmPicker.date
        let sourceTmeZone = NSTimeZone(abbreviation: "GMT")
        let destinationTimeZone = NSTimeZone.systemTimeZone()
        let sourceOffset = sourceTmeZone!.secondsFromGMTForDate(sourceDate)
        let destinationOffset = destinationTimeZone.secondsFromGMTForDate(sourceDate)
        let interval : Double
        interval = Double(destinationOffset - sourceOffset)
        destinationDate = NSDate.init(timeInterval: interval, sinceDate: sourceDate)

        self.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
    }
}
我缺乏使用Swift的经验,非常感谢您的帮助。
PS我正在使用Swift 2.3

您可以使用协议:

protocol DateShare {
    func share(date: NSDate)
}
您可以在任何控制器范围之外的任何位置声明。 然后添加一个

delegate: DateShare!
属性在CustomAlertVC中。在VC中,初始化CustomAlert时,添加以下行:

customAlert.delegate = self
当然,您在VC中添加了一个符合DateShare协议的扩展,如下所示:

extension ViewController: DateShare {
    func share(date: NSDate) {
         // do whatever you can for that the date can be displayed in table view 
        alarmDates.append(date) // if I understood it all ?
    }
}
最后,在addButton(sender:_)作用域中添加这一行:


这应该会成功

实现这一点的最佳方法是使用协议和委托在视图控制器之间传递信息。不管怎样,我都会学习协议和委托,因为它们是随着您的进步而需要了解的价值概念。在线和通过stackoverflow都有大量的资源。这里有一个教程让你开始:谢谢!。我会查的不客气!我会发布代码,但是已经有太多的资源,所以在这一点上是多余的。如果你有具体的问题,我很乐意帮忙!另外,您可能可以通过NotificationCenter实现这一点,但这更像是一种“黑客”方式。您可能会在通知中心遇到类似的问题。我想你会说,协议是“正确的”方式。或者,如果您使用的是导航控制器,则可以使用“unwindSegue”功能来完成相同的任务。祝你好运嗯,通知不是一个好的过程。您可以通过协议执行此操作。@user3353890谢谢!终于想出了如何使用协议。本教程非常有用。没问题,如果您需要进一步的解释,我可以提供一些给您:)我只是尝试了您的代码,但无法使其正常工作。我不知道如何让
customAlert.delegtae=self
编译。你想在这里干什么?customAlert是指CustomAlertViewController吗?我必须在哪里输入代码?没关系。我已经弄明白了,并做了必要的修改。谢谢你的帮助!
@IBOutlet func addButton(sender: UIButton?) {
    // generate inputDate here
    delegate.share(date: inputDate)
}