【问题标题】:Using AutoLayout programmatically for search bar and UITableView以编程方式对搜索栏和 UITableView 使用 AutoLayout
【发布时间】:2016-02-23 21:24:58
【问题描述】:

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

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

我 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]];

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

【问题讨论】:

  • 具有讽刺意味的是,我的主要错误被发现隐藏在我的代码中,几周前我“不小心”在表格视图中添加了一个愚蠢的偏移量,导致我的大部分问题(不在上面的代码中)

标签: ios uitableview autolayout ios9 uisearchcontroller


【解决方案1】:

您不仅可以从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];

【讨论】:

  • 概念性问题:当你有一个图形工具为你完成所有繁重的工作时,为什么还要在黑暗中编写代码,所有这些都可能存在 0 个错误?
  • 我在反引号(`)之间写了代码,例如-`这里的代码`你也可以使用排序键Command + k。
  • @SwiftArchitect 你能告诉我你说的是哪个图形工具吗?我该如何使用它?
  • 澄清:您的代码没有任何问题,并且您以清晰、简洁的方式呈现它。我发现 不编码 是一种更好的方法,而 Interface Builder Preview 编辑器允许您在所有方向上可视化所有设备的布局,而无需编码、构建或运行单行代码。更简单,如果不是更容易的话。
【解决方案2】:

那么约束肯定是错误的

它们应该是这样的:

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 以系统默认 (8px) 边距固定在 containerView 的左右两侧
  3. @"V:|[searchBar(44)][tableView]|" -->

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

【讨论】:

  • 但是当范围选项出现时会发生什么?搜索栏达到 88 点,但表格视图位于范围选项下。
  • 是的,但是当 44 点的搜索栏转到 88 点的搜索栏和范围栏时会发生什么?
  • 你试过不带上搜索栏的固定吗?
  • 你的意思是这样的:@"V:|[searchBar][tableView]|"而不是这个:@"V:|[searchBar(44)][tableView]|"?那么是的
  • 没有。范围栏最终仍然出现在顶部的 tableview 单元格上。我在 ios 9.0
【解决方案3】:

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

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

使用 Interface Builder 的另一个理由。


原因 1 = 你一开始就不会有这个错误,你可以可视化你的约束,你可以用 0 行代码来实现所有这些。 p>

我绝对肯定,只要付出适当的努力,并得到 SO 社区的支持,您就可以在代码中完成所有工作。我只是发现 IB 不仅节省了设计时间,而且将调试工作转移到了操作系统上,并确保任何应用程序的使用寿命更长。 故事板让您可以专注于使您的应用与我的应用不同的地方,而不是为布局故障而苦恼。

【讨论】:

  • 是的,我现在就这样做。不过我想学习底层代码。
  • 虽然我完全理解您的意思,但不要误以为您通过这种方式养成了更好的习惯。以我的拙见,您将通过使用 Apple 多年前发布的工具学到同样多的东西。 0 行代码将提高您的生产力、代码质量和应用程序的超速。
  • 是的,我听到了。那么没有Interface Builder就没有办法做我想做的事吗?
  • 如何在情节提要中添加 UISearchController?在 IB 中,我只看到 Search Bar 和 SearchDisplayController。
  • @SwiftArchitect,您不仅可以从 Interface Builder (Storyboard/xib) 添加顶部布局指南约束,还可以通过编程方式添加。查看我的答案,使用 KVConstraintExtensionsMaster 库以编程方式添加顶部和底部布局指南约束。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多