iOS - navigation bar displayed when UISearchController is active - ios

I programatically created a UISearchController and added it to my UIView A. I also have a UITableView in the same UIView. I use UISearchController to search through my UITableView. When you click on a cell, UIView B gets pushed. Both UIView A and UIView B have UINavigationBar set to HIDDEN.
When I simply click on a UITableViewCell WITHOUT searching, everything happens perfectly, and UIView B is displayed without UINavigationBar.
But when I am searching using the UISearchController and I click on a UITableViewCell, the UINavigationBar is displayed on UIView B, even though I set it to hidden in the viewDidAppear method.
Here is my code:
BarsSearchController = [[UISearchController alloc] initWithSearchResultsController:nil];
BarsSearchController.searchResultsUpdater = self;
BarsSearchController.dimsBackgroundDuringPresentation = NO;
BarsSearchController.searchBar.delegate = self;
BarsSearchController.searchBar.barTintColor = [UIColor whiteColor];
BarsSearchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
[searchBarView addSubview:BarsSearchController.searchBar];
[searchBarView addConstraint:[NSLayoutConstraint constraintWithItem:BarsSearchController.searchBar
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:searchBarView
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0]];
[searchBarView addConstraint:[NSLayoutConstraint constraintWithItem:BarsSearchController.searchBar
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:searchBarView
attribute:NSLayoutAttributeLeading
multiplier:1.0
constant:0.0]];
[searchBarView addConstraint:[NSLayoutConstraint constraintWithItem:BarsSearchController.searchBar
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:searchBarView
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0]];
[searchBarView addConstraint:[NSLayoutConstraint constraintWithItem:BarsSearchController.searchBar
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:searchBarView
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:0.0]];
[searchBarView layoutIfNeeded];
self.definesPresentationContext = YES;
[BarsSearchController.searchBar sizeToFit];
What am I missing here?

BarsSearchController.hidesNavigationBarDuringPresentation = YES;

I have the same problem, to fix it, I hide back button and background in viewDidLoad :
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.hidesBackButton = YES;
[[[self navigationController] navigationBar] setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[[[self navigationController] navigationBar] setShadowImage:[UIImage new]];
[[[self navigationController] navigationBar] setTranslucent:YES];
}
and I hide navigationBar in viewDidAppear :
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[[self navigationController] setNavigationBarHidden:YES];
}

Related

UISearchBar ignores programmatic constraints

