天天看點

關于代理方法的使用

項目中用到的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模式的機會。