观察者模式:一种常用的设计模式,一个对象 A想了解另外一个对象B的状态是否发生了改变,在对象B上注册一个观察者,当对象B的状态发生改变时观察者通知对象A
实现下面的方法
image.png
通知的作用
- 一个对象不用知道消息的接受者是谁,就可以将一些消息发送给需要的接受者;
- 有时发送消息的对象无法知道有哪些对象,有多少对象接收消息,也不知道这些对象是否存在;
-
有时消息的接受者离发送者太远
image.png
自定义通知
新建两个类CCTV1、ZhangsanTV继承NSObject
CCTV1.h声明属性-(void)sendNotification:(NSString*)notiContent;
CCTV1.m
@implementation CCTV1
-(void)sendNotification:(NSString*)notiContent{
//获取通知中心对象(NSNotificationCenter这是一个单例类)
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotificationName:@"电视节目" object:self userInfo:@{@"name":@"cctv1",@"sendContent":notiContent}];
//获取发送方的对象
//dic["object"]
}
ZhangsanTV.m
#import "ZhangsanTV.h"
@implementation ZhangsanTV
-(instancetype)init{
if(self = [super init]){
//向通知中心注册 要接受名字为电视节目的通知
[[NSNotificationCenter defaultCenter ]addObserver:self selector:@selector(play:) name:@"电视节目" object:nil];
}
return self;
}
//NSNotification是接受的通知对象
-(void)play:(NSNotification*)notification{
NSLog(@"%@",notification);
NSDictionary *dic = notification.userInfo;
NSLog(@"%@发送了%@",dic[@"name"],dic[@"sendContent"]);
}
@end
ViewController.m
#import "ViewController.h"
#import "CCTV1.h"
#import "ZhangsanTV.h"
@interface ViewController ()
@property(nonatomic,strong)CCTV1 *cctv1;
@property(nonatomic,strong)ZhangsanTV *zs;
@end
@implementation ViewController
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self.cctv1 sendNotification:@"新闻联播"];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.cctv1 = [[CCTV1 alloc]init];
self.zs = [[ZhangsanTV alloc]init];
}
-
在模拟器里面,textfield可以通过电脑键盘输入,可是怎么也不会自动弹出模拟器软键盘 解决办法:点开iOS模拟器,Hardware -> Keyboard -> Toggle Software keyboard.
image.png
image.png
第二步将此处1修改成0.5就改好了
image.png
image.png
注意:Label 的行数要改成0;不然不会根据你说话的多少改变tableView的行高
image.png
image.png
发送消息
ViewController.m
#import "ViewController.h"
#import "Message.h"
#import "MessageCell.h"
#import "otherCell.h"
@interface ViewController ()<UITableViewDelegate,UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *viewBottom;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property(nonatomic,strong)NSMutableArray *allMessage;
@end
@implementation ViewController
-(NSMutableArray *)allMessage{
if(!_allMessage){
//mutableCopy将不可变数组转换成可变数组
_allMessage = [[Message allMessage] mutableCopy];
}
return _allMessage;
}
//textField的代理方法
- (BOOL)textFieldShouldReturn:(UITextField *)textField;{
Message *message = [[Message alloc]init];
message.me = YES;
message.message = textField.text;
//将新的消息对象 添加到数组中
[self.allMessage addObject:message];
Message *message2 = [[Message alloc]init];
message2.me = NO;
message2.message = @"太喜欢你了,你以后一定会找到工资上万的工作!你是最漂亮的!";
//将新的消息对象 添加到数组中
[self.allMessage addObject:message2];
//刷新tableView
[self.tableView reloadData];
[self scrillToTableViewLastRow];
textField.text = @"";
return YES;
}
-(void)scrillToTableViewLastRow{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.allMessage.count - 1 inSection:0];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
//问二:每个分区有多少行
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.allMessage.count;
}
//问三:每行长什么样子
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Message *message = self.allMessage[indexPath.row];
if(message.isMe){
MessageCell *cell = [tableView dequeueReusableCellWithIdentifier:@"messageCell" forIndexPath:indexPath];
cell.messageLabel.text = message.message;
return cell;
}
otherCell *othercell = [tableView dequeueReusableCellWithIdentifier:@"otherCell" forIndexPath:indexPath];
othercell.label.text = message.message;
return othercell;
}
- (void)viewDidLoad {
[super viewDidLoad];
//键盘 通知的 通知名称
//UIKeyboardDidShowNotification
//UIKeyboardWillShowNotification
//UIKeyboardWillHideNotification
//UIKeyboardDidHideNotification]
//设置数据源和代理 也可以在 xib或storyboard中进行设置
//self.tableView.delegate = self;
//self.tableView.delegate = self;
//设置tableView动态行高
//预设高度为60
self.tableView.estimatedRowHeight = 60;
//设置行高 根据内容 自动计算
self.tableView.rowHeight = UITableViewAutomaticDimension;
//调用后可以看到最近消息
[self scrillToTableViewLastRow];
//给tableView 添加 点击手势
}
-(void)tap{
UITapGestureRecognizer *tap= [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
//设置核心 属性
//需要几个手指点
//tap.numberOfTouchesRequired = 2;
tap.numberOfTapsRequired = 1;
//将手势添加到视图上
[self.tableView addGestureRecognizer:tap];
}
//模拟两只手按住alt
-(void)tap:(UITapGestureRecognizer*)gesture{
[self.view endEditing:YES];
}
//关联轻扫手势 触发的 事件方法
- (IBAction)swipe:(id)sender {
[self.view endEditing:YES];
}
-(void)viewWillAppear:(BOOL)animated{
//将要显示需要接受
[super viewWillAppear:animated];
//注册接受 键盘 弹起通知
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardOpen:) name:UIKeyboardWillShowNotification object:nil];
//注册接受 键盘 将要关闭通知
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardClose:) name:UIKeyboardWillHideNotification object:nil];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
//当前对象下全部移除
[[NSNotificationCenter defaultCenter]removeObserver:self];
//当前对象下部分移除
// [[NSNotificationCenter defaultCenter]removeObserver:self name:UIKeyboardWillShowNotification object:nil];
// [[NSNotificationCenter defaultCenter]removeObserver:self name:UIKeyboardWillHideNotification object:nil];
//
}
-(void)keyboardOpen:(NSNotification*)noti{
NSLog(@"键盘将要弹起 %@",noti);
//获取键盘尺寸
CGRect frame = [noti.userInfo[UIKeyboardFrameEndUserInfoKey]CGRectValue];
//动画持续时间
NSTimeInterval duration = [noti.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
self.viewBottom.constant = frame.size.height;
[UIView animateWithDuration:duration animations:^{
[self.view layoutIfNeeded];
}];
NSLog(@"%f", self.viewBottom.constant);
[self scrillToTableViewLastRow];
}
-(void)keyboardClose:(NSNotification*)noti{
//动画持续时间
NSTimeInterval duration = [noti.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
self.viewBottom.constant = 0;
[UIView animateWithDuration:duration animations:^{
[self.view layoutIfNeeded];
}];
NSLog(@"键盘将要关闭了");
}
@end
Message.h
@interface Message : NSObject
@property(nonatomic,strong)NSString *message;
@property(nonatomic,assign,getter=isMe)BOOL me;
+(NSArray*)allMessage;
@end
Message.m
#import "Message.h"
@implementation Message
+(NSArray*)allMessage{
NSMutableArray *array = [NSMutableArray array];
Message *m = [[Message alloc]init];
m.message = @"在吗?";
m.me = YES;
[array addObject:m];
m = [[Message alloc]init];
m.message = @"最近好吗?";
m.me = YES;
[array addObject:m];
m = [[Message alloc]init];
m.message = @"在忙吗?";
m.me = YES;
[array addObject:m];
m = [[Message alloc]init];
m.message = @"嗯,在忙!";
m.me = NO;
[array addObject:m];
m = [[Message alloc]init];
m.message = @"找个时间一起吃个饭吧!";
m.me = YES;
[array addObject:m];
m = [[Message alloc]init];
m.message = @"呵呵!我先去洗澡了!";
m.me = NO;
[array addObject:m];
m = [[Message alloc]init];
m.message = @"好吧!多注意身体!";
m.me = YES;
[array addObject:m];
return array;
}
@end
MessageCell.h
@property (weak, nonatomic) IBOutlet UILabel *messageLabel;
otherCell.h
@property (weak, nonatomic) IBOutlet UILabel *label;
网友评论