UISwitches を含むいくつかのセルを含む UITableView があります。
UISwitch* actSwitch = (UISwitch*)[cell viewWithTag: SWITCH_TAG];
[actSwitch addTarget: self
action: @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];
BOOL value = [appSettings.lock_when_inactive boolValue];
[actSwitch setOn: value animated:NO];
didSelectRowAtIndexPath:また、それぞれの UISwitch の切り替えを実行するメソッドを上書きしたいと思います。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellType = [self typeOfCellForIndexPath:indexPath];
if ( cellType == @"CellWithSwitch" )
{
UISwitch* actSwitch = (UISwitch*)[[[self tableView] cellForRowAtIndexPath:indexPath ] viewWithTag: SWITCH_TAG];
BOOL value = [actSwitch isOn];
[actSwitch setOn:!value animated:YES]; // <-- HERE IS THE PROBLEM
[self actSwitchChanged: actSwitch];
}
else if ( cellType == @"CellWithoutSwitch" )
{
// other actions
}
}
どちらの状況でも、UISwitch を直接クリックするか、セルをクリックして、状態を変更し、actSwitchChanged:正しく呼び出します。
ただし、セルをクリックすると、UISwitch はある状態から別の状態への切り替えをアニメーション化せず、状態を一瞬で変更するだけです。
アニメーション[actSwitch setOn:!value animated:YES]を実行するように指示するだけで十分ではないでしょうか。
構成セルを設定して呼び出す方法は次のとおりです。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
NSString *EnabledCellIdentifier = [self typeOfCellForIndexPath:indexPath];
cell = [tableView dequeueReusableCellWithIdentifier:EnabledCellIdentifier];
if (cell == nil)
{
cell = [self cellForType:EnabledCellIdentifier];
}
[self cofigureCell:cell forIndexPath:indexPath];
return cell;
}
これは私がセルを設定する方法です:
- (void)cofigureCell:(UITableViewCell*)cell forIndexPath:(NSIndexPath*)indexPath {
switch ( indexPath.section )
{
case 0:
// not this
case 1:
{
switch ( indexPath.row )
{
case 0:
{
cell.textLabel.text = @"Limit passwords attempts";
UISwitch* actSwitch = (UISwitch*)[cell viewWithTag: SWITCH_TAG];
[actSwitch addTarget: self
action: @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];
BOOL value = [appSettings.limit_password_attempts boolValue];
[actSwitch setOn: value animated:NO];
break;
}
//other rows of this section here are being configured
}
break;
}
case 2:
{
switch ( indexPath.row )
{
case 0:
{
cell.textLabel.text = @"Lock when inactive";
UISwitch* actSwitch = (UISwitch*)[cell viewWithTag: SWITCH_TAG];
[actSwitch addTarget: self
action: @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];
BOOL value = [appSettings.lock_when_inactive boolValue];
[actSwitch setOn: value animated:NO];
break;
}
//other rows of this section here are being configured
}
break;
}
default:
break;
}
}
しかし、段階的にデバッグし、この手順を実行すると、次のようになります。
[actSwitch setOn:!value animated:YES]; // <-- HERE IS THE PROBLEM
actSwitch は、[self actSwitchChanged: actSwitch];変更されたデータ モデルと呼び出しの後にのみ状態を変更します。[self.tableView reloadData];
その理由は、UISwitches を持つ 2 つのセルがあり、それらの間で競合が発生している可能性がありますか? 私のこのコードよりもセルから UISwitch を取得するためのより良い方法があるかもしれません?:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellType = [self typeOfCellForIndexPath:indexPath];
if ( cellType == @"CellWithSwitch" )
{
UISwitch* actSwitch = (UISwitch*)[[[self tableView] cellForRowAtIndexPath:indexPath ] viewWithTag: SWITCH_TAG];
BOOL value = [actSwitch isOn];
[actSwitch setOn:!value animated:YES]; // <-- HERE IS THE PROBLEM
[self actSwitchChanged: actSwitch];
}
else if ( cellType == @"CellWithoutSwitch" )
{
// other actions
}
}