2013-07-16 34 views
5

Hãy nói rằng tôi cóSử dụng dequeueReusableCellWithIdentifier cho tế bào tùy chỉnh

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

    if (!cell) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
    } 
    else 
    { 
     return cell; 
    } 

    UILabel * nameLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 15, box.size.width, 19.0f)]; 
    nameLabel.text = name; 
    [nameLabel setTextColor: [UIColor colorWithRed: 79.0f/255.0f green:79.0f/255.0f blue:79.0f/255.0f alpha:1.0f]]; 
    [nameLabel setFont: [UIFont fontWithName: @"HelveticaNeue-Bold" size: 18.0f]]; 
    [nameLabel setBackgroundColor: [UIColor clearColor]]; 
    nameLabel.textAlignment = NSTextAlignmentCenter; 
    [cell addSubview: nameLabel]; 
} 

gì đó sẽ làm gì?

Nếu ô không phải là nil, và giả sử bạn đang ở hàng 5, nó sẽ trả về ô cho hàng 5 với nhãn văn bản chính xác, v.v.

Về cơ bản, câu hỏi của tôi là, nếu bạn có các ô tùy chỉnh có nhãn, số lần xem lại, v.v. Bạn sử dụng cellForRowAtIndexPath với dequeueReusableCellWithIdentifier như thế nào?

+0

nó cũng tương tự cho tableviewcell cho dù đó là tùy chỉnh hay không. Bạn nhận được giữ của đối tượng di động và thiết lập lại tất cả các tiểu bang của nó và sau đó thêm nội dung của bạn. Vì vậy, có, bạn sẽ phải dọn dẹp nội dung trong nhãn/hình ảnh (bằng cách đặt nó thành không) và cung cấp nội dung mới. – rydgaze

+1

Trong mã này, không có cách nào để truy cập lại đối tượng UILabel ngoại trừ bằng cách liệt kê các bản xem trước của ô rất xấu xí. Tốt hơn nên sử dụng một lớp con của UITableViewCell có thuộc tính UILabel để nó có thể truy cập dễ dàng –

Trả lời

0

Có, khử một ô mà bạn đã thêm các nhãn đó sẽ vẫn có chúng và văn bản của chúng giống như khi bạn tạo nó khi bạn tạo ô cụ thể đó.

Tạo lớp con UITableViewCell, hãy gọi nó là MyTableViewCell có thuộc tính chứa nhãn/imageViews/v.v mà nó sẽ cần. Một khi bạn đã dequeued hoặc phân bổ init'ed một trong MyTableViewCell của bạn, sau đó bạn có thể thiết lập các văn bản/hình ảnh/vv trên các thuộc tính này. Như thế này:

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

    static NSString *CellIdentifier = @"identifier"; 

    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 
     cell = [[MyTableViewCell alloc] initWithStyle:UITableViewStylePlain reuseIdentifier:CellIdentifier]; 
    } 



    cell.nameLabel.text = name; 
    cell.imageView.image = anImage; 


    return cell; 
} 

Một vấn đề lớn với phương pháp của bạn là điều kiện xung quanh khử và tạo. Trong phương pháp của bạn, bạn chỉ thiết lập các tế bào nhãn khi nó được phân bổ init'ed (bạn ngay lập tức trả lại một tế bào dequeued mà không cần định dạng nó). Tuy nhiên, bạn muốn thiết lập này xảy ra cho cả hai tế bào được giải mã và được tạo thủ công. Lưu ý điều này xảy ra như thế nào trong phương thức của tôi, câu lệnh return ở dưới cùng. Điều này sẽ đảm bảo rằng cả hai tế bào được tạo và tái sử dụng đều có dữ liệu thích hợp.

EDIT: Một điều quan trọng tôi bỏ ra, bạn sẽ khởi tạo các thuộc tính của ô trong phương thức initWithStyle: reuseIdentifier: và thêm chúng dưới dạng xem phụ vào ô. Điều này là như vậy khi bạn đi để thiết lập các văn bản của nhãn (hoặc bất cứ điều gì) trong phương pháp cellForRowAtIndexPath của bạn, nó đã được tạo ra. Về cơ bản, các tế bào quản lý việc tạo ra các khung nhìn riêng của nó và đại biểu UITableView chỉ phải lo lắng về việc lấp đầy các khung nhìn đó bằng dữ liệu.

