2010-11-21 25 views
7

Tôi có UITableView sử dụng tùy chỉnh UITableViewCell s. Các ô có thể có một trong ba loại hình nền (được đặt trong thuộc tính .backgroundView.image của mỗi ô): trên cùng, giữa hoặc dưới. Các hình ảnh trên cùng và dưới cùng dành cho các ô đầu tiên và cuối cùng, và có các góc tròn (giống như các ô của UITableView được nhóm). Tất cả các ô "trung bình" khác trong hình UITableView đều có hình nền ở giữa hình chữ nhật.Tải lại tùy chỉnh UITableViewCell sau khi sắp xếp lại các ô

Vấn đề của tôi là khi sắp xếp lại các ô trong chế độ Chỉnh sửa, các ô không làm mới với hình nền khác tùy thuộc vào vị trí mới của chúng. Ví dụ: nếu tôi di chuyển ô đầu tiên vào giữa bảng, nó vẫn giữ nguyên hình nền "trên cùng" ban đầu (với các góc tròn) và ô mới xuất hiện ở đầu chế độ xem bảng vẫn có "trung bình" ban đầu của nó hình nền, tất cả trông hơi lạ.

Tôi có thể giải quyết vấn đề này bằng cách thực hiện reloadData trên chế độ xem bảng nhưng điều này có vấn đề không mang lại hiệu ứng động đẹp mắt cho những thay đổi. Tôi nhận thấy rằng khi sắp xếp lại một nhóm tiêu chuẩn UITableView ngay sau khi một ô được di chuyển/kéo hình nền trên các ô có liên quan thay đổi (ngay cả trước khi ô di chuyển đã được thả vào vị trí mới của nó) trông rất đẹp. Tôi muốn đạt được điều tương tự.

Để kết thúc này, tôi đã triển khai tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath được gọi là mỗi lần một hàng được kéo xung quanh trong chế độ xem bảng. Trong bài này tôi đã thử các phương pháp khác nhau để thiết lập backgroundView.image bao gồm chỉ trực tiếp thiết lập hình ảnh và sau đó cũng yêu cầu nó vẽ lại ô và/hoặc hình ảnh bằng cách sử dụng setNeedsLayoutsetNeedsDisplay nhưng không có gì làm cho việc vẽ lại ô. Tôi có NSLog 'ged kết quả của những thay đổi này và họ dường như cam kết với các tế bào, như các giá trị chính xác xuất hiện trong NSLog, nhưng các tế bào dường như không được cập nhật trên màn hình.

Nếu bất cứ ai có thể chỉ ra những gì tôi đang làm sai, hoặc đề xuất một cách tốt hơn để đạt được một kết quả làm việc, tôi sẽ rất cảm kích. Cảm ơn!

EDIT: đoạn mã sau được kéo từ tiền thưởng và được định dạng để nó có thể được dễ dàng hơn tiêu hóa:

UIImage *rowBackground; 
UIImage *selectionBackground; 
NSInteger sectionRows = [_tableView numberOfRowsInSection:[indexPath section]]; 
NSInteger row = [indexPath row]; 
if (row == 0 && row == sectionRows - 1) 
{ 
    rowBackground = [UIImage imageNamed:@"field_title_bkg.png"]; 
    selectionBackground = [UIImage imageNamed:@"field_title_bkg.png"]; 
} 
else if (row == 0) 
{ 
    rowBackground = [UIImage imageNamed:@"table_row_top_bkg.png"]; 
    selectionBackground = [UIImage imageNamed:@"table_row_top_bkg.png"]; 
} 
else if (row == sectionRows - 1) 
{ 
    rowBackground = [UIImage imageNamed:@"table_bottom_row_bkg.png"]; 
    selectionBackground = [UIImage imageNamed:@"table_bottom_row_bkg.png"]; 
} 
else 
{ 
    rowBackground = [UIImage imageNamed:@"table_row_bkg.png"]; 
    selectionBackground = [UIImage imageNamed:@"table_row_bkg.png"]; 
} 
UIImageView *rowBackGroundImageView = [[UIImageView alloc] initWithImage:rowBackground]; 
UIImageView *rowBackGroundSelectionImageView = [[UIImageView alloc] initWithImage:selectionBackground]; 
if (row != sectionRows - 1) 
{ 
    UIImageView *sep = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cell_separator.png"]]; 
    [sep setFrame:CGRectMake(20, 56, 280, 1)]; 
    [rowBackGroundImageView addSubview:sep]; 
} 
[cell setBackgroundView:rowBackGroundImageView]; 
[rowBackGroundImageView release]; 
+0