I'm trying to build a ViewController subclass that leverages a UISearchController to display results. The view has an input field that I want to animate up to the top of the screen so the user has a maximum amount of room to view the results.
I built out a proof of concept using a UIView that wraps a Search Bar drop-in component and set their top, leading, trailing, and bottom constraints equal in a Storyboard. The following code is responsible for animating the different movements:
- (void)keyboardWillAppear:(NSNotification*)notification {
self.labelToSearchBarSpaceConstraint.active = NO;
self.searchBarAtTopConstraint.active = YES;
self.searchBarLeadingSpaceConstraint.constant = 0;
self.searchBarTrailingSpaceConstraint.constant = 0;
[UIView animateWithDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
- (void)keyboardWillDisappear:(NSNotification*)notification {
self.searchBarAtTopConstraint.active = NO;
self.labelToSearchBarSpaceConstraint.active = YES;
self.searchBarLeadingSpaceConstraint.constant = 20;
self.searchBarTrailingSpaceConstraint.constant = 20;
[UIView animateWithDuration: [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
I then tried switching over to a programatically created UISearchController and UISearchBar. The following code sets up what I thought was the equivalent relationship in code instead of in the Storyboard:
self.definesPresentationContext = YES;
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
UISearchBar* searchBar = self.searchController.searchBar;
searchBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.searchBarView addSubview:searchBar];
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0].active = YES;
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0].active = YES;
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0].active = YES;
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0].active = YES;
However, when done this way the UISearchBar object does not obey the constraints. When the container is animated up, the search bar flies off the page. Why is this happening?
Minor Update: I noticed in the documentation for NSLayoutConstraint to set its active property to YES instead of explicitly adding it, but the behavior is exactly the same. Updating code to match.
I had a similar issue when adding UISearchController's searchBar to a UITableView header view.
When animating constraints of the containerView holding the UITableView after the user selected the searchBar, it would not follow the containerView.
In my case it would appear that after the delegate didPresentSearchController:(UISearchController *)searchController is called, the searchBar had a superview of UISearchBarContainerView instead of the UITableView header view.
Re-adding it back to the original header view before animation helped me.
-(void)didPresentSearchController:(UISearchController *)searchController {
NSLog(#"did present search controller");
self.tableView.tableHeaderView = self.searchController.searchBar;
...animation...
}

Custom UIView (with xib) autolayout width and pushing viewcontroller from delegate

I have problem with setting constraints to custom UIView and pushing new ViewController by delegate when I tap the view. I tried to find solution for these problems but couldn't find one that answers to these questions.
Autolayout problem
I have custom xib-file which has been set Size: Freeform, Width: 600 and Height: 25, it also includes one label and one button with constraints in this view. I have added this view successfully below navigation bar where I want it. Problem is, that it don't make anything to fit it's width equally with navigation bar / window size (I have tried multiple choices eg. making new frame for view that is width of window / navigation bar). It only appears to have static 600 width all the time whatever I try.
First two constraints are working, it appears 25 points below navigation bar and it centers it. But last one won't make anything.
How should I do this properly? So far have this:
[self.subView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:self.subView];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:self.subView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.navBar
attribute:NSLayoutAttributeBottom
multiplier:1
constant:25.0]];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:self.subView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:self.subView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0]];
Should I do something more with xib-file that it will make this width to fit it's parent view? I have also implemented initWithFrame, initWithCoder and intrinsicContentSize to my custom view.
Solution
I ended up to make containerView for my subView and center it vertically and horizontally and found right constraint for width. I also forgot to update my subView's view frames to match navigation bar width. Here is what I ended up to (if there is better way to do this, I take critic with pleasure):
self.containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 62, self.navBar.frame.size.width, 25)];
[self.view addSubview:self.containerView];
self.subView = [[SubView alloc]init];
[self.subView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.containerView addSubview:self.subView];
self.subView.view.frame = CGRectMake(0, 0, self.containerView.frame.size.width, self.containerView.frame.size.height);
[self.containerView addConstraint:
[NSLayoutConstraint constraintWithItem:self.subView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.containerView
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];
[self.containerView addConstraint:
[NSLayoutConstraint constraintWithItem:self.subView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.containerView
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[self.containerView addConstraint:
[NSLayoutConstraint constraintWithItem:self.subView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.containerView
attribute:NSLayoutAttributeWidth
multiplier:1.0f
constant:0]];
Delegate problem (solved)
For answer to this problem: check MisterGreen's answer below.
Another problem occured when I made UITapGestureRecognizer with delegate in my custom view. What I want is when I tap the view, it opens another ViewController. The delegate function is like this where I implement my custom view:
-(void)pushViewControllerUsingDelegate
{
NSLog(#"DELEGATE WAS : %#", self.subView.delegate);
[self pushViewController:self.anotherViewController animated:YES];
}
Now it gives exception when I tap the view:
DELEGATE WAS : <MasterViewController: 0x7fc96132e7d0> <-- Delegate is OK
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AnotherViewController 0x7fc961248230> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key subViewButton.'
What this actually means? I have this subViewButton IBOutlet with weak property, does it have something to do with this? Or is there another way to make this happen?
Tutorial which I followed: https://www.youtube.com/watch?v=TfKv1MYxnA4
Because there is not enough data to be exactly sure what is the problem you encountered, i have just created a code snippet that is working and doing exactly what you are trying to get.
About the constraints i think the problem is the hight constraint that is missing(unless you determined it elsewhere),
try to remember that when you add constraints provide enough data to the compiler to understand how to resize and position your subview according to it's superview, in your case it didn't know what is the hight cause you didn't supply nor bottom or hight constraint to determine it.
About the delegate method you didn't supply enough data to exactly determine what is the problem, so i've written something that i think is doing what you are trying to get.
This code snippet is tested and working:
The subview:
View.h
#protocol viewManager <NSObject>
#optional
- (void)subviewWasTapped;
#end
#interface View : UIView
#property (nonatomic, strong) id<viewManager>delegate;
#end
View.m
#implementation View
- (void)awakeFromNib{
[super awakeFromNib];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(viewWasTapped:)];
[self addGestureRecognizer:tap];
}
- (void)viewWasTapped:(NSNotification *)notification
{
[self sendViewWasTappedToDelegate];
}
- (void)sendViewWasTappedToDelegate
{
#synchronized(_delegate)
{
if([_delegate respondsToSelector:#selector(subviewWasTapped)])
{
[_delegate subviewWasTapped];
}
}
}
#end
FirstViewController:
#interface ViewController () <viewManager>
#property (nonatomic, strong) View *subview;
#end
#implementation ViewController
#synthesize subview;
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:#"View" owner:self options:nil];
subview = [subviewArray objectAtIndex:0];
[subview setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:subview];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:subview
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.topLayoutGuide
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0]];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:subview
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:subview
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0.0]];
// Height constraint to determine the
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:subview
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:25.0]];
[self.view layoutIfNeeded];
[subview setDelegate:self];
}
#pragma mark - viewManager delegate method
- (void)subviewWasTapped{
SecondeViewController *secondeVC = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondeViewController"];
[self.navigationController pushViewController:secondeVC animated:YES];
}

