2013-09-23 31 views
29

Tôi đang cố triển khai UITableView sẽ hoạt động tương tự như dòng thời gian của ứng dụng khách twitter. Ngay bây giờ tôi chỉ đơn giản là cố gắng để có được hai nhãn bên trong một UITableViewCell. Theo đề xuất của this Stack Overflow answer, tôi đang sử dụng một reuseIdentifier khác cho mỗi bố cục. Bố cục của tôi rất đơn giản, bao gồm một nhãn hoặc hai nhãn. Cuối cùng, tôi sẽ điều chỉnh chiều cao của UITableViewCells nhưng trước tiên tôi cần phải lấy các tế bào có nội dung.Cách tạo UITableViewCell tùy chỉnh theo lập trình bằng cách sử dụng AutoLayout

Tôi có thể nhận được các nhãn để hiển thị nếu tôi đặt khung của chúng với initWithFrame:, tuy nhiên các ràng buộc không được triển khai.

  • Câu hỏi: Điều gì ngăn cản các nhãn và khó khăn xuất hiện? Tôi rõ ràng thiếu một cái gì đó trong việc thực hiện của tôi của UITableViewCell nhưng tôi không có ý tưởng nó là gì.

  • Câu hỏi phụ: Tôi có đăng ký lớp UITableViewCell chính xác cho mỗi reuseIdentifier trong viewDidLoad không?

Điều này có thể gặp khó khăn nhưng Trình tạo giao diện gây nhầm lẫn cho tôi, tôi muốn thực hiện điều này tất cả trong mã.

Đây là mã cho các tùy chỉnh UITableViewCell tên TVTCell.h:

static NSString * const kCellIDTitle = @"CellWithTitle"; 
static NSString * const kCellIDTitleMain = @"CellWithTitleMain"; 

@interface TVTCell : UITableViewCell 
{ 
    NSString *reuseID; 
} 

@property (nonatomic, strong) UILabel *nameLabel; 
@property (nonatomic, strong) UILabel *mainLabel; 

@end 

Và TVTCell.m:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     reuseID = reuseIdentifier; 

     nameLabel = [[UILabel alloc] init]; 
     [nameLabel setTextColor:[UIColor blackColor]]; 
     [nameLabel setBackgroundColor:[UIColor colorWithHue:32 saturation:100 brightness:63 alpha:1]]; 
     [nameLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:18.0f]]; 
     [nameLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 
     [self.contentView addSubview:nameLabel]; 

     mainLabel = [[UILabel alloc] init]; 
     [mainLabel setTextColor:[UIColor blackColor]]; 
     [mainLabel setBackgroundColor:[UIColor colorWithHue:66 saturation:100 brightness:63 alpha:1]]; 
     [mainLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:18.0f]]; 
     [mainLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 
     [self.contentView addSubview:mainLabel]; 

     [self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO]; 

    } 
    return self; 
} 


- (void)updateConstraints 
{ 
    [super updateConstraints]; 

    NSDictionary *views = NSDictionaryOfVariableBindings(nameLabel, mainLabel); 
    if (reuseID == kCellIDTitle) { 
     NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameLabel]|" 
               options: NSLayoutFormatAlignAllCenterX 
               metrics:nil 
                views:views]; 
     [self.contentView addConstraints:constraints]; 
     constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[nameLabel]|" 
                   options: NSLayoutFormatAlignAllCenterX 
                   metrics:nil 
                   views:views]; 
     [self.contentView addConstraints:constraints]; 
    } 
    if (reuseID == kCellIDTitleMain) { 
     NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameLabel]|" 
                     options: NSLayoutFormatAlignAllCenterX 
                     metrics:nil 
                     views:views]; 
     [self.contentView addConstraints:constraints]; 

     constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mainLabel]|" 
                     options: NSLayoutFormatAlignAllCenterX 
                     metrics:nil 
                     views:views]; 
     [self.contentView addConstraints:constraints]; 

     constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[nameLabel][mainLabel]|" 
                   options: NSLayoutFormatAlignAllLeft 
                   metrics:nil 
                   views:views]; 
     [self.contentView addConstraints:constraints]; 

     [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:nameLabel 
            attribute:NSLayoutAttributeHeight 
            relatedBy:NSLayoutRelationEqual 
             toItem:nil 
            attribute:NSLayoutAttributeNotAnAttribute 
            multiplier:0.0 
             constant:44.0]]; 
     [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:nameLabel 
                    attribute:NSLayoutAttributeWidth 
                    relatedBy:NSLayoutRelationEqual 
                     toItem:self.contentView 
                    attribute:NSLayoutAttributeNotAnAttribute 
                    multiplier:0.0 
                     constant:1]]; 
    } 
} 