Bạn có thể thử che mặt bảng với chế độ xem khác ở trên đầu trang. Sau đó, bạn sẽ không cần backgorund hình ảnh cho các tế bào ở tất cả. – Eimantas

+0

Bạn có thể giải thích ý tưởng này thêm một chút không? Tôi không hoàn toàn làm theo cách đó sẽ làm việc. – Skoota

+0

Câu hỏi liên quan: http://stackoverflow.com/questions/7338161/update-old-new-top-bottom-cells-backgroundview-when-inserting-deleting-top-bott – an0

Trả lời

0

tôi đã không cố gắng bản thân mình nhưng tại sao không kiểm tra giá trị indexPath.row của bạn vào phương pháp cellForRowAtIndexPath và cung cấp các giá trị backgroundView.image khác nhau cho hàng đầu tiên và cuối cùng?

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

Tôi hy vọng điều này sẽ hữu ích. Chúc mừng, Rog

+0

Hi Rog. Đó là những gì tôi hiện đang làm, nhưng 'cellForRowAtIndexPath' không được gọi khi hàng được di chuyển khi hàng đã có trên màn hình. Tôi đã cố gắng tự gọi 'cellForRowAtIndexPath' trong phương thức' tableView: targetIndexPathForMoveFromRowAtIndexPath: toProposedIndexPath' nhưng không có gì xảy ra (tức là ô không tải lại/vẽ lại trên màn hình). – Skoota

1

Nếu bạn chỉ muốn tải lại một vài tế bào chứ không phải toàn bộ bảng, bạn có thể sử dụng:

reloadRowsAtIndexPaths:withRowAnimation: 

sẵn như là một phương pháp thể hiện của UITableView.

+0

Xin chào Robert. Thử rằng, nhưng nó sẽ không hoạt động trong 'tableView: targetIndexPathForMoveFromRowAtIndexPath: toProposedIndexPath' phương thức (tức là trong khi hàng đang được kéo/di chuyển xung quanh) và treo với thông báo rằng số hàng và phần sau khi hoạt hình phải khớp với số trước hoạt ảnh. Không ngạc nhiên khi các hàng vẫn đang được di chuyển xung quanh khi chúng ta thử và gọi phương thức này. – Skoota

+0

Bạn đã cố gắng thực hiện tải lại trong phương thức UITableViewDataSource 'tableView: moveRowAtIndexPath: toIndexPath:' thay thế? Tôi nghĩ rằng một trong những được gọi là sau khi di chuyển được hoàn thành. –

+0

Xin chào Robert. Xin lỗi về việc trả lời trễ. Tôi đã thử điều này là tốt, nhưng nó gây ra một số hành vi kỳ lạ. Nếu tôi chỉ tải lại 'toIndexPath', nó sẽ làm cho hàng tại' fromIndexPath' biến mất hoàn toàn. Nếu tôi tải lại cả hai đường dẫn chỉ mục, nó sẽ thực sự đi hoặc dây và bắt đầu đặt nhiều bản sao của các tế bào trên đầu trang của mỗi khác! – Skoota

0

