Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UITableView标题上的自动布局_Ios_Autolayout - Fatal编程技术网

Ios UITableView标题上的自动布局

Ios UITableView标题上的自动布局,ios,autolayout,Ios,Autolayout,我一直在寻找一个关于如何将自动布局添加到UITableView的明确答案。到目前为止,我的代码如下所示: - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { UINib *nib = [UINib nibWithNibName:@"HomeHeaderView" bundle:nil]; UIView *headerView = (UIView *)[

我一直在寻找一个关于如何将自动布局添加到UITableView的明确答案。到目前为止,我的代码如下所示:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UINib *nib = [UINib nibWithNibName:@"HomeHeaderView" bundle:nil];
    UIView *headerView = (UIView *)[nib instantiateWithOwner:self options:nil][0];
    [headerView.layer setCornerRadius:6.0];
    [headerView setTranslatesAutoresizingMaskIntoConstraints:NO];

//    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(headerView);
//    NSMutableArray *headerConstraints = [[NSMutableArray alloc] init];
//    [headerConstraints addObject:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[headerView]-|" options:0 metrics:nil views:viewsDictionary]];
//        [headerConstraints addObject:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[headerView]-|" options:0 metrics:nil views:viewsDictionary]];
//    [self.actionsTableView addConstraints:headerConstraints];
//    [self.view addSubview:headerView];
    tableView.tableHeaderView = headerView;
    [headerView layoutSubviews];

    NSLayoutConstraint *centerX = [NSLayoutConstraint constraintWithItem:headerView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
    NSLayoutConstraint *centerY = [NSLayoutConstraint constraintWithItem:headerView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
    NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:headerView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:300];
    NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:headerView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:90];
    [self.view addConstraints:@[centerX, centerY, width, height]];

    return headerView;
}
我的头视图基本上有一个nib文件,我想在UITableViewHeader中将该nib居中。我希望它在纵向和横向上相应地增长和收缩。老实说,我不确定我是否正确设置了约束。我不确定我的
toItem
应该是视图控制器的视图,还是表视图本身

我也不知道是否应该将headerview作为子视图添加到视图控制器的视图或tableview本身

或者,我不确定设置tableView.tableHeaderView=headerView是否足够

我真的不知道这种事情的最佳实践是什么。我不确定这一切是否也可以在IB中完成。目前,使用您看到的代码,我得到以下错误:

'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'
正是由于这个错误,我添加了
[headerView layoutSubviews]


对此有何想法?提前谢谢

真正的问题是您将
viewForHeaderInSection:
与表的
headerView
混淆了。他们没有关系

前者是节的标题。从委托方法返回视图

后者是表的标题。您可以在
viewDidLoad
中设置视图

约束以正常方式运行。但它们应该只是子视图的内部约束。形成视图时,该视图不在界面中。而且它的大小和位置在那个时候不由你决定。如果是节标题,它将自动调整大小以正确匹配(根据表格的宽度以及表格或代表对标题高度的说明)。如果它是表格标题,您可以给它一个绝对高度,但它的宽度将调整大小以正确匹配

下面是一个完整的示例,说明如何使用子视图上的内部约束构造节标题

- (UIView *)tableView:(UITableView *)tableView 
        viewForHeaderInSection:(NSInteger)section {
    UITableViewHeaderFooterView* h =
        [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"Header"];
    if (![h.tintColor isEqual: [UIColor redColor]]) {
        h.tintColor = [UIColor redColor];
        h.backgroundView = [UIView new];
        h.backgroundView.backgroundColor = [UIColor blackColor];
        UILabel* lab = [UILabel new];
        lab.tag = 1;
        lab.font = [UIFont fontWithName:@"Georgia-Bold" size:22];
        lab.textColor = [UIColor greenColor];
        lab.backgroundColor = [UIColor clearColor];
        [h.contentView addSubview:lab];
        UIImageView* v = [UIImageView new];
        v.tag = 2;
        v.backgroundColor = [UIColor blackColor];
        v.image = [UIImage imageNamed:@"us_flag_small.gif"];
        [h.contentView addSubview:v];
        lab.translatesAutoresizingMaskIntoConstraints = NO;
        v.translatesAutoresizingMaskIntoConstraints = NO;
        [h.contentView addConstraints:
         [NSLayoutConstraint 
          constraintsWithVisualFormat:@"H:|-5-[lab(25)]-10-[v(40)]"
          options:0 metrics:nil views:@{@"v":v, @"lab":lab}]];
        [h.contentView addConstraints:
         [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|[v]|"
           options:0 metrics:nil views:@{@"v":v}]];
        [h.contentView addConstraints:
         [NSLayoutConstraint
          constraintsWithVisualFormat:@"V:|[lab]|"
           options:0 metrics:nil views:@{@"lab":lab}]];
    }
    UILabel* lab = (UILabel*)[h.contentView viewWithTag:1];
    lab.text = self.sectionNames[section];
    return h;
}
我发现这个解决方案可能并不完美,因为他正在为
UITableViewHeaderFooterView
contentView
添加自定义视图和约束。这总是导致运行时出现自动布局警告:
当我们想要动态标题高度时,无法同时满足约束

我不确定原因,但我们可以假设iOS为
contentView
添加了一些额外的约束,以设置该视图的固定宽度和高度。在运行时生成的警告告诉我们,手动添加的约束不能满足这些要求,这是显而易见的,因为我们的约束应该拉伸标题视图,以便子视图可以适应它


解决方案非常简单-不要使用
UITableViewHeaderFooterView
contentView
,只需将子视图直接添加到
UITableViewHeaderFooterView
。我可以确认它在iOS 8.1上运行没有任何问题。如果您想添加多个视图并更改头的背景颜色,请考虑添加<代码> UIVIEW/COD> >填充头视图(由于AutoLayOutlook约束),然后您希望看到的所有子视图(我称之为“代码> Cuto CopeTrime</代码>”)。这样,我们可以避免任何自动布局问题,并在
UITableView

中自动调整标题。这是一个简洁的解决方案:

可选:initWithStyle:UITableViewStyleGrouped以防止浮动tableViewHeader

制作两个属性,标签仅用于演示:

@property (nonatomic, strong, readwrite) UIView *headerView;
@property (nonatomic, strong, readwrite) UILabel *headerLabel;
在viewDidLoad中设置所有内容:

self.headerView = [[UIView alloc] initWithFrame:CGRectZero];
self.headerLabel = [[UILabel alloc] init];
self.headerLabel.text = @"Test";
self.headerLabel.numberOfLines = 0; //unlimited
self.headerLabel.textAlignment = NSTextAlignmentCenter;
self.headerLabel.translatesAutoresizingMaskIntoConstraints = NO; //always set this to NO when using AutoLayout
[self.headerView addSubview:self.headerLabel];

NSString *horizontalFormat = @"H:|-[headerLabel]-|";
NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:horizontalFormat options:0 metrics:nil views:@{@"headerLabel":self.headerLabel}];
[self.headerView addConstraints:horizontalConstraints];

