tableView's Skills


iOS 列表性能優(yōu)化之異步繪制

Demo:stkusegithub/AsyncDraw






Cell不變色、不可選

[A].Cell不變色
(a). Cell不能變色:
 cell.selectionStyle = UITableViewCellSelectionStyleNone;
 //不能變色  (選中的風(fēng)格:無(wú)顏色)

Cell的其他選中色:
//藍(lán)色
cell.selectionStyle = UITableViewCellSelectionStyleBlue; 

//灰色  
cell.selectionStyle = UITableViewCellSelectionStyleGray; 


(b). Cell取消選中,變?cè)?/h6>
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    //取消選中后,變?yōu)樵?    [tableView deselectRowAtIndexPath:indexPath animated:NO];
}





[B].Cell不可選
a. 處理tableView的“select”方法:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath{
     return nil; //tableview不可選
}


b. 不經(jīng)過tableView的“select”方法
self.myTableView.allowsSelection = NO;//不響應(yīng)select
cell.selectionStyle = UITableViewCellSelectionStyleNone;//選中:無(wú)色




header標(biāo)題

[ 1 ].系統(tǒng)自帶的方法:titleForHeaderInSection (背景色:深灰

// 深灰色(背景色)
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    ClassesListCellModel * model = self.dataArray[section];
    return model.date;
}



[ 2 ].自己把headerView視圖,設(shè)置為一個(gè)Label

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView * view = [[UIView alloc] init];

    UILabel * date_LB = [[UILabel alloc] init];
    CategoryListCellModel * model = self.dataArray[section];
    date_LB.text = model.date; //格式:@"2017-08-02"
    date_LB.textColor = [UIColor lightGrayColor];
    [view addSubview: date_LB];
    [date_LB mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(view).with.offset(10.f);
        make.centerY.equalTo(view).with.offset(0.f);
   
    }];

    view.backgroundColor = All_BG_Color;
    return view;
}




內(nèi)容重復(fù):cell復(fù)用問題

QuesListTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
    cell = [[QuesListTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}

使用“Debug View Hierarchy”,查看視圖關(guān)系

Debug View Hierarchy



解決

cell的復(fù)用,定位每一行[tableView cellForRowAtIndexPath:indexPath];

QuesListTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];//定位到每一行
if (!cell) {
    cell = [[QuesListTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}

改善后效果









分割線隱藏:separator

  • 設(shè)置separator背景色:透明
    self.quesListTabV.separatorColor = [UIColor clearColor];


  • 設(shè)置cell相對(duì)于contentView上左下右間距
    在“-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { }”里:

    cell.separatorInset = UIEdgeInsetsMake(0, cell.contentView.frame.size.width/2.f, cell.contentView.frame.size.width/2.f, 0);
    




提前 注冊(cè)Cell (“register”方法)

  • - (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);

    在創(chuàng)建UITableView的時(shí)候,就可以順帶注冊(cè)復(fù)用的Cell?。?/p>

    [self.tableView registerClass:[FKTableViewCell class] forCellReuseIdentifier:@"FKCell"];
    

    這樣,在“- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { }”里,就只需要:

    FKTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FKCell" forIndexPath:indexPath];
    


    可以省去如下代碼:

    static NSString *CellIdentifier = @"FKCell";
    FKTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
    if (cell == nil) {
        cell = [[FKTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        //設(shè)置cell
    
    }
    



  • 如果已經(jīng)用NIB來(lái)制作了一個(gè)Cell:

    - (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);

    注冊(cè)復(fù)用的cell??!

    [self.resourceTabV registerNib:[UINib nibWithNibName:@"ResourceTableViewCell" bundle:nil] forCellReuseIdentifier:@"cell"];
    

    在“- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { }”里:

    ResourceTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    


    可以省去如下代碼:

    ResourceTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (!cell) {
       cell = [ResourceTableViewCell xibTableViewCell];
    }
    


    在“ResourceTableViewCell.m”里面:
    //實(shí)現(xiàn)類方法
     +(instancetype)xibTableViewCell {
        //在類方法中加載xib文件    firstObject、lastObject都可以
        return [[[NSBundle mainBundle] loadNibNamed:@"ResourceTableViewCell" owner:nil options:nil] lastObject];
    }
    






Xib關(guān)聯(lián)的UITableViewCell


視圖布局(Xib文件)

在“JobsTableViewCell.m”里面: (loadNibNamed:加載nib)

//實(shí)現(xiàn)類方法
+(instancetype)xibTableViewCell {
    //在類方法中加載xib文件   (僅一個(gè)元素 :firstObject、lastObject都可以)

    return [[[NSBundle mainBundle] loadNibNamed:@"JobsTableViewCell" owner:nil options:nil] lastObject];
    //loadNibNamed:關(guān)聯(lián)的名字(本身名字)
}



- (void)awakeFromNib {
    [super awakeFromNib];

    /** 設(shè)置控件屬性 */
    self.titleImgV.image = [UIImage imageNamed:@"hg_job_avatar"];
    self.titleLB.text = @"工作標(biāo)題";
    self.detailInfoLB.text = @"工作安排";
    self.littlePicImgV.image = [UIImage imageNamed:@"hg_progress"];
}


使用Cell:
    • 在“-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { }”里:

      JobsTableViewCell * jobDataCell = [tableView dequeueReusableCellWithIdentifier:@"jobCell"];
      //如果緩存池中沒有,那么創(chuàng)建一個(gè)新的cell
      if (! jobDateCell) {
           //這里換成自己定義的cell,并調(diào)用類方法加載xib文件
           jobDataCell = [JobsTableViewCell xibTableViewCell];
      }
      

    不能使用:“alloc”方法創(chuàng)建Cell (???????)
    JobsTableViewCell * jobDataCell = [[JobsTableViewCell alloc]  initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"jobCell"];
    //??? 不能使用 “alloc”方法 創(chuàng)建 ???
    



    • 另一種使用方式:(注冊(cè) 復(fù)用Cell)
      在創(chuàng)建tableView時(shí),直接注冊(cè) 復(fù)用Cell

      [self.jobListTabV registerNib:[UINib nibWithNibName:@"JobsTableViewCell" bundle:nil] forCellReuseIdentifier:@"jobCell"];
      


      在“-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { }”里的寫法:

      JobsTableViewCell * jobDataCell = [tableView dequeueReusableCellWithIdentifier:@"jobCell" forIndexPath:indexPath];
      




自定義的Cell尺寸調(diào)整 (setFrame

- (void)setFrame:(CGRect)frame {
    //上 分隔線的距離:SCREEN_WIDTH*30.f/750.f
    frame.origin.y += SCREEN_WIDTH*30.f/750.f;
    //下 分隔線的距離:0 (= size.hight偏差 - origin.y偏差)
    frame.size.height -= SCREEN_WIDTH*30.f/750.f;

    float distance_X = SCREEN_WIDTH*30.f/750.f;//左、右邊間距
    frame.origin.x += distance_X;
    frame.size.width -= 2*distance_X;

    [super setFrame:frame];
}


效果:給layer層,加上邊框!








添加 長(zhǎng)按手勢(shì)

// 添加長(zhǎng)按手勢(shì)
UILongPressGestureRecognizer * longPressGr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressMyTableView:)];
longPressGr.minimumPressDuration = 1.5f; //長(zhǎng)按手勢(shì)的“最短時(shí)長(zhǎng)”
[self.myTabV addGestureRecognizer:longPressGr];

//長(zhǎng)按手勢(shì) 的響應(yīng)方法
-(void)longPressMyTableView:(UILongPressGestureRecognizer *)gesture {
    if(gesture.state == UIGestureRecognizerStateBegan) { //“手勢(shì)開始”狀態(tài)
        CGPoint point = [gesture locationInView: self.myTabV];
        NSIndexPath * indexPath = [self.myTabV indexPathForRowAtPoint:point];
    
        if(indexPath == nil) return; //其他 不是Cell所在的地方

    
        NSLog(@"longPress  indexPath.row:%ld",indexPath.row);//所點(diǎn)擊cell的位置
        //根據(jù) 所點(diǎn)擊Cell的位置,做響應(yīng)操作!
        //add your code here

    }
}







tableView相對(duì)于導(dǎo)航欄的偏移

宏定義:
//忽略導(dǎo)航欄
#define SCREEN_WithOutNavBar CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 64.f)

定義tableView:

self.detailsListTabV = [[UITableView alloc] initWithFrame:SCREEN_WithOutNavBar style:UITableViewStylePlain];
self.detailsListTabV.separatorColor = [UIColor clearColor];

[self.view addSubview:self.detailsListTabV];


故障的效果:


原因

視圖控制器會(huì)根據(jù)狀態(tài)欄,導(dǎo)航欄標(biāo)簽欄,來(lái)調(diào)整它所包含的scrollview偏移量!!
由于tableview、collectionviewtextview等都是繼承于scrollview,所以都會(huì)出現(xiàn)這種情況。

解決

self.edgesForExtendedLayout = UIRectEdgeNone;//從導(dǎo)航欄開始
//self.extendedLayoutIncludesOpaqueBars = NO;

從導(dǎo)航欄開始,進(jìn)行tableView的布局??!


效果







Cell里的按鈕響應(yīng)

自定義的ResourceTableViewCell:
  • ResourceTableViewCell.xib

  • ResourceTableViewCell.h”里:

    #import <UIKit/UIKit.h>
    
    @protocol ClickCellDelegate <NSObject> //協(xié)議 各按鈕點(diǎn)擊響應(yīng)
    - (void)didClickIndexWithBtn:(UIButton *)button;
    @end
    
    
    @interface ResourceTableViewCell : UITableViewCell
    
    @property (nonatomic,weak) id<ClickCellDelegate> delegate;//響應(yīng)的協(xié)議 
    
    /** ??????直接拖的各個(gè)按鈕?????? */
    @property (weak, nonatomic) IBOutlet UIButton *collectionBtn;//收藏按鈕
    @property (weak, nonatomic) IBOutlet UIButton *sendToEmailBtn;//傳到郵件按鈕
    @property (weak, nonatomic) IBOutlet UIButton *previewBtn;//預(yù)覽按鈕
    
    +(instancetype)xibTableViewCell;//初始化方法
    @end
    

  • ResourceTableViewCell.m”里:

    #import "ResourceTableViewCell.h"
    
    #define Button_Tag 1000
    
    
    
    @implementation ResourceTableViewCell
    
    //實(shí)現(xiàn)類方法
    +(instancetype)xibTableViewCell {
        //在類方法中加載xib文件    firstObject、lastObject都可以
        return [[[NSBundle mainBundle] loadNibNamed:@"ResourceTableViewCell" owner:nil options:nil] lastObject];
    }
    
    
    - (void)awakeFromNib {
        [super awakeFromNib];
    
    
        _collectionBtn.tag = Button_Tag;        //收藏按鈕
        _sendToEmailBtn.tag = Button_Tag + 1;   //發(fā)送按鈕
        _previewBtn.tag = Button_Tag + 2;       //閱覽按鈕
    }
    
    
    /** ??????各按鈕直接拖的方法?????? */
    - (IBAction)collectBtnPress:(id)sender {
        [self tapWithBtn:sender];
    }
    - (IBAction)sendToEmailBtnPress:(id)sender {
        [self tapWithBtn:sender];
    }
    - (IBAction)perviewBtnPress:(id)sender {
        [self tapWithBtn:sender];
    }
    
    -(void)tapWithBtn:(UIButton *)button {
        //聲明好的代理
        if([self.delegate respondsToSelector:@selector(didClickIndexWithBtn:)]) {
            [self.delegate didClickIndexWithBtn:button];
        }
    }
    
    @end
    


使用

在使用了“ResourceTableViewCell”的tableView所在界面里:

  • 滿足協(xié)議<ClickCellDelegate>

  • 設(shè)置全局變量:用來(lái)獲取 響應(yīng)Cell 所在位置?。?br> NSIndexPath * _whole_IndexPath; //全局選擇項(xiàng)

  • 注冊(cè)Cell:(在創(chuàng)建tableView時(shí))
    [self.reourcesTabV registerNib:[UINib nibWithNibName:@"ResourceTableViewCell" bundle:nil] forCellReuseIdentifier:@"cell"];


  • 設(shè)置Cell的代理<ClickCellDelegate>

    在“-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { }”里面:

    ResourceTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    cell.delegate = self;//設(shè)置代理
    


  • 重寫代理方法

    #pragma mark - ClickCellDelegate
    -(void)didClickIndexWithBtn:(UIButton *)button {
    
      ResourceTableViewCell *cell = (ResourceTableViewCell *)[[[button superview] superview] superview];
      //cell、xib、view 三層
      / ** 解釋:
        第1層:[button superview]是ResourceTableViewCell的“contentView”;
        第2層:第二個(gè)superview是ResourceTableViewCell??自己本身??的“cell”;
        第3層:第三個(gè)superview是??UITableView??的“cell”。
      * /
    
    
      _whole_IndexPath = [self.reourcesTabV indexPathForCell:cell];
      //??????獲取到是哪一行的Cell  被點(diǎn)擊!??????
      //NSLog(@"indexPath row is = %li",(long)_whole_IndexPath.row);
    
    
      //獲取該行Cell的模型
      ResourceListCellModel * model = self.dataArray[_whole_IndexPath.row]; //獲取該行Cell的模型
    
      //??????用Cell按鈕的tag值,來(lái)判斷是哪個(gè)按鈕??????
      switch (button.tag - 1000) { 
          case 0:{ //收藏
    
          }break;
          case 1:{ //發(fā)送郵件
    
          }break;
          case 2:{ //預(yù)覽
    
          }break;
          default:
              break;
    
    }
    


思路
1.獲取點(diǎn)擊的Cell所在位置(indexPath);
2.根據(jù)tag值,判斷是哪個(gè)按鈕(子視圖)被點(diǎn)擊!

















goyohol's essay

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容