2009-08-25 9 views
6

Tôi đã tìm thấy một số bài đăng tương tự như vấn đề của mình nhưng không hoàn toàn giống nhau.hàng trùng lặp trong chế độ xem bảng trên uitableviewcell

Trong ứng dụng của tôi, người dùng có thể điều hướng giữa một số uitableviews để xem chi tiết kết quả mong muốn. Khi người dùng đi tiếp, sau đó lùi lại, sau đó chuyển tiếp, v.v. có thể nhận thấy rằng các hàng đang được vẽ lại/viết lại và văn bản trở nên táo bạo và táo bạo hơn.

Tôi nhận thấy rằng trong một số bài đăng, điều này có thể liên quan đến cách tôi tạo hàng, sử dụng uilable trong phương thức cellforrowatindexpath.

Có điều gì mà tôi cần phải làm sao cho các hàng không lặp lại/vẽ lại mỗi khi người dùng đi tiếp và lùi giữa các lần xem bảng? Tôi có cần phải thêm một cái gì đó vào mã dưới đây hoặc thêm một cái gì đó vào phương pháp viewwillappear (hiện tại có một 'reloaddata' trong viewwillappear cho bảng nhưng dường như không giúp đỡ)?

Đây là mã của tôi:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) 
{ 
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
} 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 

    UILabel *label = [[[UILabel alloc] init] autorelease]; 
    label.font = [UIFont fontWithName:@"Arial-BoldMT" size:20]; 
    label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f); 
    label.textColor = [UIColor blackColor]; 
    label.backgroundColor = [UIColor clearColor]; 
    label.opaque = NO; 
    label.text = [mapareaArray objectAtIndex:indexPath.row]; 
    [cell.contentView addSubview:label]; 

    CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero]; 
    bgView.borderColor = [UIColor clearColor]; 
    bgView.fillColor = [UIColor whiteColor]; 
    bgView.position = CustomCellBackgroundViewPositionSingle; 
    cell.backgroundView = bgView; 
    return cell; 
} 

Trả lời

11

Vấn đề bạn gặp phải là do dòng này:

[cell.contentView addSubview:label]; 

Bạn đang thêm một subview vào ô trong bảng cho dù đó là một tế bào mới hay không . Nếu nó là một tế bào cũ (dequeued từ các hồ bơi tái sử dụng), sau đó bạn sẽ thêm một subview khác cho các tế bào.

Thay vào đó, bạn nên gắn nhãn UILabel và sau đó định vị thẻ đó bằng thẻ để sửa đổi nội dung của UILabel đó. Thêm (và thiết lập tất cả các thuộc tính của nó) và tag các UILabel bên trong if (tế bào == nil) khối:

if(cell == nil) { 
    // alloc and init the cell view... 

    UILabel *label = [[[UILabel alloc] init] autorelease]; 
    label.tag = kMyTag; // define kMyTag in your header file using #define 
    // and other label customizations 
    [cell.contentView addSubview:label]; // addSubview here and only here 
    ... 
} 

Sau đó, xác định vị trí nó với:

UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag]; 
label.text = [mapareaArray objectAtIndex:indexPath.row]; 

Và không cần phải thêm lại nó như là một subview bên ngoài của if (cell == nil) khối. Các subview đã có (và đó là lý do tại sao tái sử dụng các khung nhìn tế bào là rất nhiều hiệu quả hơn, nếu bạn làm điều đó một cách chính xác, đó là;).

+0

Cảm ơn bạn rất nhiều vì điều này. Trợ giúp lớn. Một câu hỏi cuối cùng về điều này - Tôi không có nền tảng lập trình để không chắc chắn ý bạn là gì bằng cách sử dụng #define trong tệp tiêu đề. Cú pháp để làm điều này là gì? Tôi đã nhìn thấy nó trước và đã cố gắng để đặt '#define kMyTag' trong tiêu đề nhưng điều này không hoạt động ...Tôi giả định rằng bạn cần phải định nghĩa kMyTag với một giá trị nhưng không chắc chắn cú pháp sẽ làm gì. Bạn có thể giúp? – SKayser

1

.h tập tin Các 'định nghĩa' được đặt sau khi các báo cáo #import ở phía trên của tập tin header, và được đặt là 0 bởi vì tôi không biết làm thế nào khác để xác định nó:

#define kMyTag 0 

. m file Tôi đã cập nhật phần này theo ý kiến ​​của bạn, nhưng a) bảng không được điền, b) khi người dùng đã điều hướng đến chế độ xem tiếp theo và quay trở lại chế độ xem này không thành công với "bộ chọn không được nhận dạng được gửi tới ví dụ" , và c) Tôi đã phải đặt vào hai ô 'trả lại'; mục hoặc nó rơi xuống. Tôi nghĩ rằng tôi có những thứ sai trật tự và có thể đã không khởi tạo đúng thứ ????

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

if (cell == nil) 
    { 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 

     UILabel *label = [[[UILabel alloc] init] autorelease]; 
     label.tag = kMyTag; // define kMyTag in your header file using #define 
     label.font = [UIFont fontWithName:@"Arial-BoldMT" size:20]; 
     label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f); 
     label.textColor = [UIColor blackColor]; 
     label.backgroundColor = [UIColor clearColor]; 
     label.opaque = NO; 

     CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero]; 
     bgView.borderColor = [UIColor clearColor]; 
     bgView.fillColor = [UIColor whiteColor]; 
     bgView.position = CustomCellBackgroundViewPositionSingle; 
     cell.backgroundView = bgView; 

     [cell.contentView addSubview:label]; // addSubview here and only here 
     return cell; 
    } 
UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag]; 
label.text = [mapareaArray objectAtIndex:indexPath.row]; 
return cell; 
} 
+0

Tôi không chắc chắn nếu bạn nên sử dụng 0 cho giá trị của kMyTag. Hãy thử bắt đầu từ 1, vì 0 có thể là mặc định cho mọi thứ. Sau thay đổi đó, hãy xóa ô trả lại bên trong khối if. – tchen

+0

Cảm ơn một lần nữa! Điều đó hoạt động ngay bây giờ! Đánh giá cao thời gian của bạn! – SKayser

0

Bạn nên tạo phân lớp cho UITableViewCell cho ô cụ thể đó, sau đó áp dụng lôgic để xem liệu bạn có cần thêm chế độ xem phụ vào chính nó mọi lúc không. Ngoài ra, hãy sử dụng PrepareForReuse của UITableviewcell và loại bỏ bất kỳ bản xem trước nào trong thời gian đó trước khi áp dụng logic của thời điểm bạn muốn thêm một UILabel vào ô của bạn.