0

I have viewController with segue to secondViewController named "toSecond". In viewController i load customView.xib

let myCustomView = NSBundle.mainBundle().loadNibNamed("customView", owner: self, options: nil)[0]

in this customView i have button with action:

viewController().goToSecond()

in viewController i have function with this code

func goToSecond() {
self.performSegueWithIdentifier("toSecond", sender: self)
}

but when i pressed button in customView i become a error:

viewController has no segue with identifier 'toSecond'

when i call this function directly from viewController all work great!

So, how can i call performSegueWithIdentifier from my customView?

customView source code:

import UIKit

class customView: UIView {

@IBAction func ToSecondButton(sender: AnyObject) {
viewController().goToSecond() }

}

viewController source code:

import UIKit

class viewController: UIViewController {

...
let myCustomView = NSBundle.mainBundle().loadNibNamed("customView", owner: self, options: nil)[0]
self.view.addSubview(myCustomView)
func goToSecond() {
    self.performSegueWithIdentifier("toSecond", sender: self)
    }
...

}
Dmitry
  • 2,963
  • 2
  • 21
  • 39
  • If the File's Owner for the custom view is the view controller, I don't understand how this code: `viewController().goToSecond()` is contained inside your custom view. Could you provide more of the source code for your custom view? How are you creating a reference to the view controller inside the custom view? – Daniel Hall Mar 18 '16 at 23:07
  • i present customView in presenting viewController... My segue between viewController and secondViewController... i can call func goToSecond() from viewController directly but can't from customView! if in function goToSecond write something like print("Click!") i see this click in log! – Dmitry Mar 18 '16 at 23:13
  • 1
    In the future, I'd encourage you to stick to [Cocoa naming conventions](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingBasics.html#//apple_ref/doc/uid/20001281-1002242-BBCIJGDB), where all class names start with uppercase letters. This was unnecessarily confusing... – Rob Mar 18 '16 at 23:28

1 Answers1

3

The problem is that your UIView subclass is calling viewController().goToSecond(). That's not doing what you think it is. The viewController() isn't referencing the view controller that loaded your custom view. It's instantiating a second, orphaned instance of that class (not connected to any storyboard) and therefore cannot find the segue.

If you're really going to have this custom UIView subclass initiate a segue, you need to pass a reference to your original view controller to the custom view. So add a property to the custom view subclass that can hold the reference to its view controller, and when the view controller instantiates this custom view, it has to set that property.


For example:

import UIKit

protocol CustomViewDelegate: class {         // make this class protocol so you can create `weak` reference
    func goToNextScene()
}

class CustomView: UIView {

    weak var delegate: CustomViewDelegate?   // make this `weak` to avoid strong reference cycle b/w view controller and its views

    @IBAction func toSecondButton(sender: AnyObject) {
        delegate?.goToNextScene() 
    }

}

And then

import UIKit

class ViewController: UIViewController, CustomViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let myCustomView = NSBundle.mainBundle().loadNibNamed("customView", owner: self, options: nil)[0] as! CustomView
        myCustomView.delegate = self

        // ... do whatever else you want with this custom view, adding it to your view hierarchy
    }


    func goToNextScene() {
        performSegueWithIdentifier("toSecond", sender: self)
    }

    ...

}
Rob
  • 415,655
  • 72
  • 787
  • 1,044