Reputation: 83
At the moment I have a ViewController
class containing a UIScrollView
, within the scroll view I have another view controller, where I can currently receive gesture recognition. My goal is to be able to perform a segue to a different view controller, based on which subViewController I tap.
let scrollView = UIScrollView(frame: CGRect(x:0,y:0, width: self.view.frame.width, height:self.view.frame.height-106))
scrollView.delegate = self;
self.view.addSubview(scrollView);
let subView11 = subView(nibName: nil, bundle: nil);
subView1.view.frame = CGRect(x:0,y:0, width: self.view.frame.width, height: CGFloat(openReelHeight));
self.addChildViewController(subView1);
scrollView.addSubview(subView1.view);
subView.didMove(toParentViewController: self);
Then in the subView class I have a basic touch recognition function:
@IBAction func tapOnView(_ sender: UITapGestureRecognizer) {
//change main View controller
}
Upvotes: 2
Views: 1069
Reputation: 437381
I would suggest letting the parent perform the segue. So you need a mechanism to let the child inform the parent that the button has been tapped. Here are two approaches:
The child view controller can define a protocol and then have its @IBAction
for the button invoke that in the parent view controller.
protocol ChildViewControllerDelegate {
func child(_ child: ChildViewController, didTapButton button: Any)
}
class ChildViewController: UIViewController {
@IBAction func didTapButton(_ sender: Any) {
if let parent = parent as? ChildViewControllerDelegate {
parent.child(self, didTapButton: sender)
}
}
}
Clearly, the parent view controller needs to conform to that protocol:
extension ViewController: ChildViewControllerDelegate {
func child(_ child: ChildViewController, didTapButton button: Any) {
// now segue to whatever you want
}
}
You can alternatively follow an explicit protocol-delegate pattern, rather than relying upon the view controller containment relationships of the parent
:
protocol ChildViewControllerDelegate: class {
func didTapButton(_ sender: Any)
}
class ChildViewController: UIViewController {
weak var delegate: ChildViewControllerDelegate?
@IBAction func didTapButton(_ sender: Any) {
delegate?.didTapButton(sender)
}
}
And then, when the parent adds the child, it would have to explicitly set the delegate
:
let child = storyboard!.instantiateViewController(withIdentifier: "ChildViewController") as! ChildViewController
addChildViewController(child)
child.delegate = self
// add the child's view to your view hierarchy however appropriate for your app
child.didMove(toParentViewController: self)
And, of course, the parent again has to conform to this protocol:
extension ViewController: ChildViewControllerDelegate {
func didTapButton(_ sender: Any) {
// segue to next scene
}
}
Note, with both of these approaches, you can change your protocol's func
to include whatever parameters you want (e.g. passing back contents of some UITextField
or whatever). Likewise, you might use method names that make the functional intent of the child a little more explicit. I used somewhat generic method and protocol names because I don't know what the various children are doing.
Upvotes: 2