iOS-通过继承UIScrollView来自定义UITableView实现对代理的详解

6 篇文章 0 订阅
5 篇文章 0 订阅

文明转载评论是对自己尊重也是对学者的鼓励

             iOS-通过继承UIScrollView来自定义UITableView实现对代理的详解


一.自定义UITableView     (CustomerTableView继承于UIScrollView)

实现一个类继承至UIScrollView,通过代理的语法模式实现UITableView的获得UITableviewCell和UITableviewCell的布局的原理,从而加深对UITableview的原理及对代理模式的理解。

CustomerTableView.h头文件
#import <UIKit/UIKit.h>
@class CustomerTableView;

@protocol CustomerTableViewDelegate <NSObject>
//返回cell的个数
-(NSInteger)numberCellForCustomerTableView:(CustomerTableView *)customerView;
//返回cell的高度
-(CGFloat)cellHeightForCustomerTableView:(CustomerTableView *)customerView ;
//相当于cell
-(UIView *)customerTableView:(CustomerTableView *)customerView cellForIndex:(NSInteger)index;
//返回标题
-(NSString *)customerTableView:(CustomerTableView *)customerView titleForIndex:(NSInteger)index;

@end

@interface CustomerTableView : UIScrollView
//代理
@property (nonatomic,assign)id<CustomerTableViewDelegate> customerDelegate;
//设置代理和frame
-(id)initWithDelegate:(id<CustomerTableViewDelegate>)aDelegate andFrame:(CGRect)aFrame;


@end


CustomerTableView.m文件

#import "CustomerTableView.h"

@implementation CustomerTableView

-(id)initWithDelegate:(id<CustomerTableViewDelegate>)aDelegate andFrame:(CGRect)aFrame{
    if (self = [super initWithFrame:aFrame]) {
        
        self.frame = aFrame;
        //通过代理得到多少个cell
        int numberCell = (int)[aDelegate numberCellForCustomerTableView:self];
        //通过代理得到cell的高度,用来设置cell的布局
        CGFloat cellHeight = [aDelegate cellHeightForCustomerTableView:self];
        
        CGFloat width = CGRectGetWidth(aFrame);
        CGFloat height = CGRectGetHeight(aFrame);
        
        //根据cell的个数来设置contentSize
        self.contentSize = CGSizeMake(width, numberCell*cellHeight);
        
        
        //循环的通过代理来拿到cell  title  并根据索引i来设置它们的位置,其他的属性又属性设置
        for (int i=0; i<numberCell; i++) {
            
            UIView *cell = [aDelegate customerTableView:self cellForIndex:i];
            cell.frame = CGRectMake(0, cellHeight*i, width, cellHeight);
            [self addSubview:cell];
            
            NSString *title = [aDelegate customerTableView:self titleForIndex:i];
            
            UILabel *lable = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, width, cellHeight)];
            lable.backgroundColor = [UIColor brownColor];
            lable.text = title;
            [cell addSubview:lable];
            
        }
        
        
    }
    return self;
}

@end

使用:
#import "ViewController.h"
#import "CustomerTableView.h"

@interface ViewController ()<CustomerTableViewDelegate>
@end
@implementation ViewController{
}
- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    CustomerTableView *customer = [[CustomerTableView alloc]initWithDelegate:self andFrame:CGRectMake(0, 0, 320, 400)];
    customer.showsHorizontalScrollIndicator = NO;
    customer.backgroundColor = [UIColor purpleColor];
    [self.view addSubview:customer];
    
    
}

//返回cell的高度
-(CGFloat)cellHeightForCustomerTableView:(CustomerTableView *)customerView{
    return 100;
}
//返回对应索引的的名字
-(NSString *)customerTableView:(CustomerTableView *)customerView titleForIndex:(NSInteger)index{
    return [NSString stringWithFormat:@"item %ld",index];
}
//相当于UITableView的返回cell
-(UIView *)customerTableView:(CustomerTableView *)customerView cellForIndex:(NSInteger)index{
    UIView *v = [[UIView alloc]init];
    v.backgroundColor = [UIColor redColor];
    return v;
}
//返回cell的个数
-(NSInteger)numberCellForCustomerTableView:(CustomerTableView *)customerView{
    return 10;
}

@end



运行效果:




二.UITableView的使用

    UITableView *table = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 400)];
    table.delegate = self;
    table.dataSource = self;
    [self.view addSubview:table];

代理使用:

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}


//相当于CustomerTableview返回多少个cell
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 10;
}

//相当于CustomerTableView 的UIView的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 100;
}

//相当于CustomerTableview   的UIView
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
    cell.textLabel.text = [NSString stringWithFormat:@"item%ld",indexPath.row];
    return cell;
}


运行效果:




三.两者对比了解代理模式


委托持有代理的引用,代理实现协议,委托通过代理得到代理服务。就比如你要找房子你要找一个阳光好的,价格少于1000元。房产中介能为你找房,它能提供很多的房源,有阳光好的少于1000的家电齐全等等,现在你们并没有什么关系,如果你想找房不可能呆在家里,于是你找了一家房产中介,这时你就成了委托方法,这时们就会签署一式两份的找房协议,上面有你的签名和中介的签名,你们各持有一份,这时你们就建立了委托代理的关系,这时你关系的不是中介提供的其他服务,你只关心签署协议中的条件。然后中介就会拿出符合条件的房源给你。这就是生活中的代理模式的例子。

上面只是一个简单的代理的生活抽象。把它映射到代码中又会是什么样了:

@protocol   someDelegate<NSObject>   //你们要签署的协议,这个协议是由你来提出
-(house*)getHouse;                                 //要找的房子
@end

@interface some
@property (assign,nonautomic)id<someDelegate> delegate;     //你去找了哪家的代理中介
@end



@interface agent()<someDelegate>    //实现找房的协议
@end
@implement agent
-(house *)getHouse{ //找到符合条件的房子
return house;
@end


委托和代理建立联系,上面只是代码的设计。

运行时才是真实场景的存在:

some *you =[[some alloc]init];  //你出现了
agent  *agent =[ [agen alloc]init] //房产中介出现了

上面两步委托和代理没有建立委托代理的关系
you.delegate = agent;        //委托代理建立了关系,相当于签署了找房协议


[you.delegate  getHouse]  //这样你就能通过代理给你找到房子了。


运行时内存状态抽象图:







总结:代理模式随处可见,一般在MVC设计模式中,V(视图)层常常通过代理C(控制)层得到要显示的数据,并把用户对V(视图)层的操作传给C(控制)层,让C做相应的处理。如上中的UITableView (视图层)  UIViewController(控制层),UITalbleView通过UIViewController的到数据,也可以把用户的操作传到UIViewController,所以任何的设计模式只要把它映射成C语言的数据和函数,就会更容易理解各种模式的设计原理。






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值