UITableViewController 表头添加一个带有自动布局约束的 UIButton

Posted

技术标签:

【中文标题】UITableViewController 表头添加一个带有自动布局约束的 UIButton【英文标题】:UITableViewController Table Header Add a UIButton with Autolayout Constraints 【发布时间】:2016-07-09 11:20:31 【问题描述】:

我尝试将 UIButton 添加到 UITableHeaderFooterView。

似乎我只能使用特定的 CGRect 框架在代码中固定它的位置和大小(

UIButton *scanQRCodeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
scanQRCodeButton.frame = CGRectMake(0.0f, 5.0f, 320.0f, 44.0f);
scanQRCodeButton.backgroundColor = [UIColor redColor];
[scanQRCodeButton setTitle:@"Hello" forState:UIControlStateNormal];    
[cell addSubview:scanQRCodeButton];

但我真正想要的是使用 centerX、centerY 和比例宽度等“约束”来使其适应不同的屏幕尺寸。那么问题就出在“constraintWithItems”部分:

从 UITableView 中获取 headerView:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
    static NSString *headerReuseIdentifier = @"TableViewSectionHeaderViewIdentifier";

    // Reuse the instance that was created in viewDidLoad, or make a new one if not enough.
    UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerReuseIdentifier];
    if (headerView == nil) 
        [tableView registerClass:[UITableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"TableViewSectionHeaderViewIdentifier"];
        headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"TableViewSectionHeaderViewIdentifier"];
    

    headerView.textLabel.text = @"MISSION";
    headerView.contentView.backgroundColor = [UIColor blackColor];

在与上面相同的块中的 headerView 顶部创建 UIButton:

UIButton *goBack = [[UIButton alloc] init];
    [goBack setImage:[UIImage imageNamed:@"Back"] forState:UIControlStateNormal];
    [goBack addTarget:self
           action:@selector(back:)
 forControlEvents:UIControlEventTouchUpInside];

    [headerView addSubview:goBack];

然后设置约束并返回headerView:

NSLayoutConstraint *constraint = [NSLayoutConstraint
                                  constraintWithItem:headerView.goBack
                                  attribute:NSLayoutAttributeWidth
                                  relatedBy:NSLayoutRelationEqual
                                  toItem:self.view
                                  attribute:NSLayoutAttributeCenterX
                                  multiplier:0.5
                                  constant:0];
    [headerView addConstraint:constraint];
    return headerView;

问题:当我在“constraintWithItem”中说“headerView.goBack”时,编译器警告我“在 UITableHeaderFooterView 类型的对象上找不到属性 goBack”。

更新 1

根据 Natarajan 的回答,我现在尝试这样做:

    headerView.translatesAutoresizingMaskIntoConstraints = false;
    goBack.translatesAutoresizingMaskIntoConstraints = false;
    NSDictionary *metrics   = @ @"width"           :   @(CGRectGetWidth(self.view.frame) / 10) ;
    [headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[goBack]|" options:0 metrics:metrics   views:@@"goBack":goBack]];
    [headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[goBack]|" options:0 metrics:metrics views:@@"goBack":goBack]];

当前问题:“指标”部分不起作用。我想要与 headerView 或 tableView 成比例的宽度而不是固定数字。我应该使用“self.view.frame”(也尝试过 self.tableView.frame)吗?

更新 2

现在headerView也有问题。如果我使用“headerView.translatesAutoresizingMaskIntoConstraints = false;”,我还需要手动设置headerView的位置。但是,使用以下代码,仍然无法正确设置 headerView。我尝试先将其添加到 tableView 并将其设置为与 UIButton 相同的方式,但它无法以相同的方式工作。

[headerView addSubview:goBack];
[tableView addSubview:headerView];

headerView.translatesAutoresizingMaskIntoConstraints = false;
goBack.translatesAutoresizingMaskIntoConstraints = false;

[headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[goBack(40.0)]|" options:0 metrics:nil views:@@"goBack":goBack]];
[headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[goBack(40.0)]|" options:0 metrics:nil views:@@"goBack":goBack]];
[tableView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[headerView]|" options:0 metrics:nil views:@@"headerView":headerView]];
[tableView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[headerView]|" options:0 metrics:nil views:@@"headerView":headerView]];

【问题讨论】:

【参考方案1】:

我认为“goBack”不能作为 headerView 属性访问。试着找到它。

    for (UIView *view in headerView.contentView.subviews) 
        if ([view isKindOfClass:[UIButton class]]) 
            //found button
        
    

【讨论】:

【参考方案2】:

编译器警告是正确的,因为UITableViewHeaderFooterView 没有您刚刚添加为UITableViewHeaderFooterView 子视图的名为“goBack”的属性。因此,只需尝试在约束代码中传递“goBack”按钮,如下所示。

在 HeaderView 上设置 goBack 按钮完全占据:

[headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[goBack]|" options:0 metrics:nil views:@@"goBack":goBack]];

[headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[goBack]|" options:0 metrics:nil views:@@"goBack":goBack]];

为特定的宽度和高度设置返回按钮:

[headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[goBack(40.0)]" options:0 metrics:nil views:@@"goBack":goBack]];

[headerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[goBack(30.0)]" options:0 metrics:nil views:@@"goBack":goBack]];

注意:在添加约束之前不要忘记设置headerView.translatesAutoresizingMaskIntoConstraints = false;goBack.translatesAutoresizingMaskIntoConstraints = false;

【讨论】:

谢谢!请参阅我最新的更新 1:我尝试改为使用比例宽度。 现在headerView也有问题。如果我使用“headerView.translatesAutoresizingMaskIntoConstraints = false;”,我还需要手动设置headerView的位置。但是,使用以下代码,仍然无法正确设置 headerView。我尝试先将其添加到 tableView 并将其设置为与 UIButton 相同的方式,但它无法以相同的方式工作。 我希望与 headerView 或 tableView 的宽度成比例,而不是固定数字。我在“metrics”中使用“self.view.frame”(也尝试过self.tableView.frame),但它们都不能正常工作。

以上是关于UITableViewController 表头添加一个带有自动布局约束的 UIButton的主要内容,如果未能解决你的问题,请参考以下文章

UISearchControllerDelegate - 搜索栏在表头中不可见

WPF的DataGrid怎么实现多行表头

当 UISearchController 处于活动状态时,iOS 9 searchBar 从表头视图中消失

MVVM后台ViewModel添加DataGrid表头

MVVM后台ViewModel添加DataGrid表头

MVVM后台ViewModel添加DataGrid表头