UINavigationController subview's won't come back after hide/show of navigation bar

I'm struggling with a subview of my navigation controller whose position and dimensions are constricted to the navigation bar. When I hide the navigation bar, the subview disappears (expected behavior). But when I'm bringing the navigation bar back the subview does not follow.
This subview is just a progress view (a custom UIView that I fill with a color depending on the progress of some tasks) on top of my navigation bar.
The positionning of the progress view is set with constraints in the viewDidLoad of my UINavigationController subclass :
- (void) viewDidLoad{
// The dimensions here are totally arbitrary since they are going to be defined automatically by the constraints
_progressView = [[CRProgressView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[self.view addSubview:_progressView];
UINavigationBar *navBar = [self navigationBar];
[self.view addConstraint: [NSLayoutConstraint constraintWithItem:_progressView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:navBar
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0]];
[self.view addConstraint: [NSLayoutConstraint constraintWithItem:_progressView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:navBar
attribute:NSLayoutAttributeLeft
multiplier:1
constant:0]];
[self.view addConstraint: [NSLayoutConstraint constraintWithItem:_progressView
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:navBar
attribute:NSLayoutAttributeRight
multiplier:1
constant:0]];
[self.view addConstraint: [NSLayoutConstraint constraintWithItem:_progressView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:navBar
attribute:NSLayoutAttributeHeight
multiplier:0
constant:2]];
[_progressView setTranslatesAutoresizingMaskIntoConstraints:NO];
}
From here everything looks fine but at some point, in the collectionView displayed in the navigation controller I call [self.navigationController setNavigationBarHidden:YES animated:YES] to clear the screen and have extra space when the user scrolls down in the collection view.
If the user scrolls up I show the navigation bar back but here the navigation bar appears without the progress view.
Here is the code used for showing and hiding the navigation bar in the collectionView, but I don't think the issue comes from here. It correctly hides and shows the navigationBar :
- (void) scrollViewDidScroll:(UIScrollView *)scrollView{
if (scrollView.contentOffset.y >= 0 && scrollView.contentOffset.y <= scrollView.contentSize.height - self.view.frame.size.height) {
if (self.lastContentOffsetY > scrollView.contentOffset.y) {
//Show navigation bar
if (self.navigationController.navigationBarHidden) {
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
}
else if (self.lastContentOffsetY < scrollView.contentOffset.y) {
if (!self.navigationController.navigationBarHidden) {
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
}
self.lastContentOffsetY = scrollView.contentOffset.y;
}
}
I don't understand why the progress view does not come back with the navigation bar when I'm calling [self.navigationController setNavigationBarHidden:NO animated:YES].
Any help will be greatly appreciated. Thanks in advance.
I'm not sure if it works 100% in your case, but you could try inserting this override method:
- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated{
[super setNavigationBarHidden:hidden animated: animated];
[self layoutIfNeeded];
}

Can't remove/hide recently added view from self.navigationcontroller.view

I have a Navigationviewcontroller with a tableview in it. I am adding a UIView to self.navigationcontroller.view and constraints for Auto Layout. When I try to remove it from superview or to hide it, nothing happens.
Any ideas?
How I create the View and Constraints
-(void)doneWithTraining{
//Create Backgroundview
UIView *groupView = [[UIView alloc] init];
[groupView setTranslatesAutoresizingMaskIntoConstraints:NO];
groupView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7];
groupView.tag = 999;
groupView.alpha = 0.0;
[self.navigationController.view addSubview:groupView];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:0]];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0f]];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0.0]];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeHeight
}
multiplier:1.0
constant:0.0]];
//Animate View
[UIView animateWithDuration:0.2 animations:^(void) {
groupView.alpha = 1.0;
}];
How I try to remove the View
- (void)closeFinishAlert{
UIView *grouView = [self.navigationController.view viewWithTag:999];
grouView.hidden = YES;
NSLog(#"Check if closeFinishAlert is called");
//[self.navigationController popViewControllerAnimated:YES];
}
What I also tried
This removes the view an its content, but after this there is no user interaction possible. It looks like a crash, but Xcode tells me that the app is still running.
- (void)closeFinishAlert{
UIView *groupView = [self.navigationController.view viewWithTag:999];
for (UIView *subview in groupView.subviews) {
subview.hidden = YES;
[subview removeFromSuperview];
}
[_groupView removeFromSuperview];
//[self.navigationController popViewControllerAnimated:YES];
}
If you are actually just presenting a view which you will remove for sure later on,
then its better to create a ViewController class for your view and present it modally using :
[self presentViewController:yourViewControllerObject animated:NO completion:nil];
you can later on remove this view using:
[self dismissViewControllerAnimated:NO completion:nil];
hope this helps !
Thanks to "GoGreen" green I found a solution which works for me.
Create Viewcontroller from ViewDidAppear
- (void)viewDidAppear:(BOOL)animated{
if (executedExercises.count == [_fetchedResultsController.fetchedObjects count] && self.groupView == FALSE) {
[self performSelector:#selector(doneWithTraining) withObject:nil afterDelay:0.0];
}
}
Header file
#property (strong, nonatomic) UIViewController *groupView;
Creating the Viewcrontroller and its content
-(void)doneWithTraining{
_groupView = [[UIViewController alloc] init];
[self presentViewController:_groupView animated:YES completion:nil];
_groupView.view.backgroundColor = [UIColor whiteColor];
//SubTitle
UILabel *subTitleLabel = [[UILabel alloc] init];
[subTitleLabel setFont:[UIFont fontWithName:#"HelveticaNeue-Light" size:18.0]];
subTitleLabel.textColor = [BackgroundLayer gray];
[subTitleLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
subTitleLabel.numberOfLines = 5;
subTitleLabel.adjustsFontSizeToFitWidth = YES;
subTitleLabel.textAlignment = NSTextAlignmentCenter;
[_groupView.view addSubview:subTitleLabel];
subTitleLabel.text = subTitleText;
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationLessThanOrEqual
toItem:_groupView.view
attribute:NSLayoutAttributeWidth
multiplier:0.0
constant:300.0f]];
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:_groupView.view
attribute:NSLayoutAttributeHeight
multiplier:0.0
constant:140]];
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:_groupView.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:_groupView.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];}
Removing ViewController
- (void)closeFinishAlert{
[_groupView dismissViewControllerAnimated:NO completion:nil];
[self.navigationController popViewControllerAnimated:YES];
}

