Objective-C将UILabel与表格视图单元格右上角对齐的简单约束

Objective-C将UILabel与表格视图单元格右上角对齐的简单约束,objective-c,Objective C,我试图以编程方式将标签添加到表视图单元格的右上角 [label addConstraint:[NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:cell attribute:NSLayoutAttributeRight multiplier:1.0 consta

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

[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
tableView.frame.size.width的宽度。我仍然希望得到一些关于约束的反馈,看看这是否可行

编辑:这是我如何设置单元格和标签的

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

通常,您不应该针对单元格本身约束
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:…
并使用
nslayoutatributeWidth
属性来固定大小。另一种方法是使用视觉格式样式来做本质上相同的事情。最好是将标签上的压缩阻力设置得非常高(使用
-[UIView SetContentCompressionResistance Priority:forAxis:][/code>),这样它就可以自动调整以适应其内容,而无需更改任何值


如果您对autolayout的视觉格式语言感到不舒服,我强烈建议您观看相关的WWDC视频,并编写一些虚拟代码来熟悉它。我发现这是使用自动布局最有效的方法。

我想这已经得到了回答?但是,如果您有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

我尝试将行更改为
到item:cell.contentView
,但我得到了同样的错误。您能否添加实际错误,并描述如何在问题中设置表视图/标签?我尝试更改开头以将约束添加到contentView,而不是标签
[cell.contentView addConstraint…
这样就消除了错误,但实际上什么也做不了。我将为我的问题添加更多细节。啊,你说得对。你只能“自上而下”添加约束,我应该注意到。:P我还更新了我的答案,提供了更多信息。谢谢@frozendevil,我尝试了你的两个建议,两个都奏效了。我还应该提醒其他人,如果没有行
label.translatesAutoResistingGMaskintoConstraints=NO;