2012-02-07 21 views
6

Bazı ayarları kullanıcıya sunan bir UITableView var. UISwitch 'On' konumunda değilse, bazı hücreler gizlenir. Aşağıdaki kod var:UISwitch ile UITableViewCell gösterme ve gizleme çok hızlı çöküyor

- (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]; 
} 

Bu işler beklendiği gibi, ben (çift dokunarak) arka arkaya iki kez UISwitch geçene kadar, bu durumda bir

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. 

ile uygulama çöker içinde Hücre animasyonu hala çalarken anahtarın orijinal konumuna geri döndüğünden numberOfRowsInSection değerinin yanlış dönüş değerinden kaynaklandığını biliyorum. Geçişi devre dışı bırakmayı ve diğer olay işleyicileri altındaki kodu çektiğimi denedim, ancak hiçbir şey kilitlenmeyi engelliyor gibi görünmüyor. Animasyon yerine reloadData kullanmak da problemi çözer, ancak güzel animasyonları tercih ederim.

Bunu gerçekleştirmenin doğru bir yolu bilen var mı?

+0

UIToggle nedir? UISwitch'i mi kastediyorsun? – Mundi

+0

Evet Yaptım, sorunu düzelttim. –

cevap

2

Güncelleştirmeler tamamlanana kadar anahtarınızın NOenabled özelliğini ayarlayın.

+2

Bunu denedim, ancak devre dışı bırakma etkinleşmeden önce geçişi değiştirmek mümkündür. –

+0

'UIControlEventTouchDown' etkinliği için yeni bir @ selektör 'ekleyin ve orada devre dışı bırakın. – Mundi

+0

Bu şekilde çalıştın mı? Lütfen onay işaretini işaretlemeyi düşünün. – Mundi

2

Bu sorunu benim üzerimde yaptım ve çökmeyi önlemenin yolu açık bir şekilde uiswitch'i kullanmak değil, bunun yerine bilgiyi bir boole, aktarımları nasıl yaptığımı anlatmaktır.

sizin numberOfRowsInSection

- (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]; 
} 
} 

Ve nihayet güncelleyin uygulama dosyası

bool _showRows = NO; 

güncelleme uiswitch kod üstüne

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

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

    }  
} 
return 0; 
} 
3

Başka (daha şık) solüsyonu bir boolean ekle Sorun şu:

ben bu şekilde Alan MacGregor - (IBAction)SwitchDidChange:(id)sender yöntemi modifiye:

- (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]; 
    } 
} 

diğer parçalar değişmeden kalır.

0

UIControlEventValueChanged olaylar, bir denetimin değeri gerçekten değişmediğinde bile oluşur. Bu nedenle geçiş değeri, anahtarın değeri değişmediğinde bile çağrılır. anahtarı hızlı bir şekilde değiştirdiğinizde, her zaman> kapalı> açık> kapalı, vb. devam etmeyebilirsiniz.> açık> açık> kapalı durumdan çıkmak mümkündür.

Yani ne oluyor, arka arkaya iki insertSections birbiri ardına neden iki satır alıyorsunuz. ki bu açıkça kötü.

bunu düzeltmek için, düğmenin önceki durumunun (ivar, belki de) ne olduğunu ve yeni değer (source.on) önceki değerden farklıysa yalnızca ekleme (veya silme) işlemini hatırlamanız gerekir. değer.

İlgili konular