Here is what I wanna do: My storyboard contains a UIViewController
with just a few controlls. It's height is less than half a screen. For simplicity, let's call it the DataViewController
. The DataViewController
is embedded inside other UIViewControllers
through a " Container View
".
Although " Container View
" displays the DataViewController
, it still needs to have an explicit height
set. Otherwise interface builder complains about ambiguous constraints.
Now, how can I tell " Container View
" that it's size should be what's required by DataViewController
? Ie without setting a hard coded, explicit height
in Interface Builder (which, I fear, would break the layout if the font size changes)?
Or in other words: How do you size/position embedded UIViewControllers
in Interface Builder?
If you want the childViewContainer to be responsible for its width and height, here is a way to do it :
Set width and height constraints in your Parent View Controller(s) and select remove at build time. They are just here so interface builder stops complaining about missing constraints.
(You can) Change your Child View Controller simulated size from fixed to freeform in your storyboard size inspector tab.
Objective-C
- (void)viewDidLoad {
[super viewDidLoad];
self.containerView.subviews[0].translatesAutoresizingMaskIntoConstraints = NO;
}
#pragma mark - Constraints
- (void)updateViewConstraints {
[super updateViewConstraints];
[self initConstraints];
}
- (void)initConstraints {
if (!self.didSetConstraints) {
self.didSetConstraints = YES;
self.containerView.subviews[0].translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *views = @{@"subview" : self.containerView.subviews[0]};
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subview]|" options:0 metrics:nil views:views]];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subview]|" options:0 metrics:nil views:views]];
}
}
Swift
override func viewDidLoad() {
super.viewDidLoad()
containerView.subviews[0].translatesAutoresizingMaskIntoConstraints = false
}
// Mark: Constraints
override func updateViewConstraints() {
super.updateViewConstraints()
initConstraints()
}
func initConstraints() {
if !didSetConstraints {
didSetConstraints = true
containerView.subviews[0].translatesAutoresizingMaskIntoConstraints = false
let views = ["subview": containerView.subviews[0]]
containerView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[subview]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
containerView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[subview]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
}
}
Now your child View Controller (linked to the container view) is fully responsible for its content size. Thus, you must set constraints that let the root view calculates its size to satisfies the constraints it holds.
If you are embedding with a segue, just do:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let viewController = segue.destination as? EmbeddedViewController {
viewController.view.translatesAutoresizingMaskIntoConstraints = false
}
}
in your content view controller set the preferredContentSize
(In your example DataViewController
) like the following
override func viewDidLoad() {
super.viewDidLoad()
preferredContentSize = CGSize(width: 400, height: 200)
}
When the child gets added to the parentViewController, the parentViewController gets notified about the prefered size. Following function gets called on the parent
func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer)
In this method you can then change the container to the prefered size of the child.
For example change the height to the prefered height of the child/content
override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
// heightConstraint is a IBOutlet to your NSLayoutConstraint you want to adapt to height of your content
heigtConstraint.constant = container.preferredContentSize.height
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.