从一个视图控制器到另一个视图控制器进行代理呼叫

时间:2016-11-24 12:21:47

标签: ios swift uiviewcontroller delegates

我在Swift中没有做过的事情之一是使用委托。所以我试图从一个视图控制器到另一个视图控制器进行委托调用以传递数据。

我在两个独立的故事板上有两个视图控制器。一个是HomeViewController,第一个视图控制器。这就是用户现在所处的位置。然后他点击右侧导航项按钮,转到第二个视图控制器SettingsViewController。然后他点击导航项按钮返回第一个视图控制器。在回来的路上,SettingsViewController向HomeViewController发送Int值。我所拥有的是以下内容。

// 1st view controller //
class HomeViewController: UIViewController, SettingsViewControllerDelegate {
    @IBAction func rightTapped(sender: AnyObject) {
        let storyboard = UIStoryboard(name: "Settings", bundle: nil)
        let controller = storyboard.instantiateViewControllerWithIdentifier("InitialController") as! UINavigationController
        let view = controller.topViewController as! SettingsViewController
        view.selectedRow = lineSelection
        self.navigationController?.pushViewController(view, animated: true)
    }

    override func viewDidLoad() {
        let storyboard = UIStoryboard(name: "Settings", bundle: nil)
        let controller = storyboard.instantiateViewControllerWithIdentifier("InitialController") as! UINavigationController
        let settingsViewController = controller.topViewController as! SettingsViewController
        settingsViewController.delegate = self
    }

    func didChangeLine(number: Int) {
        print(number) // <<<<<<<<< not getting a delegate call
    }
}

// 2nd view controller //
protocol SettingsViewControllerDelegate {
    func didChangeLine(number: Int)
}

class SettingsViewController: UIViewController {
    var selectedRow = Int() // the row selected from a table view
    var rightButton = UIBarButtonItem()

    override func viewDidLoad() {
        rightButton = UIBarButtonItem(title: "Change", style: .Plain, target: self, action: #selector(changeNumber))
        self.navigationItem.rightBarButtonItem  = rightButton
    }

    // going back to 1st view controller (HomeViewController)
    func changeNumber() {
        self.delegate?.didChangeLine(selectedRow)
        self.navigationController?.popViewControllerAnimated(true)
    }
}

当用户从第二个(设置)返回到第一个视图控制器(主页)时,我没有接到电话。我可以用不同的方法传递数据,但我想知道我在这种情况下做错了什么。

感谢。

5 个答案:

答案 0 :(得分:2)

@IBAction func rightTapped(sender: AnyObject) {
        let storyboard = UIStoryboard(name: "Settings", bundle: nil)
        let controller = storyboard.instantiateViewControllerWithIdentifier("InitialController") as! UINavigationController
        let view = controller.topViewController as! SettingsViewController
        view.selectedRow = lineSelection
        self.navigationController?.pushViewController(view, animated: true)
    }

更改为:

@IBAction func rightTapped(sender: AnyObject) {
        let storyboard = UIStoryboard(name: "Settings", bundle: nil)
        let controller = storyboard.instantiateViewControllerWithIdentifier("InitialController") as! UINavigationController
        let view = controller.topViewController as! SettingsViewController
        view.selectedRow = lineSelection
view.delegate = self
        self.navigationController?.pushViewController(view, animated: true)
    }

答案 1 :(得分:1)

您需要覆盖第一个viewcontroller中的prepareForSegue,以便将第一个viewcontroller引用传递给secondviewcontroller委托属性。

override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
        let viewController = segue.destinationViewController as! SettingsViewController
        viewController.delegate = self
}

HomeViewController viewDidLoad代码中没有任何意义,因为您正在从故事板中执行segue。

<强>已更新

@IBAction func rightTapped(sender: AnyObject) {
    let storyboard = UIStoryboard(name: "Settings", bundle: nil)
    let controller = storyboard.instantiateViewControllerWithIdentifier("InitialController") as! UINavigationController
    let view = controller.topViewController as! SettingsViewController
    view.delegate = self

   view.selectedRow = lineSelection
    self.navigationController?.pushViewController(view, animated: true)
}

您可以直接获取SettingViewController参考。只需设置viewcontroller storyboard id并像这样得到它

 let storyboard = UIStoryboard(name: "Settings", bundle: nil)
 let controller = storyboard.instantiateViewControllerWithIdentifier("InitialController") as! UINavigationController

let controller = storyboard.instantiateViewController(withIdentifier: "SettingsViewController") as! SettingsViewController

答案 2 :(得分:1)

在这个Protocol-Sample中,我模拟了调用HomeViewController&#39; didChangeLine&#39;功能如下图所示。 enter image description here

答案 3 :(得分:0)

更改SettingsViewController类中的follwing方法: -

override func viewDidLoad() {
        rightButton = UIBarButtonItem(title: "Back", style: .Plain, target: self, action: #selector(changeNumber))
        self.navigationItem.leftBarButtonItem  = rightButton
    }

答案 4 :(得分:0)

尝试这种方式,在这里我创建了一个变量settingsViewController,我在viewDidLoad()方法中设置它并在用户点击右键时使用它,而不是创建一个新的settingsViewController。

// 1st view controller //
class HomeViewController: UIViewController, SettingsViewControllerDelegate {

    var settingsViewController: SettingsViewController? 
    // creating a variable so that we can use it in the IBOutlet 
    // method after setting it in the viewDidLoad() method

    @IBAction func rightTapped(sender: AnyObject) {
        settingsViewController.selectedRow = lineSelection
        self.navigationController?.pushViewController(settingsViewController, animated: true)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let storyboard = UIStoryboard(name: "Settings", bundle: nil)
        let controller = storyboard.instantiateViewControllerWithIdentifier("InitialController") as! UINavigationController
        settingsViewController = controller.topViewController as? SettingsViewController
        settingsViewController.delegate = self
    }

    func didChangeLine(number: Int) {
        print(number) 
    }
}