iOS:使用代理模式监听开关状态改变事件
记一次解决跨控制器监听开关状态改变的尝试。
为了统一设置UITableViewCell里的内容,自定义了UITableViewCell类的一个基类,命名为SettingCell。SettingCell里显示的内容由数据模型SettingItem提供:在SettingCell里定义一个属性即可。
@property (nonatomic, strong) SettingItem *item;
再定义几个SettingItem的子类表示显示不同内容的Cell(如图1).由于所有开关状态的归档和解档都一样,故统一在父类SettingItem里实现。但是点击“手势密码”后跳转到下一个控制(如图2)后,需要单独监听手势密码开关的状态,这就涉及到了跨控制器监听开关状态改变事件的问题。我首先想到了代理模式。

图1 图2
首先在SettingCell.h里声明代理方法和属性:
#import <UIKit/UIKit.h> @class SettingItem, SettingCell; @protocol SettingCellDelegate <NSObject> @optional // 监听开关状态改变
- (void)settingCell:(SettingCell *)cell switchChanged:(UISwitch *)switchView; @end @interface SettingCell : UITableViewCell // 存放模型数据
@property (nonatomic, strong) SettingItem *item; @property (nonatomic, assign, getter = isLastRowInSection) BOOL lastRowInSection; + (instancetype)cellWithTableView:(UITableView *)tableView; // 定义代理属性
@property (nonatomic, weak) id<SettingCellDelegate> delegate; @end
然后,在SettingCell.m里初始化开关并注册ValueChanged事件,在switchStateChange:方法里调用代理方法传递开关状态:
- (UISwitch *)switchView
{
if (_switchView == nil) {
_switchView = [[UISwitch alloc] init];
[_switchView addTarget:self action:@selector(switchStateChange:) forControlEvents:UIControlEventValueChanged];
}
return _switchView;
} /**
* 监听开关状态改变
*/
- (void)switchStateChange:(UISwitch *)switchView
{
// NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// [defaults setBool:self.switchView.isOn forKey:self.item.title];
// [defaults synchronize];
if ([self.delegate respondsToSelector:@selector(settingCell:switchChanged:)]) {
[self.delegate settingCell:self switchChanged:switchView];
} [CoreArchive setBool:self.switchView.isOn key:self.item.title];
}
最后,在图2的控制器里实现代理方法:
- (void)settingCell:(SettingCell *)cell switchChanged:(UISwitch *)switchView
{
NSLog(@"手势密码开关状态改变了-------------------");
}
但是发现点击开关后并没有发现打印结果,窘迫~
检查代理模式的使用方法后发现是没有设置SettingCell的代理为当前控制器(GestureViewController)。问题又来了,在图2的控制器里我根本拿不到SettingCell,无奈只好追本溯源,发现这个控制器又是继承自自定义的一个控制器(BaseSettingViewController),故在父类控制器里的Cell初始化方法里设置代理为当前控制器即可(下面代码第11行)。于是开心地看到打印结果鸟!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.创建cell
SettingCell *cell = [SettingCell cellWithTableView:tableView]; // 2.给cell传递模型数据
SettingGroup *group = self.data[indexPath.section];
cell.item = group.items[indexPath.row];
cell.lastRowInSection = (group.items.count - == indexPath.row);
// 设置代理
cell.delegate = self;
// 3.返回cell
return cell;
}