3

Bạn cố gắng loại bỏ một ô. Nếu cố gắng thất bại (ô là nil), thì bạn tạo một ô và cấu hình nó là các khung nhìn (không phải dữ liệu bên trong khung nhìn). Sau đó, bạn điền các chế độ xem với bất kỳ dữ liệu hoặc cài đặt nào thay đổi ô thành ô. Ngoài ra, bạn nên thêm bất kỳ chế độ xem tùy chỉnh nào vào ô contentView của ô, chứ không phải chính ô đó.

#define NAME_LABEL_TAG 1234 

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

    if (!cell) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     UILabel * nameLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 15, box.size.width, 19.0f)]; 
     nameLabel.tag = NAME_LABEL_TAG; 
     [nameLabel setTextColor: [UIColor colorWithRed: 79.0f/255.0f green:79.0f/255.0f blue:79.0f/255.0f alpha:1.0f]]; 
     [nameLabel setFont: [UIFont fontWithName: @"HelveticaNeue-Bold" size: 18.0f]]; 
     [nameLabel setBackgroundColor: [UIColor clearColor]]; 
     nameLabel.textAlignment = NSTextAlignmentCenter; 
     [cell.contentView addSubview: nameLabel]; 
    } 

    // Populate views with data and retrieve data for "name" variable 
    UILabel *nameLabel = (UILabel *)[cell.contentView viewWithTag:NAME_LABEL_TAG]; 
    nameLabel.text = name; 

    // Return fully configured and populated cell 
    return cell; 
} 

Nếu bạn có một tế bào phức tạp, nó thường dễ dàng hơn để tạo ra nó trong Interface Builder và lớp con UITableViewCell để bạn có thể có các thuộc tính tùy chỉnh mà tham khảo Nhãn của bạn, Buttons vv

+10

Bạn nên lưu ý rằng nếu bạn tạo ô trong bảng phân cảnh, dequeueReusableCellWithIdentifier: được đảm bảo trả về một ô, vì vậy mệnh đề if (! Ô) của bạn sẽ không bao giờ chạy. – rdelmar

+0

bạn có thể gọi nameLabel.text = name; mặc dù nameLabel không được tham chiếu khi ô không phải là 0. –

+0

nameLabel sẽ nằm ngoài phạm vi của 'if (! Cell)'. Bạn nên sử dụng viewWithTag để lấy nhãn. –

0

UITableView lúc đầu hỏi bạn cho số lượng các tế bào dự kiến. Sau đó, nó tải thông qua - tableView: cellForRowAtIndexPath: phương pháp các tế bào đó sẽ được hiển thị + một số để di chuyển trơn tru, nhiều đối tượng nó không tạo ra. Các đối tượng đã tạo (bởi người dùng) được lưu trữ trong dạng xem bảng và bạn có thể truy cập không được sử dụng thông qua phương thức dequeueReusableCellWithIdentifier:. TableView yêu cầu người dùng sửa đổi các ô hiện đang được tạo khi di chuyển. Nếu đây là đối tượng miễn phí - hãy lấy nó từ dequeueReusableCellWithIdentifier: một đối tượng khác - tạo một đối tượng mới.

0

để không phải phân bổ từng ô bảng, bảng chỉ phân bổ những gì cần thiết. Nếu chỉ có 8 ô phù hợp trên một trang thì chế độ xem bảng sẽ chỉ phân bổ 8 ô hoặc 9 i không nhớ nếu nó có đệm. Khi bạn cuộn một khung nhìn và ô đi ra khỏi trang, ô được xếp hàng để được sử dụng lại, thay vì phân bổ lại một ô mới, khung nhìn bảng sẽ có một khung hiện có được gọi là dequeue-ing.Khi bạn tạo/phân bổ các ô của mình, bạn cung cấp cho nó một số nhận dạng, mã định danh này được sử dụng để truy xuất một ô được đánh dấu bằng chuỗi đó.

0

Bạn có thể sử dụng này

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath 

này có sẵn sau khi iOS 6

Hoặc bạn cũng có thể đăng ký lớp học của bạn ở đâu đó trong viewDidLoad và sử dụng ResuseIdentifier, vì vậy bạn không cần phải viết ResuseIdentifier gia cellForRowAtIndexPath

- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0) 

Hy vọng điều này sẽ giúp bạn ...

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