2012-02-07 38 views
6

Tôi có một UITableView trình bày một số cài đặt cho người dùng. Một số ô bị ẩn trừ khi UISwitch ở vị trí 'Bật'. Tôi đã có đoạn mã sau:Hiển thị và ẩn UITableViewCell với UISwitch treo nhanh quá

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return switchPush.on ? 6 : 1; 
} 

// Hooked to the 'Value Changed' action of the switchPush 
- (IBAction)togglePush:(id)sender { 
    NSMutableArray *indexPaths = [NSMutableArray arrayWithCapacity:0]; 
    for(int i = 1; i <= 5; i++) { 
     [indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]]; 
    } 

    [tableView beginUpdates]; 
    if(switchPush.on) { 
     [tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; 
    } else { 
     [tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; 
    } 
    [tableView endUpdates]; 
} 

này hoạt động như mong đợi, cho đến khi tôi chuyển UISwitch hai lần liên tiếp nhanh (bằng cách gõ kép), trong trường hợp tai nạn ứng dụng với một

Invalid table view update. The application has requested an update to the table view that is inconsistent with the state provided by the data source. 

mà Tôi biết rằng nó được gây ra bởi giá trị trả về sai của numberOfRowsInSection khi chuyển đổi trở lại vị trí ban đầu của nó trong khi hoạt ảnh của ô vẫn đang phát. Tôi đã thử vô hiệu hóa các chuyển đổi và hooking mã dưới xử lý sự kiện khác nhưng không có gì có vẻ để ngăn chặn sự cố. Sử dụng reloadData thay vì hoạt ảnh cũng giải quyết được vấn đề nhưng tôi thích hình động đẹp hơn.

Có ai biết cách thực hiện chính xác điều này không?

+0

UIToggle là gì? Bạn có nghĩa là một 'UISwitch'? – Mundi

+0

Có, tôi đã sửa lại câu hỏi. –

Trả lời

2

Chỉ cần đặt thuộc tính enabled của chuyển đổi thành NO cho đến khi hoàn tất cập nhật.

+2

Tôi đã thử điều này nhưng vẫn có thể chuyển đổi lại sau khi vô hiệu hóa có hiệu lực. –

+0

Thêm một bộ chọn '@ mới' cho sự kiện' UIControlEventTouchDown' và tắt nó ở đó. – Mundi

+0

Bạn đã làm cho nó hoạt động theo cách này? Vui lòng xem xét đánh dấu vào dấu kiểm. – Mundi

2

Tôi đã gặp vấn đề này đối với tôi và cách tránh tai nạn là không sử dụng rõ ràng uiswitch, thay vì chuyển tiếp thông tin vào một boolean, heres cách tôi đã làm nó.

Thêm một boolean để phía trên cùng của tập tin thực thi của bạn

bool _showRows = NO; 

cập nhật mã uiswitch bạn

- (IBAction)SwitchDidChange:(id)sender { 

NSArray *aryTemp = [[NSArray alloc] initWithObjects:[NSIndexPath indexPathForRow:1 inSection:0], 
        [NSIndexPath indexPathForRow:2 inSection:0], 
        [NSIndexPath indexPathForRow:3 inSection:0], 
        [NSIndexPath indexPathForRow:4 inSection:0],nil]; 

if (_showRows) { 
    _showRows = NO; 
    _switch.on = NO; 
    [_tblView deleteRowsAtIndexPaths:aryTemp withRowAnimation:UITableViewRowAnimationTop]; 
} 
else { 
    _showRows = YES; 
    _switch.on = YES; 
    [_tblView insertRowsAtIndexPaths:aryTemp withRowAnimation:UITableViewRowAnimationBottom]; 
} 
} 

Và cuối cùng cập nhật numberOfRowsInSection bạn

- (NSInteger)tableView:(UITableView *)tableView 
numberOfRowsInSection:(NSInteger)section 
{ 
if (section == 0) { 

    if (_showRows) { 
     return 5; 
    } 
    else { 
     return 1; 

    }  
} 
return 0; 
} 
3

khác (tao nhã hơn) giải pháp vấn đề là:

Tôi đổi Alan MacGregor - (IBAction)SwitchDidChange:(id)sender phương pháp theo cách này:

- (IBAction)SwitchDidChange:(UISwitch *)source { 
    if (_showRows != source.on) { 
     NSArray *aryTemp = [[NSArray alloc] initWithObjects: 
        [NSIndexPath indexPathForRow:1 inSection:0], 
        [NSIndexPath indexPathForRow:2 inSection:0], 
        [NSIndexPath indexPathForRow:3 inSection:0], 
        [NSIndexPath indexPathForRow:4 inSection:0],nil]; 
     [_tblView beginUpdates]; 
     _showRows = source.on; 
     if (_showRows) { 
      [_tblView insertSections:aryTemp withRowAnimation:UITableViewRowAnimationFade]; 
     } 
     else { 
      [_tblView deleteSections:aryTemp withRowAnimation:UITableViewRowAnimationFade]; 
     } 
     [_tblView endUpdates]; 
    } 
} 

Các bộ phận khác lại không thay đổi.

0

UIControlEventValueThay đổi sự kiện xảy ra ngay cả khi giá trị của kiểm soát không thực sự thay đổi. nên togglePush được gọi ngay cả khi giá trị của công tắc không thay đổi. khi bạn nhanh chóng chuyển đổi công tắc, bạn có thể không phải lúc nào cũng đi từ bật> tắt> bật> tắt, v.v. có thể tắt> bật> bật> tắt.

vì vậy điều đang xảy ra là bạn đang nhận được hai tiện ích liên tiếp khiến hai phần chèn sau cái kia. mà rõ ràng là xấu.

để khắc phục điều này, bạn cần nhớ trạng thái trước của nút (bằng ivar, có thể) và chỉ thực hiện chèn (hoặc xóa) nếu giá trị mới (source.on) khác với giá trị trước đó giá trị.

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