On an iPhone project I'm using Xcode storyboard to embed a few containing views in a main scroll view. I've heard containing view is also an "embed segue". Now I don't necessarily have to embed other child controllers, I could have just created custom views and have the original child controllers' logic in those custom subviews. (I think I'm just going to do that after posting here, because it seems easier.) But I've already done the code and want to know how easy or hard it is to stay with it.
Because scroll view content is greater than the main screen bounds, it's harder to layout the container view in storyboard. I can think of three ways to solve it. I can either
Is there a way to create embed segue in Xcode, but NOT putting it in but to do something like a "manual segue" as with other view transitions? I wouldn't be able to see the layout in storyboard but at least it'll be easier than #3 and I don't have to drag up and down like #2 which seems silly.
To create a segue between view controllers in the same storyboard file, Control-click an appropriate element in the first view controller and drag to the target view controller. The starting point of a segue must be a view or object with a defined action, such as a control, bar button item, or gesture recognizer.
Embed Segues are used by container views. These are views inside a viewController which loads another view from another viewController. If what you want is to present or push a view controller, you don't have to use an Embed segue.
So, Ctrl+Drag from the “Go to Other View Controller” button, to somewhere in the second View Controller. It can be anywhere in the main box of the second view controller. When you release, it will show you a box like the one below. This lets you set what kind of segue you want to use.
Here are the helper functions I use to programmatically embed a child view controller in a view.
struct MyChildViewController {
static func embed(
viewControllerId: String,
storyboardName: String,
containerViewController: UIViewController,
containerView: UIView) -> UIViewController? {
guard let viewController = initViewController(viewControllerId, storyboardName: storyboardName)
else { return nil }
containerViewController.addChildViewController(viewController)
containerView.addSubview(viewController.view)
viewController.view.translatesAutoresizingMaskIntoConstraints = false
MyConstraints.fillParent(
viewController.view, parentView: containerView, margin: 0, vertically: true)
MyConstraints.fillParent(
viewController.view, parentView: containerView, margin: 0, vertically: false)
viewController.didMoveToParentViewController(containerViewController)
return viewController
}
static func initViewController(viewControllerId: String, storyboardName: String) -> UIViewController? {
let storyboard = UIStoryboard(name: storyboardName, bundle: NSBundle.mainBundle())
return storyboard.instantiateViewControllerWithIdentifier(viewControllerId)
}
}
struct MyConstraints {
static func fillParent(view: UIView, parentView: UIView, margin: CGFloat = 0,
vertically: Bool) -> [NSLayoutConstraint] {
var marginFormat = ""
if margin != 0 {
marginFormat = "-\(margin)-"
}
var format = "|\(marginFormat)[view]\(marginFormat)|"
if vertically {
format = "V:" + format
}
let constraints = NSLayoutConstraint.constraintsWithVisualFormat(format,
options: [], metrics: nil,
views: ["view": view])
parentView.addConstraints(constraints)
return constraints
}
}
Usage:
let childWiewController = MyChildViewController.embed("MyViewControllerId", storyboardName: "MyStoryboardName", containerViewController: containerViewController, containerView: containerView)
Where:
I understand that the WWDC has an hour of video on it. But if you have watched any of their other videos it should become quite clear that time does not directly relate to complexity. This is how you use a container (or a child sub view controller) programmatically:
[self addChildViewController:child]; // 1
[self.view addSubview:child.view]; // 2
[child didMoveToParentViewController:self]; // 3
Pretty simple and only two extra lines of code compared to adding a subview. As you said, there are storyboard solutions but depending on your complexity, doing this through code may be easier. It really comes down to your preference though.
If you intend to animate adding the view, you should make the last call to didMoveToParentViewController
in the completion block (i.e. after the animation has been completed).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With