以编程方式布置UITableViewCell

时间:2016-03-30 07:43:24

标签: ios objective-c uitableview autolayout

我是iOS开发的新手,我想创建一个自定义的UITableViewCell。我更喜欢在代码中而不是在IB中进行布局。我创建了一个自定义单元类,只添加了一个UIImageView进行测试。我应用了以下约束:

-(void)layoutSubviews {

    NSDictionary *views = @{
                       @"view": self.mCoverImage
                       };

    NSArray* horizontalConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:NSLayoutFormatAlignmentMask metrics:nil views:views];

    NSArray* verticalConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view(170)]|" options:NSLayoutFormatAlignmentMask metrics:nil views:views];

    [self.contentView addConstraints:horizontalConstraint];
    [self.contentView addConstraints:verticalConstraint];
}

但这在控制台中给了我以下内容:

2016-03-30 11:37:08.818 Testing3[87057:1179225] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x7fb033e721d0 h=--& v=--& V:[naruto(0)]   (Names: naruto:0x7fb033fb4c70 )>",
    "<NSLayoutConstraint:0x7fb033e6fab0 V:[naruto(170)]   (Names: naruto:0x7fb033fb4c70 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7fb033e6fab0 V:[naruto(170)]   (Names: naruto:0x7fb033fb4c70 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2016-03-30 11:37:08.819 Testing3[87057:1179225] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 

我的代码出了什么问题?

修改

为了方便起见,请在下面找到代表的完整源代码以及单元格实现:

这是表格视图委托:

#import "TopPointsController.h"
#import "TestCell.h"

@interface TopPointsController ()
@property (strong, nonatomic) IBOutlet UITableView *mainTable;

@end

@implementation TopPointsController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.mainTable.rowHeight = UITableViewAutomaticDimension;
    self.mainTable.estimatedRowHeight = 50.0;
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 50;
}

-(UITableViewCell*)tableView:(UITableView*) tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {

    TestCell* cell = [tableView dequeueReusableCellWithIdentifier:@"TestCell"];
    if(cell == nil) {
        cell = [[TestCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"TestCell"];
    }

    return cell;
}

@end

这是单元格实现:

#import "TestCell.h"

@implementation TestCell

- (void)awakeFromNib {
    // Initialization code
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.mCoverImage = [[UIImageView alloc] init];
        UIImage* image = [UIImage imageNamed:@"naruto"];
        self.mCoverImage.image = image;
        [self.contentView addSubview:self.mCoverImage];

        NSDictionary *views = @{
                                @"view": self.mCoverImage
                                };

        self.mCoverImage.translatesAutoresizingMaskIntoConstraints = NO;


        NSArray* horizontalConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:NSLayoutFormatAlignmentMask metrics:nil views:views];
        NSArray* verticalConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view(170)]" options:NSLayoutFormatAlignmentMask metrics:nil views:views];

        [self.contentView addConstraints:horizontalConstraint];
        [self.contentView addConstraints:verticalConstraint];
    }
    return self;
}

@end

1 个答案:

答案 0 :(得分:1)

问题在于:

V:|[view(170)]|

基本上你是告诉视图在顶部和底部垂直伸展,就像它们固定在超视图上一样,但你也说高度必须是170点。
如果单元格高度大于或小于170磅,则无法满足您的约束条件 要解决该问题,您可以:

  • 删除高度限制V:|[view]|
  • 移除顶部或底部约束V:[view(170)]|V:|[view(170)]
  • 降低其中一个约束优先级,因此如果两个约束优先级之间存在冲突,则优先级较高的优先级将获胜V:[view(170@250)]|

    另请注意在您添加的图片视图中将translatesAutoresizingMaskIntoConstraints设置为false。


不要在layoutSubview中添加约束,如果要覆盖它,请始终致电super.layoutSubviews() 可以多次调用layoutSubviews,并且每次调用都会向视图添加约束。在awakeFromNibinitWithStyleupdateConstraints中添加约束(但请注意执行一次)