Protocol翻译过来, 叫做”协议”
Protocol的作用
@protocol
协议名称
// 方法声明列表
@end
@interface
类名 : 父类 <协议名称1, 协议名称2,…>
@end
@protocol
SportProtocol
<NSObject>- (void)playFootball;- (void)playBasketball;@end#import "SportProtocol.h" // 导入协议@interface Studnet : NSObject<SportProtocol> // 遵守协议@end@implementation Student// 实现协议方法- (void)playBasketball{ NSLog(@"%s", __func__);}// 实现协议方法- (void)playFootball{ NSLog(@"%s", __func__);}@end
@protocol
SportProtocol
<NSObject>{ int _age; // 错误写法}- (void)playFootball;- (void)playBasketball;@end
@protocol
SportProtocol
<NSObject>- (void)playFootball;- (void)playBasketball;@end
#import "SportProtocol.h"
@interface
Student
: NSObject <SportProtocol>@end@interface GoodStudent : Student@end@implementation GoodStudent- (void)playFootball{ NSLog(@"%s", __func__);}- (void)playBasketball{ NSLog(@"%s", __func__);}@end
#import "SportProtocol.h"
#import "StudyProtocol.h"
@interface
Student
: NSObject <SportProtocol, StudyProtocol>@end
@protocol
A
-(
void
)
methodA
;
@end
@protocol
B <A>-(void)methodB;@end
@interface
Student
: NSObject <B>-(void)methodA; // 同时拥有A/B协议中的方法声明-(void)methodB;@end
NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它
还有名字也叫NSObject的协议,它是一个基协议,最根本最基本的协议
NSObject协议中声明很多最基本的方法
建议每个新的协议都要遵守NSObject协议
@protocol
SportProtocol
<NSObject> // 基协议- (void)playFootball;- (void)playBasketball;@end
@protocol SportProtocol
@required // 如果遵守协议的类不实现会报警告
- (void)playFootball;
@optional // 如果遵守协议的类不实现不会报警告
- (void)playBasketball;
@end
设定情景:
从题目中我们得到要求
@protocol
WifeCondition
<
NSObject
>
-
(void)cooking;- (void)washing;- (void)job;@end
// 如果没有遵守协议则会报警告
id
<
WifeCondition
>
wife
= [[Person alloc] init];
什么是设计模式
什么是代理设计模式
代理设计模式的场合:
baby.h
// 协议
#import
@class
Baby
;@protocol BabyProtocol <NSObject>- (void)feedWithBaby:(Baby *)baby;- (void)hypnosisWithBaby:(Baby *)baby;@end@interface Baby : NSObject// 食量@property (nonatomic, assign) int food;// 睡意@property (nonatomic, assign) int drowsiness;// 饿- (void)hungry;// 睡意- (void)sleepy;@property (nonatomic, weak) id<BabyProtocol> nanny;@end
#import "Baby.h"
#import "Mother.h"
#import "Father.h"
@implementation
Baby
-
(void)hungry{ self.food -= 5; NSLog(@"婴儿饿了"); // 通知保姆 if ([self.nanny respondsToSelector:@selector(feedWithBaby:)]) { [self.nanny feedWithBaby:self];}}- (void)sleepy{ self.drowsiness += 5; NSLog(@"婴儿困了"); // 通知保姆 if ([self.nanny respondsToSelector:@selector(hypnosisWithBaby:)]) { [self.nanny hypnosisWithBaby:self]; }}@end
// 保姆
@interface
Nanny
: NSObject <BabyProtocol>@end@implementation Nanny- (void)feedWithBaby:(Baby *)baby{ baby.food += 10; NSLog(@"给婴儿喂奶, 现在的食量是%i", baby.food);}- (void)hypnosisWithBaby:(Baby *)baby{ baby.drowsiness += 10; NSLog(@"哄婴儿睡觉, 现在的睡意是%i", baby.drowsiness);}@end
#import
@class
Student
;//谁的代理就写在谁的头部@protocol StudentDelegate <NSObject>- (void)helpToFindRoom:(Student *)student;@end@interface Student : NSObject@property (nonatomic, strong) NSString *name;@property (nonatomic, strong) id<StudentDelegate> delegate;- (void)goToGuangZhou;@end
#import "Student.h"
@implementation
Student
-
(void)goToGuangZhou{ if ([_delegate respondsToSelector:@selector(helpToFindRoom:)]) { [_delegate helpToFindRoom:self]; }}@end
#import
#import "Student.h"
@interface
Teacher
: NSObject <StudentDelegate>@end
#import "Teacher.h"
@implementation
Teacher
-
(void)helpToFindRoom:(Student *)student{ NSLog(@"帮%@同学找房子", student.name);}@end
#import
#import "Student.h"
#import "Teacher.h"
/*
学生来广州找代理帮他找房子
*/
int
main
(
int
argc, const char * argv[]) { @autoreleasepool { Student *stu = [[Student alloc] init]; Teacher *tea = [[Teacher alloc] init]; stu.name = @"zhangsan";stu.delegate = tea; [stu goToGuangZhou]; } return 0;}
frame方式,文字尺寸
@interface
XMGStatus
: NSObject/**** 文字\图片数据 ****/// ...../**** frame数据 ****//** 头像的frame */@property (nonatomic, assign) CGRect iconFrame;// ...../** cell的高度 */@property (nonatomic, assign) CGFloat cellHeight;@end
-
(
CGFloat
)
cellHeight
{
if (_cellHeight == 0) { // ... 计算所有子控件的frame、cell的高度} return _cellHeight;}
/**
* 返回每一行cell的具体高度
*/
-
(
CGFloat
)
tableView:
(
UITableView
*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ XMGStatus *status = self.statuses[indexPath.row]; return status.cellHeight;}
-
(
UITableViewCell
*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *ID = @"tg"; // 访问缓存池 XMGStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 设置数据(传递模型数据) cell.status = self.statuses[indexPath.row]; return cell;}
UITableViewCell
的子类,比如XMGStatusCell
@interface
XMGStatusCell
: UITableViewCell@end
-initWithStyle:reuseIdentifier:
方法
/**
* 在这个方法中添加所有的子控件
*/
-
(
instancetype
)
initWithStyle:
(
UITableViewCellStyle
)
style
reuseIdentifier:(NSString *)reuseIdentifier{ if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { // ...... } return self;}
@class
XMGStatus
;@interface XMGStatusCell : UITableViewCell/** 团购模型数据 */@property (nonatomic, strong) XMGStatus *status;@end
-
(
void
)
setStatus:
(
XMGStatus
*)status{ _status = status; // .......}
-layoutSubviews
方法
[super layoutSubviews]
/**
* 在这个方法中设置所有子控件的frame
*/
-
(
void
)
layoutSubviews
{
[super layoutSubviews]; // ......}
// 计算文字所占据的尺寸
NSDictionary
*nameAttrs = @{ NSFontAttributeName : [UIFont systemFontOfSize:17]}; CGSize nameSize = [self.name sizeWithAttributes:nameAttrs]; self.nameFrame = (CGRect){ { nameX, nameY},nameSize };// 文字 CGFloat textX = iconX; CGFloat textY = CGRectGetMaxY(self.iconFrame) + margin; CGFloat textW = [UIScreen mainScreen].bounds.size.width - 2 * textX; CGSize textMaxSize = CGSizeMake(textW, MAXFLOAT); NSDictionary *textAttrs = @{ NSFontAttributeName : [UIFont systemFontOfSize:14]}; CGFloat textH = [self.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:textAttrs context:nil].size.height; self.textFrame = CGRectMake(textX, textY, textW, textH);
- 设置tableViewCell的真实行高和估算行高
// 告诉tableView所有cell的真实高度是自动计算(根据设置的约束来计算)
self
.
tableView
.
rowHeight
=
UITableViewAutomaticDimension;// 告诉tableView所有cell的估算高度self.tableView.estimatedRowHeight = 44;
XMGStatusCell.m
-
(
void
)
awakeFromNib
{
// 手动设置文字的最大宽度(目的是:让label知道自己文字的最大宽度,进而能够计算出自己的frame) self.text_label.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;}
XMGStatusCell.m```objc- (CGFloat)height{
// 强制布局cell内部的所有子控件(label根据文字多少计算出自己最真实的尺寸)
[self layoutIfNeeded];
// 计算cell的高度
if (self.sta.picture) {
return CGRectGetMaxY(self.pictureImageView.frame) + 10;
}else{
return CGRectGetMaxY(self.text_label.frame) + 10;
}
}```- 设置tableView的cell估算高度
ViewController.mobjc// 告诉tableView所有cell的估算高度(设置了估算高度,就可以减少tableView:heightForRowAtIndexPath:方法的调用次数)self.tableView.estimatedRowHeight = 200;
- 在代理方法中计算cell的高度
XMGStatusCell
*
cell
;
-
(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ // 创建一个cell(cell的作用:根据模型数据布局所有的子控件,进而计算出cell的高度) if (!cell) { cell = [tableView dequeueReusableCellWithIdentifier:ID]; } // 设置模型数据 cell.status = self.statuses[indexPath.row]; return cell.height;}- (CGFloat)height{ // 强制布局cell内部的所有子控件(label根据文字多少计算出自己最真实的尺寸) [self layoutIfNeeded]; // 计算cell的高度 if (self.status.picture) { return CGRectGetMaxY(self.pictureImageView.frame) + 10; } else { return CGRectGetMaxY(self.text_label.frame) + 10; }
写博客第一百零五天;
QQ:565803433