以编程方式将 AutoLayout 用于搜索栏和 UITableView

Using AutoLayout programmatically for search bar and UITableView

我有一个几乎是全屏但没有状态栏的容器视图。

然后我创建了一个 UISearchController 和一个 UITableView。我正在使用 ios 9 并以编程方式执行操作。我遇到的错误是当触摸搜索栏时,范围选项在其下方打开,但 table 视图未正确向下滑动。我该如何解决这个问题?

我的viewDidLoad中的代码是:

// Search controller
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.scopeButtonTitles = @[@"A", @"B", @"C"];
self.searchController.searchBar.delegate = self;
[self.searchController.searchBar setTranslatesAutoresizingMaskIntoConstraints:NO];

// UITableView
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
self.tableView.translatesAutoresizingMaskIntoConstraints = NO;

// Container view is defined as the whole screen except 20 points at the top where the status bar is
[containerView addSubview:self.searchController.searchBar];
[containerView addSubview:self.tableView];

// The constraints - something is probably wrong here?

// Search bar constraints
NSDictionary *views2 = @{@"searchBar": self.searchController.searchBar};
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[searchBar]|" options:0 metrics:nil views:views2]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[searchBar]|" options:0 metrics:nil views:views2]];

// Tableview constraints
NSDictionary *views = @{@"tableView": self.tableView};
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[tableView]|" options:0 metrics:nil views:views]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[tableView]|" options:0 metrics:nil views:views]];

我需要使搜索栏范围选项和 table 视图一起正确滑动。这是如何以编程方式完成的?

您想将 UITableView 的顶部附加到 顶部布局指南的底部

顶部布局指南 仅在使用 故事板 时可用。

使用 Interface Builder 的另一个原因。


原因 1 = 你一开始就不会有这个错误,你将能够可视化你的约束,并且你可以用恰好 0 行代码实现所有这些。

我绝对肯定,只要付出适当的努力,并获得 SO 社区的支持,您就可以用代码完成所有事情。我只是发现 IB 不仅节省了设计时间,而且将调试卸载到 OS,并确保任何应用程序的使用寿命更长。 Storyboard 让您可以专注于您的应用与我的应用的不同之处,而不是为布局问题而苦恼。

嗯约束肯定是错的

他们应该是这样的:

NSDictionary *views = @{@"tableView": self.tableView,@"searchBar": self.searchController.searchBar};

[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[searchBar]|" options:0 metrics:nil views:views]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[tableView]|" options:0 metrics:nil views:views]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[searchBar(44)][tableView]|" options:0 metrics:nil views:views]];

首先,如您所见,您不需要为视图创建一个单独的字典,但您可以使用一个(更简单的恕我直言)

第二个约束条件如下:

  1. @"H:|[searchBar]|" --> 搜索栏固定在 containerView 的左侧和右侧,具有系统默认的 (8px) 边距
  2. @"H:|[tableView]|" --> tableView 固定在 containerView 的左右两侧,系统默认 (8px) margin
  3. @"V:|[searchBar(44)][tableView]|" -->

    • 搜索栏以默认边距固定在 containerView 的顶部,固定高度为 44 像素
    • tableView 的顶部固定在 searchBar 的底部,没有任何边距
    • tableView 的底部固定到 containerView 的底部

您不仅可以从 Interface Builder (Storyboard/xib) 添加 top layout guide 约束,还可以通过编程方式添加。

你试过 KVConstraintExtensionsMaster 库来应用我已经实现的约束吗?使用此库,您可以通过编程方式添加 top and bottom layout guide 约束,以及更多在故事板或 xib 中不可能或非常困难的约束。

将下面的代码放在 viewDidLoad 中是:

    // create containerView
    containerView = [UIView prepareNewViewForAutoLayout];
    [containerView setBackgroundColor:[UIColor brownColor]];
    [self.view addSubview:containerView];

    // create Search controller
    self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
    self.searchController.searchResultsUpdater = self;
    self.searchController.dimsBackgroundDuringPresentation = NO;
    self.searchController.searchBar.delegate = self;
    self.searchController.searchBar.scopeButtonTitles = @[@"A", @"B", @"C"];

    // create UITableView
    self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
    [_tableView setBackgroundColor:[UIColor blueColor]];

    [self.tableView prepareViewForAutoLayout];

    [containerView addSubview:self.searchController.searchBar];
    [containerView addSubview:self.tableView];

    // now applying the constraints by using KVConstraintExtensionsMaster library
    // adding leading and trailing contraints of containerView
    [containerView applyLeadingAndTrailingPinConstraintToSuperviewWithPadding:defualtConstant];

    // adding Top and Bottom Layout Guidecontraint of containerView
    [self applyTopLayoutGuideConastrainToView:containerView withPadding:defualtConstant];
    [self applyBottomLayoutGuideConastrainToView:containerView withPadding:defualtConstant];

    // adding Top constraint of searchBar
    [self.searchController.searchBar applyTopPinConstraintToSuperviewWithPadding:defualtConstant];

    // adding leading and trailing contraints of searchBar
    [self.searchController.searchBar applyLeadingAndTrailingPinConstraintToSuperviewWithPadding:defualtConstant];

    // adding leading and trailing contraints of tableView
    [self.tableView applyLeadingAndTrailingPinConstraintToSuperviewWithPadding:defualtConstant];

    // adding Bottom constraint of tableView
    [self.tableView applyBottomPinConstraintToSuperviewWithPadding:defualtConstant];

    // adding vertical constraint between two Sibling views
    // to increase the vertical space between searchBar & tableView, update the spacing value like 10.0 or what you want  
    [self.searchController.searchBar applyConstraintFromSiblingViewAttribute:NSLayoutAttributeBottom toAttribute:NSLayoutAttributeTop ofView:self.tableView spacing:defualtConstant];