2012-02-07 4 views
6

ユーザーにいくつかの設定を提示するUITableViewがあります。 UISwitchが「オン」の位置になければ、一部のセルは非表示になります。私は、次のコードを持っている:UITableViewCellをUISwitchで表示したり隠したりするのが速すぎる

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

予想通り、私は(ダブルタップすることにより)急速に連続して2回UISwitchを切り替えるまでは、作品、

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. 

の場合のアプリケーションがクラッシュしました私はそれがnumberOfRowsInSectionの間違った戻り値によって引き起こされることを知っています。なぜなら、セルアニメーションがまだ再生されている間にスイッチが元の位置に戻るからです。私はトグルを無効にして、他のイベントハンドラの下でコードをフックしようとしましたが、何もクラッシュを防ぐことはできません。アニメーションの代わりにreloadDataを使うことで問題は解決しますが、素敵なアニメーションが好きです。

誰でもこれを実装する正しい方法を知っていますか?

+0

UIToggleとは何ですか?あなたは 'UISwitch'を意味しますか? – Mundi

+0

はい、私は質問を修正しました。 –

答えて

2

アップデートが完了するまで、スイッチのenabledプロパティをNOに設定するだけです。

+2

これを試しましたが、無効にする前に切り替えを切り替えることはできます。 –

+0

イベント 'UIControlEventTouchDown'に新しい '@ selector'を追加し、そこで無効にします。 – Mundi

+0

このように動作させましたか?チェックマークを付けてください。 – Mundi

2

私はこの問題を抱えていました。クラッシュを避ける方法は、明示的にuiswitchを使用せず、代わりに情報をブール値にリレーする方法です。

あなたuiswitchコード

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

を更新し、最終的にあなたのnumberOfRowsInSectionが

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

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

    }  
} 
return 0; 
} 
3

別の(よりエレガントな)ソリューションを更新し、あなたの実装ファイルの先頭

bool _showRows = NO; 

にブール値を追加します。この問題は次のとおりです。

私は、このようにアラン・マクレガー- (IBAction)SwitchDidChange:(id)sender方法を変更:

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

他の部分はそのままご利用いただけます。

0

UIControlEventValueChangedイベントは、コントロールの値が実際に変更されない場合でも発生します。 togglePushは、スイッチの値が変化しなくても呼び出されます。スイッチをすばやく切り替えると、on> off> on> offなどとは必ずしも進まない場合があります。> on> on> offになる可能性があります。

何が起こっているのは、2つのonSを連続して取得しているため、2つのinsertSectionsを1つずつ順番に並べているということです。それは明らかに悪いことです。

これを修正するには、ボタンの前の状態(ivarの多分)を覚えておいて、新しい値(source.on)が以前のものと異なる場合にのみ挿入または削除を実行する必要があります値。

関連する問題