2010-07-28 28 views
9

Theo mặc định, một cá thể UITableViewCell đặt cặp nhãn là textLabel/detailTextLabel ở giữa chế độ xem chính. Tôi thích có các cặp liên kết với phía trên cùng của tế bào. Làm thế nào để tôi làm điều đó theo chương trình?UITableViewCell. Làm cách nào để tôi căn chỉnh textLabel thành hàng đầu?

Cảm ơn,
Doug

+0

Đây có phải là câu hỏi liên quan đến Iphone không? –

+0

Có. UITableViewCell cùng với UITableView và UITableViewController là duy nhất cho hệ điều hành iPhone. Không? – dugla

+1

Vậy tại sao không phải là câu hỏi được gắn thẻ iphone? Hãy cẩn thận khi gắn thẻ, để những người khác có thể hưởng lợi từ các câu hỏi của bạn. –

Trả lời

24

Các tài liệu mô tả - [UIView layoutSubviews] như

"Overridden by subclasses to layout subviews when layoutIfNeeded is invoked. The default implementation of this method does nothing." 

Đó mô tả không được xây dựng, nhưng là chính xác. Trong trường hợp này, hành vi của phương pháp là bố cục các bản xem phụ của bạn. Nó sẽ được gọi bất cứ lúc nào định hướng thiết bị thay đổi. Nó cũng được lên kế hoạch cho lời gọi sau này bất cứ khi nào bạn gọi -setNeedsLayout.

Kể từ khi triển khai của UIView không có gì, (và tôi giả định tương tự cho UIControl), bạn sẽ có được tự do sáng tạo tổng thể để làm cho các phân đoạn con của UIView được định vị ở bất cứ đâu bạn muốn.

Trong subclassing một UITableViewCell, bạn có một vài lựa chọn để thử:

  1. -layoutSubviews Override và
    1. thao tác các vị trí của các built-in textLabel và quan điểm -detailLabel.
  2. Override -viewDidLoad,
    1. tạo hai của UILabels của riêng bạn để cung cấp các văn bản và văn bản chi tiết,
    2. thêm chúng vào self.contentView, và
    3. -layoutSubviews override để thao tác vị trí tùy chỉnh của bạn UILabel xem

trong một related SO question, các reco mmendation là để tránh # 1, thao tác với textLabel dựng sẵn và detailTextLabel.

Một cược đáng tin cậy hơn sẽ làm điều gì đó như thế này:


@interface MyTableViewCell : UITableViewCell { 
    UILabel *myTextLabel; 
    UILabel *myDetailTextLabel; 
} 
// ... property declarations 
@end 

@implementation MyTableViewCell 
@synthesize myTextLabel, myDetailTextLabel; 

- (id) initWithFrame: (CGRect)frame { 
    self = [super initWithFrame: frame]; 
    if (self) { 
     myTextLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; 
     [self.contentView addSubview: myTextLabel]; 

     myDetailTextLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; 
     [self.contentView addSubview: myDetailTextLabel]; 
    } 
    return self; 
} 

- (void) dealloc { 
    [myTextLabel release]; 
    [myDetailTextLabel release]; 
    [super dealloc]; 
} 

- (void) layoutSubviews { 

    // Let the super class UITableViewCell do whatever layout it wants. 
    // Just don't use the built-in textLabel or detailTextLabel properties 
    [super layoutSubviews]; 

    // Now do the layout of your custom views 

    // Let the labels size themselves to accommodate their text 
    [myTextLabel sizeToFit]; 
    [myDetailTextLabel sizeToFit]; 

    // Position the labels at the top of the table cell 
    CGRect newFrame = myTextLabel.frame; 
    newFrame.origin.x = CGRectGetMinX (self.contentView.bounds); 
    newFrame.origin.y = CGRectGetMinY (self.contentView.bounds); 
    [myTextLabel setFrame: newFrame]; 

    // Put the detail text label immediately to the right 
     // w/10 pixel gap between them 
    newFrame = myDetailTextLabel.frame; 
    newFrame.origin.x = CGRectGetMaxX (myTextLabel.frame) + 10.; 
    newFrame.origin.y = CGRectGetMinY (self.contentView.bounds); 
    [myDetailTextLabel setFrame: newFrame]; 
} 

@end 

