Question

I've got a UIViewController that does add a UISearchBar and a UITableView in it's -viewDidLoad method as subviews of it's view property. After adding those, I create constraints using the visual format language like this:

NSDictionary *views = @{@"searchBar": [_searchController searchBar],
                        @"dataTable": [self tableView]};

NSArray *horizontalSearchBarConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[searchBar]|"
                                                                                  options:0
                                                                                  metrics:nil
                                                                                    views:views];
NSArray *horizontalDataTableConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[dataTable]|"
                                                                                  options:0
                                                                                  metrics:nil
                                                                                    views:views];
NSArray *verticalSearchBarDataTableConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[searchBar(44)][dataTable]|"
                                                                                         options:0
                                                                                         metrics:nil
                                                                                           views:views];
NSMutableArray *allConstraints = [NSMutableArray new];
[allConstraints addObjectsFromArray:horizontalDataTableConstraints];
[allConstraints addObjectsFromArray:horizontalSearchBarConstraints];
[allConstraints addObjectsFromArray:verticalSearchBarDataTableConstraints];

[[self view] addConstraints:allConstraints];

Read: The widths should be the whole screen's width, the searchBar's height should be exactly 44 and the dataTable's height should stretch out from the bottom of the searchBar to the bottom of the view.

Before doing that, I set translatesAutoresizingMaskIntoConstraints for those views to NO. The UIViewController itself gets presented in a modal view. We're talking iOS 6.

What I get: An empty view. Just plain white.

What did I miss? I'm still new to Auto Layout and try to wrap my head around it.

Thanks!

Update: Adding the entire -viewDidLoad

- (void)viewDidLoad {
    [super viewDidLoad];    
    BOOL translatesAutoreszingMaskIntoConstraints = NO;

    [[self view] setTranslatesAutoresizingMaskIntoConstraints:translatesAutoreszingMaskIntoConstraints];

    // manually create the search bar
    UISearchBar *searchBar = [[UISearchBar alloc] init];
    [searchBar setDelegate:self];
    [searchBar setShowsCancelButton:NO];
    [searchBar setTranslatesAutoresizingMaskIntoConstraints:translatesAutoreszingMaskIntoConstraints];

    // create the search bar controller
    _searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
    [_searchController setDelegate:self];
    [[_searchController searchResultsTableView] setDelegate:self];
    [_searchController setSearchResultsDataSource:self];
    [_searchController setSearchResultsDelegate:self];

    // add the search bar
    [[self view] addSubview:[_searchController searchBar]];

    // manually create the table view and add it to the view
    _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
    [_tableView setBackgroundView:nil];
    [_tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLineEtched];
    [_tableView setSeparatorColor:NEA_COLOR_MEDIUM_GREY];
    [_tableView setBackgroundColor:NEA_COLOR_VIEW_BACKGROUND];
    [_tableView setDataSource:self];
    [_tableView setDelegate:self];
    [_tableView setTranslatesAutoresizingMaskIntoConstraints:translatesAutoreszingMaskIntoConstraints];

    [[self view] addSubview:[self tableView]];

    // set up the layout using Auto Layout
    NSDictionary *views = @{@"searchBar": [_searchController searchBar],
                            @"dataTable": [self tableView]};

    NSArray *horizontalSearchBarConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[searchBar]|"
                                                                                      options:0
                                                                                      metrics:nil
                                                                                        views:views];
    NSArray *horizontalDataTableConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[dataTable]|"
                                                                                      options:0
                                                                                      metrics:nil
                                                                                        views:views];
    NSArray *verticalSearchBarDataTableConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[searchBar(44)][dataTable]|"
                                                                                             options:0
                                                                                             metrics:nil
                                                                                               views:views];

    NSMutableArray *allConstraints = [NSMutableArray new];
    [allConstraints addObjectsFromArray:horizontalDataTableConstraints];
    [allConstraints addObjectsFromArray:horizontalSearchBarConstraints];
    [allConstraints addObjectsFromArray:verticalSearchBarDataTableConstraints];

    [[self view] addConstraints:allConstraints];

    // add our little gradient
    UIImage *shadow = [UIImage imageNamed:@"searchbar_bg_shadow"];
    UIImageView *shadowView = [[UIImageView alloc] initWithImage:shadow];
    [shadowView setFrame:CGRectMake(0, 44, 900, 14)];
    [shadowView setBackgroundColor:[UIColor clearColor]];
    [shadowView setTranslatesAutoresizingMaskIntoConstraints:YES];
    [[self view] addSubview:shadowView];

    // add the cancel button for the search bar
    UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ui_navigationbar_close"] style:UIBarButtonItemStyleBordered target:self action:@selector(cancel:)];
    [[self navigationItem] setRightBarButtonItem:cancelButton];

    // set a short back button title
    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@" " style:UIBarButtonItemStyleBordered target:nil action:nil];
    self.navigationItem.backBarButtonItem = backButton;
}

Update: Additional Infos

The encapsulating UINavigationController is being created through a storyboard. In there, added a UIViewController set to my class as it's rootViewController. Thats all.

When I manually add the width in that format string, it displays the views. So when I manually specify the sizes, it works. But then, I guess, I could simply use frames instead…

Was it helpful?

Solution

I don't know if your issue was resolved or not, but I noticed a potential problem in your code.

Try eliminating the following line of code:

[[self view] setTranslatesAutoresizingMaskIntoConstraints:translatesAutoreszingMaskIntoConstraints];

Don't set that property to NO for the root view.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top