1、自定义通知
第一步:定义一个方法
-(void)getCarName{ NSLog(@"getCarName"); }
第二步:注册通知
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(getCarName) name:@"event1" object:nil];
参数
addObserver:添加该通知的类 selector:接收到通知后执行的方法 name:通知的名字,作为通知的标识 object:传递的对象第三步:发送广播
我们通过创建一个按钮的点击事件来发送广播
- (IBAction)notifyEvent:(id)sender { [[NSNotificationCenter defaultCenter]postNotificationName:@"event1" object:nil userInfo:nil]; }
参数
postNotificationName:发送广播的名字 object:传递的对象 userInfo:传递的参数第四步:移除通知
注册了通知之后,必须记得移除通知,否则程序在退出时候回报错
-(void)dealloc{ [[NSNotificationCenter defaultCenter]removeObserver:self]; }
2、监听键盘通知
系统提供了监听各种控件的通知,这里演示键盘的通知
第一步:注册通知
这里注册键盘将要弹出时和将要隐藏时的通知
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(show:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(hide:) name:UIKeyboardWillHideNotification object:nil];
第二步:实现对应方法
这里会接受一个NSNotification,可以通过NSNotification获取通知传递过来的信息
-(void)show:(NSNotification *) notification{ NSDictionary *userInfo = notification.userInfo; NSLog(@"userInfo:%@",userInfo); } -(void)hide:(NSNotification *)notification{ }
当键盘弹出时,这里会打印出键盘的各种信息,可以获取键盘的Frame等信息
2017-03-14 01:02:24.857 DelegateDemo[1865:112324] userInfo:{ UIKeyboardAnimationCurveUserInfoKey = 7; UIKeyboardAnimationDurationUserInfoKey = "0.25"; UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {375, 258}}"; UIKeyboardCenterBeginUserInfoKey = "NSPoint: {187.5, 796}"; UIKeyboardCenterEndUserInfoKey = "NSPoint: {187.5, 538}"; UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 667}, {375, 258}}"; UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 409}, {375, 258}}"; UIKeyboardIsLocalUserInfoKey = 1; }
第三步:移除通知
别忘了移除通知哦
3、解决键盘遮盖文本框问题
通过通知传递过来的参数可以计算出键盘应该偏移的y值,让界面向上移动即可,效果图如下
通过对通知的处理,完成对应的动画即可,如果对y轴偏移量计算不懂的,可以在纸上画一下就懂了
-(void)show:(NSNotification *) notification{ NSDictionary *userInfo = notification.userInfo; NSLog(@"userInfo:%@",userInfo); //获取键盘的frame CGRect keyBoardFrame = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue]; //获取键盘的高度 CGFloat height = keyBoardFrame.size.height; //获取屏幕的高度 CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; //计算出View的y抽偏移量 CGFloat dy = screenHeight - height - self.textField.frame.origin.y - self.textField.frame.size.height; //如果被遮盖 if(dy<0){ //执行动画,将View的中心往上移动 [UIView animateWithDuration:1 animations:^{ self.view.center = CGPointMake(self.view.center.x, dy+screenHeight/2); }]; } } -(void)hide:(NSNotification *)notification{ //执行动画,恢复到屏幕原来的中心 [UIView animateWithDuration:1 animations:^{ self.view.center = CGPointMake(self.view.center.x, [UIScreen mainScreen].bounds.size.height/2); }]; } #pragma 代理方法 -(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event{ //点击非文本框让文本框取消焦点,即隐藏键盘 [self.textField resignFirstResponder]; }
1、自定义Delegate
第一步:在.h文件中,新建模型类,定义delegate的protocol文件
#import@interface CarModel : NSObject @property (nonatomic,strong)NSString *name; @property (nonatomic,strong)NSString *nickName; @end //自定义代理 @protocol CarModelDelegate //1、必须实现的回调方法 @required -(void)getCarModel:(CarModel *)model; //2、可选实现的回调方法 @optional -(void)getCarOtherModel:(CarModel *)model; @end
这里提供两个变量用于我们代理传递的参数,同时在代理中提供了两个方法,有必选方法和可选方法
第二步:在.m文件中,声明代理,触发代理方法
我们直接将参数的初始化和代理方法的执行放在init方法中
#import "CarModel.h" @interface CarModel() //声明代理 @property (nonatomic,weak)iddelegate; @end @implementation CarModel -(instancetype)init{ if(self = [super init]){ //初始化数据 self.name = @"奥迪"; self.nickName = @"A6"; //1、执行必选代理回调 if([self.delegate respondsToSelector:@selector(getCarModel:)]){ [self.delegate getCarModel:self]; } //2、执行可选代理回调 if([self.delegate respondsToSelector:@selector(getCarOtherModel:)]){ [self.delegate getCarOtherModel:self]; } } return self; } @end
第三步:在其他文件中,声明代理,实现代理方法,调用代理方法
#import "ViewController.h" #import "CarModel.h" @interface ViewController ()@end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; CarModel *model = [[CarModel alloc]init]; [self getCarModel:model]; } -(void)getCarModel:(CarModel *)model{ NSLog(@"CarName-->%@",model.name); } @end
这里在执行顺序中,先执行CarModel的init方法,也就是将模型的代理方法已经初始化,也就是说实现方法中已经获取模型传递过来的值了,所以执行代理方法getCarModel可以获取model.name值。