Trong MyTableViewCell, bạn sẽ bỏ qua các nhãn văn bản tích hợp và sử dụng UILabels tùy chỉnh của riêng bạn. Bạn kiểm soát hoàn toàn việc định vị chúng trong nội dung của ô xem bảng.

Tôi đang để lại rất nhiều thứ. Khi thực hiện bố cục tùy chỉnh với nhãn văn bản, bạn muốn xem xét:

  • Tìm ra thuật toán bố cục của riêng bạn.

    Tôi đang sử dụng thuật toán bố cục ở trên thay đổi kích thước các UIL tùy chỉnh để phù hợp với nội dung văn bản của chúng, sau đó định vị chúng cạnh nhau. Bạn có thể muốn một cái gì đó cụ thể hơn cho ứng dụng của mình.

  • Giữ nhãn tùy chỉnh trong chế độ xem nội dung.

    Trong chế độ xem trướcSubviews, bạn có thể muốn logic giữ cho UILabels tùy chỉnh có kích thước và được định vị sao cho chúng không nằm ngoài giới hạn của nội dung trực tuyến. Với logic bố cục ngây thơ của tôi, bất kỳ văn bản dài nào được thả vào UILabel (hoặc cả hai) đều có thể khiến các nhãn được định vị ngay ngoài giới hạn nội dung.

  • Cách xử lý -viewDidLoad/-viewDidUnload.

    Như được mã hóa ở trên, lớp con này không xử lý được tải từ ngòi bút. Bạn có thể muốn sử dụng để IB bố trí di động của bạn, và nếu bạn làm thế, bạn sẽ cần phải suy nghĩ về -viewDidLoad/-viewDidUnload/-initWithCoder:

+0

Cảm ơn bạn đã chiếu sáng toàn diện về bố cụcSubviews. Không có ý tưởng đó là dễ sử dụng. Mát mẻ. – dugla

+0

Câu trả lời hay, nhưng tôi nghĩ bạn nên viết lại initWithStyle: reuseIdentifier: thay vì phương thức initWithFrame:. – Rodrigo

+1

Tôi không chắc chắn có rất nhiều lợi ích để ghi đè 'initWithStyle: reuseIdentifier:' vs 'initWithFrame'. Đặc biệt là kể từ khi reuseIdentifier có thể được thiết lập rõ ràng sau khi khởi tạo. Đối với các lớp con UITableViewCell, có thể là một -initWithReuseIdentifier: sẽ là một trình khởi tạo được chỉ định thuận tiện hơn. Đối với các lớp con của ô, bỏ qua thuộc tính 'style'/cho phép nó lấy giá trị mặc định có vẻ là cách thực hành tốt nhất. Điều đó nói rằng, bạn có thể xác định hằng số kiểu của riêng bạn. Nhưng ai sẽ sử dụng nó? –

0

diện của UITableViewCell textLabel và detailTextLabel không trực tiếp sửa đổi, ngoại trừ bằng cách chọn một trong các kiểu định nghĩa được cung cấp bởi các API.

Nếu bạn muốn tùy chỉnh bố cục UITableViewCell, bạn sẽ cần phải phân lớp nó và ghi đè phương pháp -layoutSubviews.


- (void) layoutSubviews { 
    // [super layoutSubViews]; // don't invoke super 

    ... do your own layout logic here 
} 
+0

bố cụcSubviews là phương pháp tôi chưa bao giờ ghi đè và được ghi lại tài liệu kém. Bạn có thể xây dựng một chút không? Cảm ơn. – dugla

2

Các phương pháp sau đây trong lớp con UITableViewCell bạn nên nhanh chóng và chính xác căn chỉnh cả textLabel và detailTextLabel vào đầu ô (gật đầu với mã của Bill), mà không thêm bất kỳ chế độ xem tùy chỉnh nào.

- (void) layoutSubviews 
{ 
    [super layoutSubviews]; 

    // Set top of textLabel to top of cell 
    CGRect newFrame = self.textLabel.frame; 
    newFrame.origin.y = CGRectGetMinY (self.contentView.bounds); 
    [self.textLabel setFrame:newFrame]; 

    // Set top of detailTextLabel to bottom of textLabel 
    newFrame = self.detailTextLabel.frame; 
    newFrame.origin.y = CGRectGetMaxY (self.textLabel.frame); 
    [self.detailTextLabel setFrame:newFrame]; 
} 
Các vấn đề liên quan