iOS开发:使用代理模式监听开关状态改变事件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发:使用代理模式监听开关状态改变事件相关的知识,希望对你有一定的参考价值。
记一次解决跨控制器监听开关状态改变的尝试。
为了统一设置UITableViewCell里的内容,自定义了UITableViewCell类的一个基类,命名为SettingCell。SettingCell里显示的内容由数据模型SettingItem提供:在SettingCell里定义一个属性即可。
@property (nonatomic, strong) SettingItem *item;
再定义几个SettingItem的子类表示显示不同内容的Cell(如图1).由于所有开关状态的归档和解档都一样,故统一在父类SettingItem里实现。但是点击“手势密码”后跳转到下一个控制(如图2)后,需要单独监听手势密码开关的状态,这就涉及到了跨控制器监听开关状态改变事件的问题。我首先想到了代理模式。
图1 图2
首先在SettingCell.h里声明代理方法和属性:
1 #import <UIKit/UIKit.h> 2 3 @class SettingItem, SettingCell; 4 5 @protocol SettingCellDelegate <NSObject> 6 7 @optional 8 9 // 监听开关状态改变 10 - (void)settingCell:(SettingCell *)cell switchChanged:(UISwitch *)switchView; 11 12 @end 13 14 @interface SettingCell : UITableViewCell 15 16 // 存放模型数据 17 @property (nonatomic, strong) SettingItem *item; 18 19 @property (nonatomic, assign, getter = isLastRowInSection) BOOL lastRowInSection; 20 21 + (instancetype)cellWithTableView:(UITableView *)tableView; 22 23 // 定义代理属性 24 @property (nonatomic, weak) id<SettingCellDelegate> delegate; 25 26 @end
然后,在SettingCell.m里初始化开关并注册ValueChanged事件,在switchStateChange:方法里调用代理方法传递开关状态:
1 - (UISwitch *)switchView 2 { 3 if (_switchView == nil) { 4 _switchView = [[UISwitch alloc] init]; 5 [_switchView addTarget:self action:@selector(switchStateChange:) forControlEvents:UIControlEventValueChanged]; 6 } 7 return _switchView; 8 } 9 10 /** 11 * 监听开关状态改变 12 */ 13 - (void)switchStateChange:(UISwitch *)switchView 14 { 15 // NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 16 // [defaults setBool:self.switchView.isOn forKey:self.item.title]; 17 // [defaults synchronize]; 18 if ([self.delegate respondsToSelector:@selector(settingCell:switchChanged:)]) { 19 [self.delegate settingCell:self switchChanged:switchView]; 20 } 21 22 [CoreArchive setBool:self.switchView.isOn key:self.item.title]; 23 }
最后,在图2的控制器里实现代理方法:
1 - (void)settingCell:(SettingCell *)cell switchChanged:(UISwitch *)switchView 2 { 3 NSLog(@"手势密码开关状态改变了-------------------"); 4 }
但是发现点击开关后并没有发现打印结果,窘迫~
检查代理模式的使用方法后发现是没有设置SettingCell的代理为当前控制器(GestureViewController)。问题又来了,在图2的控制器里我根本拿不到SettingCell,无奈只好追本溯源,发现这个控制器又是继承自自定义的一个控制器(BaseSettingViewController),故在父类控制器里的Cell初始化方法里设置代理为当前控制器即可(下面代码第11行)。于是开心地看到打印结果鸟!
1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 2 { 3 // 1.创建cell 4 SettingCell *cell = [SettingCell cellWithTableView:tableView]; 5 6 // 2.给cell传递模型数据 7 SettingGroup *group = self.data[indexPath.section]; 8 cell.item = group.items[indexPath.row]; 9 cell.lastRowInSection = (group.items.count - 1 == indexPath.row); 10 // 设置代理 11 cell.delegate = self; 12 // 3.返回cell 13 return cell; 14 }
总结思路:
- 涉及到跨控制器数据访问时首先考虑代理模式;
- 当类的继承关系复杂时一定要缕清关系:什么事在基类里统一做,什么事在子类里单独做。
以上是关于iOS开发:使用代理模式监听开关状态改变事件的主要内容,如果未能解决你的问题,请参考以下文章