(this solution only works for the reordering of rows within the same section. It'll fail when dragging and dropping rows to a different section)

tôi đã cùng một vấn đề khi cập nhật văn bản nhãn chi tiết của tế bào sau khi được sắp xếp lại.

Tôi giải quyết nó với đoạn mã sau:

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 
{ 
UITableViewCell* cell = [self.table cellForRowAtIndexPath:fromIndexPath]; 
cell.detailTextLabel.text = @"NEW STRING"; 
} 

Lưu ý rằng bạn phải cập nhật các tế bào ở fromIndexPath, bởi vì nó có vẻ như tình trạng nội bộ của tableview không cập nhật cho đến khi phương pháp này lợi nhuận . Nếu bạn nhận được ô tại toIndexPath, sau khi sắp xếp lại kết thúc, bạn sẽ thấy ô lân cận được cập nhật. (đầu hoặc cuối).

1

Hãy thử điều này:

[tableView beginUpdates]; 
[tableView endUpdates]; 
0

các apis cho tải lại một phần hàng trong sdk ios không hoạt động tốt (đó là lý do tại sao ppl làm theo bài này ở đây)

tôi sẽ chỉ sử dụng bộ đếm thời gian để tải lại toàn bộ dữ liệu sau khi sắp xếp lại kết thúc hoạt ảnh. Nó phù hợp với tôi.

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 
{ 
    //things to be done when reordering rows 
    .... 


    //issue a timer to reload data 
    NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval: 0.1 
              target: self 
              selector:@selector(updateRow) 
              userInfo: nil repeats:NO]; 


} 


-(void) updateRow 
{ 

    [self.table reloadData]; 

} 
+0

không chắc chắn bạn cần sử dụng bộ hẹn giờ - bạn chỉ có thể sử dụng '-performSelectorOnMainThread:' – nielsbot

4

Viết mã bên dưới vào dự án của bạn và nó sẽ hoạt động như mong đợi.

- (NSIndexPath *)tableView:(UITableView *)tableView 
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath 
     toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath 
{ 
    NSInteger sectionRows = [tableView numberOfRowsInSection:[sourceIndexPath section]]; 

    UITableViewCell *sourceCell = [tableView cellForRowAtIndexPath:sourceIndexPath]; 
    UITableViewCell *destCell = [tableView cellForRowAtIndexPath:proposedDestinationIndexPath]; 

    if(sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == 1) 
    { 
     ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_row_top_bkg.png"]; 

     if(proposedDestinationIndexPath.row == sectionRows - 1) 
      ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_bottom_row_bkg.png"]; 
     else 
      ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_row_bkg.png"]; 
    } 

    else if(sourceIndexPath.row == sectionRows - 1 && proposedDestinationIndexPath.row == sectionRows - 2) 
    { 
     ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_bottom_row_bkg.png"]; 

     if(proposedDestinationIndexPath.row == 0) 
      ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_row_top_bkg.png"]; 
     else 
      ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_row_bkg.png"]; 
    } 

    else if(proposedDestinationIndexPath.row == 0) 
    { 
     ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_row_top_bkg.png"]; 

     destCell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:proposedDestinationIndexPath.section]]; 
     if(sectionRows == 2) 
      ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_bottom_row_bkg.png"]; 
     else 
      ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_row_bkg.png"]; 
    } 

    else if(proposedDestinationIndexPath.row == sectionRows - 1) 
    { 
     ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_bottom_row_bkg.png"]; 

     destCell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:sectionRows - 1 inSection:proposedDestinationIndexPath.section]]; 
     if(sectionRows == 2) 
      ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_row_top_bkg.png"]; 
     else 
      ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_row_bkg.png"]; 
    } 

    return proposedDestinationIndexPath; 
} 
+0

Điều này hoạt động hoàn hảo! Xem phụ kiện của tôi dường như đã biến mất nhưng tôi đã nghĩ đến việc làm một tùy chỉnh anyways. –

+0

Vì vậy, nếu bạn kéo một hàng vào một hàng khác, sau đó quyết định bạn không muốn hàng đó trước khi cho phép kéo, hình ảnh sẽ thay đổi thành hình ảnh ô sai: / –

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