Xin lỗi, tấn mã. Dưới đây là UITableView tôi tableView:cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (indexPath.row == 0 || indexPath.row == 2 || indexPath.row == 3) { 
     TVTCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIDTitle forIndexPath:indexPath]; 

     [[cell nameLabel] setText:[nameArray objectAtIndex:indexPath.row]]; 

     return cell; 
    } else if (indexPath.row == 1 || indexPath.row == 4 || indexPath.row == 5) { 
     TVTCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIDTitleMain forIndexPath:indexPath]; 

     [[cell nameLabel] setText:[nameArray objectAtIndex:indexPath.row]]; 
     [[cell mainLabel] setText:[dataArray objectAtIndex:indexPath.row]]; 

     return cell; 
    } else 
    { 
     UITableViewCell *badCell = [[UITableViewCell alloc] init]; 
     NSLog(@"Warning! returning a cell that shouldnt be here"); 
     badCell.textLabel.text = @"Warning!"; 
     return badCell; 
    } 
} 

Và cuối cùng, phương pháp viewDidLoad của UITableView:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [[self tableView] registerClass:[TVTCell class] forCellReuseIdentifier:kCellIDTitle]; 
    [[self tableView] registerClass:[TVTCell class] forCellReuseIdentifier:kCellIDTitleMain]; 
} 
+0

Tôi thấy nhầm lẫn tương tự. cảm ơn câu hỏi của bạn – stackFish

Trả lời

31

Có rất nhiều điều sai trái với mã của bạn. Trước tiên, tôi nghĩ bạn sẽ tìm thấy, nếu bạn làm một số đăng nhập, updateConstraints đó không bao giờ được gọi. Tôi sẽ đặt tất cả các mã trong phương pháp init. Ngoài ra, có một số điều sai trái trong các ràng buộc của bạn. Các ràng buộc nơi bạn thiết lập chiều cao là 44 là không cần thiết vì bạn đã có các nhãn được ghim vào đến và dưới cùng của ô. Tôi không biết những gì bạn đang cố gắng để làm với điều cuối cùng, có vẻ như điều đó sẽ làm cho nameLabel 1 điểm rộng. Ngoài ra, bạn không nên đặt translatesAutoresizingMaskIntoConstraints thành NO cho chế độ xem nội dung, gây ra các hiệu ứng lạ. Vì vậy, đây là mã tôi nghĩ rằng bạn muốn:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     reuseID = reuseIdentifier; 

     nameLabel = [[UILabel alloc] init]; 
     [nameLabel setTextColor:[UIColor blackColor]]; 
     [nameLabel setBackgroundColor:[UIColor colorWithHue:32 saturation:100 brightness:63 alpha:1]]; 
     [nameLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:18.0f]]; 
     [nameLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 
     [self.contentView addSubview:nameLabel]; 

     mainLabel = [[UILabel alloc] init]; 
     [mainLabel setTextColor:[UIColor blackColor]]; 
     [mainLabel setBackgroundColor:[UIColor colorWithHue:66 saturation:100 brightness:63 alpha:1]]; 
     [mainLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:18.0f]]; 
     [mainLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 
     [self.contentView addSubview:mainLabel]; 

     NSDictionary *views = NSDictionaryOfVariableBindings(nameLabel, mainLabel); 
     if (reuseID == kCellIDTitle) { 
      NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameLabel]|" 
                      options: 0 
                      metrics:nil 
                      views:views]; 
      [self.contentView addConstraints:constraints]; 
      constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[nameLabel]|" 
                    options: 0 
                    metrics:nil 
                    views:views]; 
      [self.contentView addConstraints:constraints]; 
     } 
     if (reuseID == kCellIDTitleMain) { 
      NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameLabel]|" 
                      options:0 
                      metrics:nil 
                      views:views]; 
      [self.contentView addConstraints:constraints]; 

      constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mainLabel]|" 
                    options: 0 
                    metrics:nil 
                    views:views]; 
      [self.contentView addConstraints:constraints]; 

      constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[nameLabel][mainLabel(==nameLabel)]|" 
                    options: 0 
                    metrics:nil 
                    views:views]; 
      [self.contentView addConstraints:constraints]; 

     } 
    } 
    return self; 
} 
+0

