1

我正在尝试以编程方式将标签添加到表格视图单元格的右上角。

[label addConstraint:[NSLayoutConstraint
    constraintWithItem:label
    attribute:NSLayoutAttributeRight
    relatedBy:NSLayoutRelationEqual
    toItem:cell
    attribute:NSLayoutAttributeRight
    multiplier:1.0
    constant:0]];

这给出了一个错误,说我引用了视图子树之外的东西,我猜是单元格本身?顶部和右侧是否需要两个单独的约束?

我更喜欢用约束来做正确的事情,但是我也尝试过手动获取单元格宽度来更改标签的位置。如果用户旋转设备,我将不得不在方向更改方法中添加代码的副本。如果我不能使用约束,我愿意这样做,但我无法获得单元格的正确宽度,这就是我尝试过的。

[label setFrame:CGRectMake(cell.frame.size.width-318, 10, 308, 30)];

似乎cell.frame.size.width没有得到正确的单元格宽度。

编辑:我计算出单元格宽度是相对于其中的内容的,所以我更改了上面的行以获取tableView.frame.size.width完成这项工作的整个 tableView 的 with。我仍然想得到一些关于约束的反馈,看看这是否可能。

编辑:这就是我设置单元格和标签的方式......

NSString *cellId = @"cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if(cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
}

UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(10, 10, 308, 30)];
label.text = @"Whatever text";

// Contraint added here

[cell.contentView addSubview: label];

编辑: `感谢@frozendevil

只是为了显示我在应用正确约束后用来设置标签宽度的最终代码......

[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:200]];
4

2 回答 2

3

一般来说,您不应该限制UITableViewCell单元格本身的视图,而是单元格的-contentView. 假设您已遵循通用表格视图最佳实践,您的标签-superview应该是单元格的-contentView- 将标签中的约束直接添加到单元格是跳过一层。


编辑:在解决这个问题几分钟后,我无法让单个约束样式代码正常运行(edit2:重新运行它,似乎两种风格都适合我),但使用视觉格式有效为了我:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        UILabel *label = [[UILabel alloc] init];
        label.text = @"Hallo!";
        label.backgroundColor = [UIColor redColor];
        [label sizeToFit];
        label.translatesAutoresizingMaskIntoConstraints = NO;

        [cell.contentView addSubview:label];

        NSDictionary *viewDict = @{@"label" : label};
        [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[label]|" options:0 metrics:0 views:viewDict]];
        [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label]" options:0 metrics:0 views:viewDict]];

        /* Or this!
        [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:label
                                                                     attribute:NSLayoutAttributeRight
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:cell.contentView
                                                                     attribute:NSLayoutAttributeRight
                                                                    multiplier:1.0
                                                                      constant:0]];
        */
    }

    return cell;
}

如果您想要更复杂的东西,最简单的方法可能是创建一个自定义 UIView 子类,该子类在内部布局并将其添加到单元格的-contentView.


附录:

这里有几种处理标签宽度的方法:

一种是调用constraintWithItem:...并使用NSLayoutAttributeWidth属性来固定大小。另一种方法是使用视觉格式样式来做本质上相同的事情。最好的办法是将标签上的压缩阻力设置得非常高(使用-[UIView setContentCompressionResistancePriority:forAxis:]),以便它自动调整到其内容而无需更改任何值。

如果您对自动布局的视觉格式语言不满意,我强烈建议您观看相关的 WWDC 视频并编写一些虚拟代码以适应它。我发现它是使用自动布局最有效的方式。

于 2013-03-22T03:03:28.043 回答
0

好吧,我认为这已经回答了吗?但是,如果您有 UITableViewCell 的自定义子类,则可以通过覆盖来轻松放置标签-layoutSubviews

@implementation MyCell : UITableViewCell

-(void)layoutSubviews
{
    [ super layoutSubviews ] ;

    CGRect bounds = self.contentView.bounds ;
    [ self.label sizeToFit ] ;
    self.label.anchorPoint = (CGPoint){ 1.0f, 0.0f } ;
    self.label.position = (CGPoint){ CGRectGetMaxX( bounds ), CGRectGetMinY( bounds } ;
}

@end
于 2013-03-22T05:35:08.767 回答