案例1
KCButton.h////KCButton.h//PRotocol&Block&Category////Created by Kenshin Cui on 14-2-2.//Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#import<Foundation/Foundation.h>@classKCButton;//一个协议可以扩展另一个协议,例如KCButtonDelegate扩展了NSObject协议@protocolKCButtonDelegate <NSObject>@required//@required修饰的方法必须实现-(void)onClick:(KCButton *)button;
@optional//@optional修饰的方法是可选实现的-(void)onMouSEOver:(KCButton *)button;-(void)onMouseout:(KCButton *)button;@end@interfaceKCButton : NSObject#pragmamark - 属性#pragmamark 代理属性,同时约定作为代理的对象必须实现KCButtonDelegate协议@property (nonatomic,retain)id<KCButtonDelegate>delegate;#pragmamark - 公共方法#pragmamark 点击方法
-(void)click;@end
KCButton.m////KCButton.m//Protocol&Block&Category////Created by Kenshin Cui on 14-2-2.//Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#import"KCButton.h"@implementationKCButton-(void)click{
NSLog(@"Invoke KCButton's click method.");//判断_delegate实例是否实现了onClick:方法(注意方法名是"onClick:",后面有个:)//避免未实现ButtonDelegate的类也作为KCButton的监听if([_delegate respondsToSelector:@selector(onClick:)]){
[_delegate onClick:self];
}
}@endMyListener.h////MyListener.h//Protocol&Block&Category////Created by Kenshin Cui on 14-2-2.//Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#import<Foundation/Foundation.h>@classKCButton;@protocolKCButtonDelegate;@interfaceMyListener : NSObject<KCButtonDelegate>
-(void)onClick:(KCButton *)button;@endMyListener.m////MyListener.m//Protocol&Block&Category////Created by Kenshin Cui on 14-2-2.//Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#import"MyListener.h"#import"KCButton.h"@implementationMyListener-(void)onClick:(KCButton *)button{
NSLog(@"Invoke MyListener's onClick method.The button is:%@.",button);
}@endmain.m////main.m//Protocol&Block&Category////Created by Kenshin Cui on 14-2-2.//Copyright (c) 2014年 Kenshin Cui. All rights reserved.//#import<Foundation/Foundation.h>#import"KCButton.h"#import"MyListener.h"intmain(intargc,constchar*argv[]) {
@autoreleasepool {
KCButton*button=[[KCButton alloc]init];
MyListener*listener=[[MyListener alloc]init];
button.delegate=listener;
[button click];/*结果:
Invoke KCButton's click method.
Invoke MyListener's onClick method.The button is:<KCButton: 0x1001034c0>.*/}return0;
}
我们通过例子模拟了一个按钮的点击过程,有点类似于java中事件的实现机制。通过这个例子我们需要注意以下几点内容:
id可以表示任何一个ObjC对象类型,类型后面的”<协议名>“用于约束作为这个属性的对象必须实现该协议(注意:使用id定义的对象类型不需要加“*”);
MyListener作为事件触发者,它实现了KCButtonDelegate代理(在ObjC中没有命名空间和包的概念,通常通过前缀进行类的划分,“KC”是我们自定义的前缀)
在.h文件中如果使用了另一个文件的类或协议我们可以通过@class或者@protocol进行声明,而不必导入这个文件,这样可以提高编译效率(注意有些情况必须使用@class或@protocol,例如上面KCButton.h中上面声明的KCButtonDelegate协议中用到了KCButton类,而此文件下方的KCButton类声明中又使用了KCButtonDelegate,从而形成在一个文件中互相引用关系,此时必须使用@class或者@protocol声明,否则编译阶段会报错),但是在.m文件中则必须导入对应的类声明文件或协议文件(如果不导入虽然语法检查可以通过但是编译链接会报错);
使用respondsToSelector方法可以判断一个对象是否实现了某个方法(需要注意方法名不是”onClick”而是“onClick:”,冒号也是方法名的一部分);
属性中的(nonatomic,retain)不是这篇文章的重点,在接下来的文章中我们会具体介绍。
案例2
////WPContactsViewController.h//OC-UI-表单-单元格////Created by wangtouwang on 15/3/26.//Copyright (c) 2015年 wangtouwang. All rights reserved.//#import<UIKit/UIKit.h>@interfaceWPContactsViewController : UIViewController
{
UITableView*_tableView;//表单UI控件NSMutableArray *_mutableArrayContacts;//联系人集合模型NSIndexPath *_selectedIndexPath;//当前选中的组和行}@end
////WPContactsViewController.m//OC-UI-表单-单元格////Created by wangtouwang on 15/3/26.//Copyright (c) 2015年 wangtouwang. All rights reserved.//#import"WPContactsViewController.h"#import"WPContacts.h"#import"WPContactsGroup.h"@interface WPContactsViewController ()<UITableViewDataSource,UITableViewDelegate,UIAlertViewDelegate>@end@implementationWPContactsViewController- (void)viewDidLoad {
[super viewDidLoad];//初始化数据[self initObjectData];//创建一个分组样式的UITableView_tableView=[[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];//设置数据源,注意必须实现对应的UITableViewDataSource协议_tableView.dataSource=self;//设置代理_tableView.delegate=self;[self.view addSubview:_tableView];
}- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];//Dispose of any resources that can be recreated.}#pragmamark 加载数据
-(void)initObjectData{
_mutableArrayContacts=[[NSMutableArray alloc]init];
WPContacts*contact1=[WPContacts initStaticWithFirstName:@"Cui"andLastName:@"Kenshin"andPhoneNumber:@"18500131234"];
WPContacts*contact2=[WPContacts initStaticWithFirstName:@"Cui"andLastName:@"Tom"andPhoneNumber:@"18500131237"];
WPContactsGroup*group1=[WPContactsGroup initStaticWithName:@"C"andDescript:@"With names beginning with C"andConcats:[NSMutableArray arrayWithObjects:contact1,contact2, nil]];
[_mutableArrayContacts addObject:group1];
WPContacts*contact3=[WPContacts initStaticWithFirstName:@"Dui"andLastName:@"JACK"andPhoneNumber:@"13712133321"];
WPContacts*contact4=[WPContacts initStaticWithFirstName:@"Dui"andLastName:@"LUCY"andPhoneNumber:@"13712133322"];
WPContactsGroup*group2=[WPContactsGroup initStaticWithName:@"D"andDescript:@"With names beginning with D"andConcats:[NSMutableArray arrayWithObjects:contact3,contact4, nil]];
[_mutableArrayContacts addObject:group2];
}#pragmamark 返回分组数
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
NSLog(@"计算分组数");return_mutableArrayContacts.count;
}#pragmamark 返回每组行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(@"计算每组(组%lu)行数",(unsignedlong)section);//WPContactsGroup *group1 = _mutableArrayContacts[section];return((WPContactsGroup *)_mutableArrayContacts[section])._concats.count;
}#pragmamark返回每行的单元格
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"生成单元格(组:%lu,行%lu)",(unsignedlong)indexPath.section,(unsignedlong)indexPath.row);
WPContactsGroup*group=_mutableArrayContacts[indexPath.section];
WPContacts*contacts =group._concats[indexPath.row];
UITableViewCell*cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil];
cell.textLabel.text=[contacts getName];
cell.detailTextLabel.text=[contacts _phoneNumber];returncell;
}#pragmamark 返回每组头标题名称
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
NSLog(@"生成组(组%lu)名称",(unsignedlong)section);
WPContactsGroup*group =_mutableArrayContacts[section];returngroup._name;
}#pragmamark 返回每组尾部说明
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
NSLog(@"生成尾部(组%lu)详情",(unsignedlong)section);return((WPContactsGroup *)_mutableArrayContacts[section])._descript;
}#pragmamark 生成索引
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
NSLog(@"生成组索引");
NSMutableArray*indexs =[[NSMutableArray alloc] init];for(WPContactsGroup *groupin_mutableArrayContacts) {
[indexs addObject:group._name];
}returnindexs;
}#pragmamark 设置分组标题高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
NSLog(@"设置分组标题高度");return25;
}#pragmamark 设置分组尾部内容高度
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
NSLog(@"设置分组尾部内容高度");return20;
}#pragmamark 设置每行高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"设置每行高度");return30;
}#pragmamark 复写设置点击行触发事件(复写的方法是在TableViewDelegate协议中已有,回调)
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"触发我吧");
_selectedIndexPath=indexPath;//获取单元格包装的对象WPContactsWPContacts *contacts = ((WPContactsGroup *)_mutableArrayContacts[indexPath.section])._concats[indexPath.row];//初始化弹出框UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"System Info" message:[contacts getName] delegate:self cancelButtonTitle:@"Cancle" otherButtonTitles:@"OK", nil];//设置窗口样式alertView.alertViewStyle=UIAlertViewStylePlainTextInput;//获取文本框UITextField *textFild = [alertView textFieldAtIndex:0];//设置文本框内容textFild.text =contacts._phoneNumber;//显示窗口[alertView show];
}#pragmamark 设置弹出框后续按钮事件 复写UIAlerViewDelegate协议 的点击按钮 clickedButtonAtIndex方法
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSLog(@"设置弹出框后续按钮事件 clickedButtonAtIndex");if(buttonIndex==1) {//获取文本框内容NSString *phoneNumber = [alertView textFieldAtIndex:0].text;//获取选中的UITableViewCell 包装的对象WPContacts *contacts = ((WPContactsGroup *)_mutableArrayContacts[_selectedIndexPath.section])._concats[_selectedIndexPath.row];
contacts._phoneNumber=phoneNumber;
NSArray*indexPaths=@[_selectedIndexPath];//需要局部刷新的单元格的组、行//此处优化 将全局跟新 该变到 选择行 局部更新[_tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationLeft];//[_tableView reloadData];}
}@end