View disappears when I set `translatesAutoresizingMaskIntoConstraints` to `NO`

I don't know if this is a bug or I'm doing something wrong:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIWindow *window = [self window];
UIViewController *main = [[UIViewController alloc] init];
UIViewController *vc1 = [[UIViewController alloc] init];
UIViewController *vc2 = [[UIViewController alloc] init];
[main addChildViewController:vc1];
[main addChildViewController:vc2];
UIView *mainView = [main view];
UIView *v1 = [vc1 view];
UIView *v2 = [vc2 view];
[v1 setBackgroundColor:[UIColor redColor]];
[v2 setBackgroundColor:[UIColor blueColor]];
[v1 setTranslatesAutoresizingMaskIntoConstraints:NO];
[v2 setTranslatesAutoresizingMaskIntoConstraints:NO];
[v1 setClipsToBounds:YES];
[v2 setClipsToBounds:YES];
[mainView setBackgroundColor:[UIColor yellowColor]];
[mainView addSubview:v1];
[mainView addSubview:v2];
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:v1
attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:mainView attribute:NSLayoutAttributeTop multiplier:1.0
constant:0.0];
[mainView addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:v1
attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual
toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0
constant:240.0];
[mainView addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:v2
attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:v1 attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
[mainView addConstraint:constraint];
[window setRootViewController:main];
[window setBackgroundColor:[UIColor greenColor]];
[window makeKeyAndVisible];
[main release];
[vc1 release];
[vc2 release];
return YES;
}
v1 and v2 appears nowhere when I launch the app.
If I comment out:
[v1 setTranslatesAutoresizingMaskIntoConstraints:NO];
[v2 setTranslatesAutoresizingMaskIntoConstraints:NO];
Cocoa wouldn't be able to satisfy my constraints because of the autoresizing mask that was translated into constraints.
You don't have any horizontal constraints and the height constraint for v2 is missing. Using the visual format language you need something like |-[v1]-|, |-[v2]-| and V:[v2]-|
NSArray *constraints;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"|-[v1]-|" options:0 metrics:nil views:#{#"v1": v1}];
[mainView addConstraints:constraints];

Resources