总结思路:
- 涉及到跨控制器数据访问时首先考虑代理模式;
- 当类的继承关系复杂时一定要缕清关系:什么事在基类里统一做,什么事在子类里单独做。
iOS:使用代理模式监听开关状态改变事件的更多相关文章
- 原生js监听input值改变事件
哈哈哈,又来了,今天闲来无事,实验了下原生js监听input value值改变事件,下面就来说道说道: 本来写监听input值便获是用jquery的,之前的随笔写了,就是这个方法,地址:http:// ...
- ios电话拨打进行监听电话状态
#import "ViewController.h" #import <CoreTelephony/CTCallCenter.h> #import <CoreTe ...
- js实现监听浏览器窗口大小改变事件
window.onresize = function(){ }
- IOS-网络(监听网络状态)
// // BWNetWorkTool.h // IOS_0131_检测网络状态 // // Created by ma c on 16/1/31. // Copyright © 2016年 博文科技 ...
- IOS-利用AFNetworking监听网络状态
网络环境检测:检测用户当前所处的网络状态 效果图 1.当蜂窝和wifi同时关闭时候 显示为不可达(AFNetworkReachabilityStatusNotReachable)状态 2.打开蜂窝移 ...
- (原创)用Receiver和SystemService监听网络状态,注册Receiver的两种方式
android中网络编程不可避免地要监听网络状态,wifi或者3G以及以太网,并根据当前状态做出相应决策. 在MyReceiver类中的onReceive方法中获得系统服务 ConnectivityM ...
- Android实时监听网络状态(2)
在开发android应用时,涉及到要进行网络访问,时常需要进行网络状态的检查,以提供给用户必要的提醒.一般可以通过ConnectivityManager来完成该工作. ConnectivityMana ...
- Android实时监听网络状态
Android实时监听网络状态(1) 其实手机在网络方面的的监听也比较重要,有时候我们必须实时监控这个程序的实时网络状态,android在网络断开与连接的时候都会发出广播,我们通过接收系统的广播就 ...
- Android监听电池状态
监听电池状态只需要接收Intent.ACTION_BATTERY_CHANGED的广播即可,当电池状态发生变化时会发出广播. 1.运行状态如下图: (1)连接USB时的状态 (2)断开USB时的状态 ...
随机推荐
- jQuery瀑布流插件——jQuery.Waterfall
插件--jQuery.Waterfall 思路: 其实只要了解了整个流程,要实现这个插件也不难,大家都玩过俄罗斯方块吧,原理差不多,找到合适的地方叠上去就好了,在这里,每个块的宽度是必需给定的,然后计 ...
- MySQL获取汉字的首字母
)) ) CHARSET utf8 BEGIN ); )),,), 0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7, 0x ...
- PowerDesigner设计Name和Comment 替换
这两天在用powerdesigner设计数据库.一直以为name就是注释名字来着.后来生成sql语句 怎么就没有注释信息那. 后来看了半天才知道自己范2了. 通过各种信息查找.大多都是改databas ...
- python学习之迭代器与生成器
1.迭代器省内存 迭代器只允许往后读数据,不允许回读数据 迭代器不能跳着读文件,因为他是一点一点加载文件内容到内存的,读完了可以销毁或丢掉 2.生成一个迭代器 a = iter(["fd&q ...
- Netsuite SuiteScript > Search Advance feature,搜索中使用 'OR' operation
Sample in online help //Define search filter expression var filterExpression = [ [ 'trandate', 'onOr ...
- QQ模拟自动登录实现
QQ模拟自动登录实现 本篇文章主要介绍"QQ模拟自动登录实现(带验证码)",主要涉及到java 实现QQ自动登录(带验证码)方面的内容,对于java 实现QQ自动登录(带验证码)感 ...
- 关于bootstrap的一些运用
bootstrap用起来很方便,代码量少,写自适应网站最合适了! 关于bootstrap你必须要知道的几点: “行(row)”必须包含在 .container (固定宽度)或 .container-f ...
- html热力图的操作(点击图片的不同位置操作不同的事件)适合说明文档
页面核心代码 <div class="first_top"> <div class="back"> <img src=" ...
- &和&&
int j = 5,k = 3; if(!(j==k) && (j == 1 + k++ )) { } System.out.println(j); System.out.printl ...
- ajax局部刷新
//5秒刷新一次 $(function () { setInterval(Refresh, 5000); }); //ajax局部刷新 function Refresh() { $.ajax({ ty ...