[英]Change the state of UISwitch with animation programmatically
我有一個UITableView,其中包含一些包含UISwitches的單元格:
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]
不足以告訴perfom動畫嗎?
這是我設置和調用配置單元格的方法:
- (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
僅在[self actSwitchChanged: actSwitch];
之后,actSwitch才更改其狀態[self actSwitchChanged: actSwitch];
更改數據模型並調用[self.tableView reloadData];
可能是因為我有兩個帶有UISwitches的單元,並且它們之間存在一些沖突? 可能有比我的代碼更好的方法來從單元中獲取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
}
}
只需稍微延遲調用actSwitchChanged函數即可:
UISwitch* actSwitch = (UISwitch*)[[[self tableView] cellForRowAtIndexPath:indexPath ] viewWithTag: SWITCH_TAG];
BOOL value = [actSwitch isOn];
[actSwitch setOn:!value animated:YES]; // <-- HERE IS THE PROBLEM
[self performSelector:@selector(actSwitchChanged:) withObject:actSwitch afterDelay:0.55];
SWIFT 4
使用委托協議創建一個UITableViewCell子類。 我添加了標題標簽和開關,如下所示:
protocol CellWithSwitchDelegate: class {
func didToggleSwitch(on: Bool)
}
class CellWithSwitchTableViewCell: UITableViewCell {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var toggleSwitch: UISwitch!
weak var delegate: CellWithSwitchDelegate?
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
@IBAction func switchWasToggled(_ sender: UISwitch) {
delegate?.didToggleSwitch(on: sender.isOn)
}
}
在您的UITableViewController中,添加委托方法,如下所示:
class UITableViewController: CellWithSwitchDelegate {
func didToggleSwitch(on: Bool) {
// This is the delegate function that's called when the switch is toggled
print("toggled switch")
}
}
在您的UITableViewController中,將以下內容添加到didSelectRowAtIndexPath中:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! CellWithSwitchTableViewCell
let settingsSwitch = cell.toggleSwitch!
didToggleSwitch(on: !settingsSwitch.isOn)
settingsSwitch.setOn(!settingsSwitch.isOn, animated: true)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.