NSString *verticalFormat = @"V:|-[headerLabel]-|";
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:verticalFormat options:0 metrics:nil views:@{@"headerLabel":self.headerLabel}];
[self.headerView addConstraints:verticalConstraints];
在“标题视图”部分中:

return self.headerView;
self.headerLabel.preferredMaxLayoutWidth = tableView.bounds.size.width;
return [self.headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
在“头部高度”部分:

return self.headerView;
self.headerLabel.preferredMaxLayoutWidth = tableView.bounds.size.width;
return [self.headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

您能否提供有关如何继续的代码片段?在这一点上,我仍然对如何对节标题或tableview标题执行约束感到困惑:-\。您可以按照正常方式执行约束。但它们应该只是子视图的内部约束。形成视图时,该视图不在界面中。如果是节标题,它将自动调整大小以正确匹配。如果它是表格标题,你可以给它一个绝对高度,但是它的宽度会被调整到合适的大小。不幸的是,它不起作用
UITableViewHeaderFooterView
contentView
已计算大小,您将在运行时收到
无法同时满足约束的警告。看起来,虽然可以使用AutoLayout自动计算单元格高度,但无法对节标题进行计算。只是在iOS 8.1上检查了它。@matt如果您设置的约束应该能够拉伸标题以适应其内容,那么它在iOS 8上就不起作用了。正如我所说,您将无法同时满足约束。如果您将自定义子视图直接添加到标题视图,而不是添加到
contentView
,那么它会起作用。@matt这与喜欢与否无关:-)您已经很好地解释了如何将带有约束的自定义视图添加到标题视图中。我同意这是正确的做法。不幸的是,它将打破ios8自动管理的约束。我刚刚演示了如何解决这个问题以实现自动调整页眉大小。您可以返回
UITableViewAutomaticDimension
并自动调整收割台高度,而不是在
HeightsforHeader部分定义固定高度。这种方法非常好。谢谢