天天看点

关于代理方法的使用

项目中用到的tableView中,经常会遇到cell上的元素,比如button和imageView需要点击响应和cell的didSelect不一样的方法,这个时候使用代理方进行处理,是一个极好的方法。关于代理方法那一堆理论就不再赘述,找度娘问问就明白了。

首先说一下我的思路,我用的tableview并没有创建一个UITableViewCell的class,而是创建了一个UIView的类来进行cell上UI的定制。那么我就在这个类里进行delegate的创建。

@protocol MyDelegate <NSObject>
-(void)didClickButton:(UIButton *)sender;
-(void)didClickImage:(UIImageView *)imageView;
@end

@interface Pic61MyquestionView : UIView
@property(nonatomic,strong)UIButton *GoodButton;
@property(nonatomic,strong)UIImageView *imageView;
@property(nonatomic,assign)id<MyDelegate>delegate;

-(id)initWithIndex:(NSIndexPath*)index;
@end
           

@protocol MyDelegate 方法下面就是声明你要使用的代理方法了。在这个地方又一个需要说明的地方,那就是如果你的方法必须被实现才行,那你必须在你声明的方法前面加上@required,如果是可以选择的,即实现不实现都可以,那你可以不加,或者加上@optional,具体用法如下:

@protocol MyDelegate <NSObject> @optional//这个可以是required,也可以是optional - (void)didClickButton:(UIButton *)sender; - (void)didClickImage:(UIImageView *)imageView; @end

在设置了代理方法之后,我们还需要在这个view的属性声明那里声明一个属性@property(nonatomic,assign)iddelegate;你在引用的时候设置代理使用

以上都是在view的.h文件里的处理,接下来是.m文件的处理方法。

因为这里讲的是button和imageView,创建的方法比较简单,只说响应方法

//响应方法
- (void)buttonClick:(UIButton *)sender {
    //确定委托是否存在代理方法
    if (_delegate && [_delegate respondsToSelector:@selector(didClickButton:)]) {
        //发送委托方法,方法的参数为用户点击的button
        [_delegate didClickButton:sender];
    }
}

- (void)tapGestureResponse:(UITapGestureRecognizer *)tap {
    if (_delegate && [_delegate respondsToSelector:@selector(didClickImage:)]) {
        [_delegate didClickImage:(UIImageView *)tap.view];
    }
}
           

最后就是使用代理方法了。我这里的使用是在tableview的cellforrow使用的。

首先你需要

@interface SecondViewController ()<UITableViewDataSource,UITableViewDelegate,MyDelegate>
{
    UITableView *_tableView;
}
@end
           

在tableView中设置如下

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *str=@"cell";
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:str];
    if (cell==nil) {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:str];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

    }

    Pic61MyquestionView *views = [[Pic61MyquestionView alloc]initWithIndex:indexPath];
    NSString *index = [NSString stringWithFormat:@"%ld.jpg",indexPath.row];
    [views.GoodButton setBackgroundImage:[UIImage imageNamed:index] forState:UIControlStateNormal];
    //设置代理
    views.delegate = self;
    [cell.contentView addSubview:views];

    return cell;
}
           

实现代理方法

#pragma mark- delegate method
- (void)didClickButton:(UIButton *)sender {
    NSLog(@"点击了第%ld个button",sender.tag);
}

- (void)didClickImage:(UIImageView *)imageView {
    NSLog(@"点击了第%ld个image",imageView.tag);
}
           

从委托类的定义可以看出,委托与协议有一定的相似性。都采用protocol关键字来声明

,并且其中的方法都有optional和required,都需要对required方法和调用的optional方法进行实现。而不同的是在委托对象所在的类中需要定义一个delegate对象,并且为id类型。

但是delegate与protocol没有关系。Delegate本身应该称为一种设计模式,是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成,而实际做事的类为delegate。而protocol是一种语法,它的主要目标是提供接口给遵守协议的类使用,而这种方式提供了一个很方便的、实现delegate模式的机会。