Tuyệt vời, cảm ơn bạn đã sửa mã của tôi. Các ô đang hiển thị độc đáo, các ô được gắn nhãn đơn lẻ có tỷ lệ phù hợp với chiều cao ô mặc định của tôi là 88,0 và các ô được gắn nhãn kép chia sẻ không gian đồng đều. Trong câu trả lời Stack Overflow mà tôi đã đề cập trước đó, nhà phát triển nói: _ "Để kích thước nội dung nội tại của các khung nhìn này tăng chiều cao của khung nhìn nội dung của ô xem bảng bằng cách đảm bảo khả năng nén nội dung và ràng buộc nội dung trong chiều dọc không bị ghi đè bởi các ràng buộc ưu tiên cao hơn mà bạn đã thêm vào. "_ Làm thế nào và tôi sẽ thực hiện điều đó ở đâu? –

+0

@ShawnThroop, tôi không chắc nó sẽ hoạt động như thế nào - cách mà poster được sử dụng là một cách tiếp cận khác với những gì tôi thường sử dụng. Bạn có cần phải có chiều cao khác nhau cho các tế bào của bạn? Nếu vậy, chiều cao đó sẽ chỉ phụ thuộc vào số lượng nhãn, hoặc một số nhãn có số lượng dòng biến không? – rdelmar

+0

Cuối cùng, tôi nhắm đến một ô có chiều cao chủ yếu phụ thuộc vào số lượng hoặc dòng của một nhãn. Tôi cần phải đọc nhiều hơn về khả năng nén nội dung và nội dung ôm. Đối với Tài liệu Apple ... btw, Bạn thường làm như thế nào? Tôi đoán nó dễ dàng hơn những gì tôi đang cố gắng thực hiện. –

0

Bạn có thể tạo UITableViewCell lập trình nhanh bằng cách sử dụng bố cục tự động như dưới đây.Nó không phải chính xác các giải pháp của vấn đề trên của bạn như bạn đã xác định trong câu hỏi, đó là thực hiện chung chung hơn như thế nào để tạo ra tế bào tableView programatically trong nhanh chóng sử dụng tính năng tự động bố trí:

class ViewController: UITableViewController { 

override func viewDidLoad() { 
    super.viewDidLoad() 
    tableView.register(CustomCell2.self, forCellReuseIdentifier: "cell") 
} 

override func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return 2 
} 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CustomCell2 else { return UITableViewCell() } 
    cell.model = CellModel(labelString: "set constriant by code") 
    return cell 
    } 
    } 

Xác định mẫu:

struct CellModel { 
    let labelString : String 
} 

Xác định tuỳ chỉnh di động:

class CustomCell2 : UITableViewCell { 
private let label : UILabel = { 
    let label = UILabel() 
    label.translatesAutoresizingMaskIntoConstraints = false // enable auto layout 
    label.backgroundColor = .green // to visualize the background of label 
    label.textAlignment = .center // center text alignment 
    return label 
}() 

private func addLabel() { 
    addSubview(label) 
    NSLayoutConstraint.activate([ 
     // label width is 70% of cell width 
     label.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.7), 
     // label is horizontally center of cell 
     label.centerXAnchor.constraint(equalTo: centerXAnchor) 
    ]) 
} 

var model : CellModel? { 
    didSet { 
     label.text = model?.labelString ?? "" 
    } 
} 

// Init 
override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
    super.init(style: style, reuseIdentifier: reuseIdentifier) 
    addLabel() 
} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 
} 

This is the output of above program.

This is the actual project, you can check out.

Các vấn đề liên quan