先創(chuàng)建一個UITableViewCell的xib
#import "MyTableViewCell.h"
#import <UIKit/UIKit.h>
@interface MyTableViewCell : UITableViewCell
- (IBAction)clickMeBtn:(UIButton *)sender;
@property (copy, nonatomic) void(^touchClickButton)();
@end
#import "MyTableViewCell.h"
@implementation MyTableViewCell
- (void)awakeFromNib {
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
}
//定制UITableViewCell的事件響應處理
- (IBAction)clickMeBtn:(UIButton *)sender {
if (self.touchClickButton) {
self.touchClickButton();
}
}
@end
對UITabeView基本用法的總結(jié)
#import "ViewController.h"
#import "MyTableViewCell.h"
@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
@property (nonatomic , strong) UITableView * tableView;
@property (nonatomic , assign) NSInteger index;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self tableView];
}
#pragma mark - 設置cell分割線靠右
-(void)viewDidLayoutSubviews {
if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPat{
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setSeparatorInset:)]){
[cell setSeparatorInset:UIEdgeInsetsZero];
}
}
#pragma mark - UITableViewDelegate
//section的header view 的高度。
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 64;
}
//section的footer view 的高度
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0.1;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#pragma mark - UITableViewDataSource
//返回分區(qū)數(shù)(默認為1)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 6;
}
//返回每個分區(qū)頭部的標題和尾部標題
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;{
return @"每個分區(qū)頭部的標題";
}
//設置自定義頭視圖和尾視圖--當然,我們可以通過self.tableView.tableHeaderView = [UIView alloc] init];這種方式來自定義headerView隶糕,但是這種方式會使tableView中所有的headerView都一樣尚揣,如果我們想讓每一組的headerView不一樣只能使用代理方法。
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;{
UIView * view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 20)];
view.backgroundColor = [UIColor yellowColor];
return view;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyTableViewCell" forIndexPath:indexPath];
//cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;//顯示箭頭
//cell.selectionStyle = UITableViewCellSelectionStyleNone;//點擊沒有效果
//點擊cell里的button執(zhí)行的事件
__weak typeof(self)weakSelf = self;
[cell setTouchClickButton:^{
weakSelf.index = indexPath.row;
NSLog(@"你點擊的是第%ld",(long)weakSelf.index);
}];
return cell;
}
#pragma mark - lazyloading
- (UITableView *)tableView {
if(_tableView == nil) {
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
_tableView.delegate = self;
_tableView.dataSource = self;
//設置cell的自適應高度
_tableView.estimatedRowHeight = 44;//預計高度為44
_tableView.rowHeight = UITableViewAutomaticDimension;//自適應高度
//_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;//不顯示分割線
[_tableView registerNib:[UINib nibWithNibName:@"MyTableViewCell" bundle:nil] forCellReuseIdentifier:@"MyTableViewCell"];
[self.view addSubview:_tableView];
}
return _tableView;
}
//實現(xiàn)右滑動刪除
//- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// return YES;
//}
//
//- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
//
// if (editingStyle == UITableViewCellEditingStyleDelete) {
// [_array removeObjectAtIndex:indexPath.row];
// [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
//
// }
// else if (editingStyle == UITableViewCellEditingStyleInsert) {
// // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
// }
//}
//- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
//{
// return @"刪除";
//}
@end
在定制的UITableViewCell中催跪,如果需要對cell中的控件添加事件響應锁蠕,就要想辦法把cell的indexPath傳遞給響應函數(shù),在此總結(jié)了比較常用的代理方法懊蒸,希望對大家有幫助荣倾。
效果圖如下
cell的高度返回
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
return cell.frame.size.height;
加好約束后,然后告訴tableView自己去適應高度就可以了骑丸。有兩種寫法:
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 100;
但是如果我們用了自動計算高度的方法舌仍,又調(diào)用了tableView的reloadData方法(例如我們的數(shù)據(jù)有分頁的時候妒貌,加載完下一頁的數(shù)據(jù)后會去刷新tableView)。這時候就會出現(xiàn)問題铸豁,點擊狀態(tài)欄就有幾率不能精確滾動到頂部了:
解決這個問題的辦法是去緩存cell的高度灌曙,代碼如下:
@property (nonatomic, strong) NSMutableDictionary *heightAtIndexPath;//緩存高度所用字典
#pragma mark - UITableViewDelegate
-(CGFloat)tableView:(UITableView *)tableViewestimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *height = [self.heightAtIndexPathobjectForKey:indexPath];
if(height)
{
return height.floatValue;
}
else
{
return 100;
}
}
- (void)tableView:(UITableView *)tableViewwillDisplayCell:(UITableViewCell *)cellforRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *height = @(cell.frame.size.height);
[self.heightAtIndexPathsetObject:heightforKey:indexPath];
}
解釋一下,就是用一個字典做容器节芥,在cell將要顯示的時候在字典中保存這行cell的高度在刺。然后在調(diào)用estimatedHeightForRowAtIndexPath方法時,先去字典查看有沒有緩存高度头镊,有就返回蚣驼,沒有就返回一個大概高度。
滾到最后一行
[self.tableView scrollToRow:[_recordCollection count] - 1 inSection:0 atScrollPosition:UITableViewScrollPositionBottom animated:YES];
獲取當前cell
NSIndexPath *indexpath=[NSIndexPath indexPathForRow:0 inSection:0];
AddFriendsDefaultCell * cell = [self.tableView cellForRowAtIndexPath:indexpath];
ios - 原生骨架屏相艇,網(wǎng)絡加載過渡動畫的封裝https://www.tuicool.com/articles/eMnmU3B
優(yōu)化點1:cellForRowAtIndexPath
主要思路是減少cellForRowAtIndexPath 方法中的運算量颖杏,從以下方面檢查
1.1 加載圖片時,做異步處理坛芽,加載完成后再單獨更新cell留储,不要用reloadData刷新數(shù)據(jù)。
1.2 圖片有變換時咙轩,提前調(diào)整圖片尺寸获讳,并做緩存,刷新時直接取緩存圖片臭墨。
1.3 優(yōu)先使用CALayer繪制Cell赔嚎,避免繼承UITableViewCell,覆蓋drawRect胧弛,因為cell除了contentView外尤误,還有其他視圖,會導致疊加運算结缚。
1.4 復雜數(shù)據(jù)提前計算并緩存损晤。
優(yōu)化點2:heightForRowAtIndexPath
主要思路是減少高度的計算時間,有以下方法:
2.1 如果都是固定cell高度红竭,不要顯式實現(xiàn)代理 heightForRowAtIndexPath尤勋,使用 rowHeight屬性設置固定值。
2.2 非固定高度茵宪,提前計算并緩存最冰,刷新時直接取緩存高度值。
2.3 總是通過estimatedHeightForRowAtIndexPath 返回估計高度稀火,避免非顯示cell請求高度暖哨。