1
votes

I'm having the hardest time finding an answer for this.

I have a xib view that is within a scrollview that is within a view controller. In the xib I have a button with an action and I need to segue to a view controller I have in my storyboard. I also would like to be able to use a custom segue.

So far, I have read that I can instantiate the viewcontroller from the storyboard to segue to it. But then I don't know how to present that controller.

thanks for any help...

UPDATE:

this is the code I'm using to perform the segue.

In parent ViewController:

    static var referenceVC: UIViewController?


override func viewDidLoad() {
    super.viewDidLoad()
    print("viewdidload")
    LevelSelectViewController.referenceVC = self

    setupScrollView()
}

code in xib view file

        let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sightWordController")

        let parent = LevelSelectViewController.referenceVC!

        let segue = InFromRightCustomSegue(identifier: "test", source: parent, destination: vc)


        segue.perform()
1
Segues are typically confined to storyboard usage only. You'll likely have to add your view (which you can configure the whole class of the view to load from a nib) into the storyboard in some way and then you can hook a segue up to it. Otherwise, they are called UIStoryboardSegues for a reason.TheCodingArt
If you use a custom segue that can be allocated in code, you just need a VC to perform on I believe, which means you can climb the responder chain to find the associated VC to perform it on. In general though, it sounds like you want a custom transition and some sort of delegate callbacks. There's absolutely no reason to make your code this complicated to keep a segue.TheCodingArt
I just got it to work. my biggest issue was getting a reference to the parent viewcontroller so that I can call the segue. The way I got the reference is a bit of a hack, I just made a static reference variable in the parent view controller that I could use within the xib file. Is there a better way to get the reference? I will update the question to show my code.Discoveringmypath
if you want the reference to be generic (such as a regular segue is) just climb the responder chain to see which VC wants to handle/can handle presenting or performing the segue first.TheCodingArt
If you want/need to be less generic, you can also use delegation to inform the VC that an action has occurred and it should respond.TheCodingArt

1 Answers

3
votes

As noted in the comments, Segues are typically confined to storyboard usage as noted in the documentation. You can implement a custom xib view in a storyboard via @IBDesignable like approaches and have you're view load from the xib into the storyboard file/class. This way, you gain the benefits of both worlds. Otherwise, you may want to approach this in another fashion (such as delegates/target-action events, etc).

You may also climb the responder chain and call a segue related to the VC loaded from the storyboard (the segue doesn't necessarily have to be attached to any particular action) via getting a reference to the VC and calling the segue. You can climb the responder chain in a manner such as the example code below:

protocol ChildViewControllerContainer {
    var parentViewController: UIViewController? { get }
}


protocol ViewControllerTraversable {
    func viewController<T: UIViewController>() -> T?
}

extension UIView: ViewControllerTraversable {

    func viewController<T: UIViewController>() -> T? {
        var responder = next

        while let currentResponder = responder {
            guard responder is T else {
                responder = currentResponder.next
                continue
            }

            break
        }

        return responder as? T
    }
}

extension UITableViewCell: ChildViewControllerContainer {
    weak var parentViewController: UIViewController? {
        return viewController() as UIViewController?
    }
}