【IOS開發(fā)基礎(chǔ)系列】Table View開發(fā)專題

1 TableView編程指南學(xué)習(xí)筆記

1.1 At a Glance

? ? A table view is an instance of theUITableView class in one of two basic styles, plain or grouped. A plain table view is an unbroken list; a grouped table view has visually distinct sections. A table view has a data source and might have a delegate. The data source object provides the data for populating the sections and rows of the table view. The delegate object customizes its appearance and behavior.

1.2 Table Views Draw Their Rows Using Cells

??? A table view draws its visible rows using cells—that is, UITableViewCell objects. Cells are views that can display text, images, or other kinds of content. They can have background views for both normal and selected states. Cells can also have accessory views, which function as controls for selecting or setting an option.

??? The UIKit framework defines four standard cell styles, each with its own layout of the three default content elements: main label, detail label, and image. You may also create your own custom cells to acquire a distinctive style for your app’s table views.

? ? When you configure the attributes of a table view in the storyboard editor, you choose between two types of cell content: static cells or dynamic prototypes.

????● Static cells. Use static cells to design a table with a fixed number of rows, each with its own layout. Use static cells when you know what the table looks like at design time, regardless of the specific information it displays.

????● Dynamic prototypes. Use dynamic prototypes to design one cell and then use it as the template for other cells in the table. Use a dynamic prototype when multiple cells in a table should use the same layout to display information. Dynamic prototype content is managed by the data source at runtime, with an arbitrary number of cells.


Related Chapters: Table View Styles and Accessory Views (page 12), A Closer Look at Table View Cells (page 55)


2 UITableViewCell

2.1 UITableViewCellStyle

????????iPhone提供了4種基本的表格視圖單元格,在SDK 3.0 之后,每個單元格都有3個屬性textLabel,detailTextLabel和imageView。

????????下面一一介紹這4種基本格式:

????1、UITableViewCellStyleDefault

????????該格式提供了一個簡單的左對齊的文本標簽textLabel和一個可選的圖像imageView。如果顯示圖像,那么圖像將在最左邊。這種格式雖然可以設(shè)置detailTextLabel,但是不會顯示該標簽。

????2、UITableViewCellStyleSubtitle

????????該格式與前一種相比,增加了對detailTextLabel的支持,該標簽將會顯示在textLabel標簽的下面,字體相對較小。

????3、UITableViewCellStyleValue1

????????該格式居左顯示textLabel,居右顯示detailTextLabel,且字體較小。

????4、UITableViewCellStyleValue2

????????該格式居左現(xiàn)實一個小型藍色主標簽textLabel,在其右邊顯示一個小型黑色副標題詳細標簽detailTextLabel。該格式不支持圖像。


2.2 使用技巧

2.2.1 UITableViewCell去掉點擊效果

????????相當于Android中的ListView的selector設(shè)置成空/透明的:

????1.XIB設(shè)置

????????上圖中的Selection設(shè)置成空。

????2.代碼

UITableViewCell *cell;

cell.selectionStyle = UITableViewCellSelectionStyleNone;


2.2.2 去掉分隔線

cityTableView.separatorStyle = UITableViewCellSeparatorStyleNone;


2.2.3 UITableview最后一行顯示不全

????????tableview的高度減去tabbar的高度就好了。

????float screenHeight = [[UIScreen mainScreen] applicationFrame].size.height;

??? float scale = [[UIScreen mainScreen] scale];

??? float statusHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;

??? float navHeight = self.navigationController.view.frame.size.height;

??? float navBarHeight = self.navigationController.navigationBar.frame.size.height;

??? float tabBarHeight = self.navigationController.tabBarController.tabBar.frame.size.height;

??? float toolBarHeight = self.navigationController.toolbar.frame.size.height;

??? float contentViewHeight = navHeight - statusHeight - navBarHeight - tabBarHeight;


??? LOGDEBUG([NSString stringWithFormat: @"screenHeight:%f, navH:%f, navBarH:%f, tabBarH:%f, toolBarH:%f, contentViewHeight:%f", screenHeight, navHeight, navBarHeight, tabBarHeight, toolBarHeight, contentViewHeight]);


2.2.4 左滑刪除實現(xiàn)

????????通過上面兩步就實現(xiàn)了數(shù)據(jù)展示工作,接下就實現(xiàn)關(guān)鍵的數(shù)據(jù)刪除了。

-?(BOOL) tableView: (UITableView?*)tableView?canEditRowAtIndexPath: (NSIndexPath?*)indexPath?{

????return?YES;

}

-?(void) tableView: (UITableView?*)tableView?commitEditingStyle:(UITableViewCellEditingStyle) editingStyle?forRowAtIndexPath: (NSIndexPath?*)indexPath?{

?????if(editingStyle?==?UITableViewCellEditingStyleDelete)?{

????????[dataArray?removeObjectAtIndex: indexPath.row];

?????????//?Delete?the?row?from?the?data?source.

????????[testTableView?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.

????}

}

?啟用上面兩個代理,并增加數(shù)據(jù)刪除操作:

[dataArray removeObjectAtIndex: indexPath.row];

?在一條數(shù)據(jù)上向右劃動一下.


2.2.5 IOS7以后UItableview默認頂部有空白

解決方法:

????????在當前VC中設(shè)置:

? ? ? ? self.edgesForExtendedLayout = UIRectEdgeNone;


2.2.6 自定義UITableViewCell分割線

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

??? UITableViewCell*cell = [tableView? dequeueReusableCellWithIdentifier: kTableCellIdentifier];


??? if(cell == nil) {

??????? cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: kTableCellIdentifier];

??? }


??? if (indexPath.section == 0) {

??????? if (indexPath.row == 0) {

??????????? UIView *lineV1 = [[UIView alloc] initWithFrame: CGRectMake(0, 0, cell.frame.size.width, 0.5)];

??????????? lineV1.backgroundColor = [UIColor colorWithRed:200.0 / 255.0 green:200.0 / 255.0 blue:200.0 / 255.0 alpha:1.0];

??????????? [cell addSubview: lineV1];

??????????? [cell addSubview: _lNameTextField];

??????????? [self relayoutLoginNameTextField];

??????? }

??????? else if (indexPath.row == 1)

??????? {

??????????? [cell addSubview: _lVerifyCodeGetButton];


??????????? UIView *lineV1 = [[UIView alloc] initWithFrame: CGRectMake(0, kLoginNameTextFieldHeight - 0.5, cell.frame.size.width, 0.5)];

??????????? lineV1.backgroundColor = [UIColor colorWithRed:200.0 / 255.0 green:200.0 / 255.0 blue:200.0 / 255.0 alpha:1.0];

??????????? [cell addSubview: lineV1];

??????? }

??? }


??? return cell;

}


2.2.7 自定義Section樣式

// 設(shè)置section的高度

- (CGFloat) tableView: (UITableView *)tableView heightForHeaderInSection: (NSInteger)section{

??? return 20;

}


- (UIView *) tableView: (UITableView *)tableView viewForHeaderInSection: (NSInteger)section {

??? UIView *sectionView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, tableView.bounds.size.width, 20)];

??? [sectionView setBackgroundColor: [UIColor colorWithRed: 240.0/255 green: 243.0/255 blue: 245.0/255 alpha: 1.0]];

??? return sectionView;

}


2.2.8 去除UITableView多余分割線

????????看了好多東西,覺得隱藏多余的分割線,基本兩個各思路,一個是通過代碼,一個是代碼配合背景圖片。

????????第一種比較常見,在網(wǎng)上到處都是,我這也是抄別人的。主要就是說自己定義一個view,弄成透明的,然后蓋在TableView的上部和下部,這樣就“隱藏”了。

-?(void) setExtraCellLineHidden:?(UITableView?*)tableView{

????UIView?*view = [[UIView?alloc] init];

????view.backgroundColor =?[UIColor?clearColor];

????[tableView?setTableFooterView: view];

????[tableView?setTableHeaderView: view];

????[view?release];

}


這個函數(shù)調(diào)用

- (void) viewDidLoad

{

????[super?viewDidLoad];

????// Do any additional setup after loading the view.

????[self?setExtraCellLineHidden: _detailTableView];

}

????好像這還不夠,如果TableView沒有數(shù)據(jù)時,會出問題,所以要在

-(NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger)section

????判斷dataSouce的數(shù)據(jù)個數(shù)

????如果為零可以將_detailTableView.separatorStyle = UITableViewCellSeparatorStyleNone

????然后在大于零時將其設(shè)置為

_detailTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine

????第二種就是比較非主流的一種,給TableView設(shè)置沒有分割線,然后給每個cell添加背景圖片,圖片上畫一個線,這樣,貌似還不用判斷數(shù)據(jù)為空的情況。

????第三種: 當背景橫向為 有規(guī)律的 色變的 時候可以取背景圖片 產(chǎn)生出一個color ok

?fuelsTabelView.separatorColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"line2.png"]];?


2.2.9 跟隨滾動的頭部視圖

????????即把headerView放在整個TableView的頭部視圖中

??? _headerView = [[HJMainPageHeaderView alloc] initWithPersonalDataModel: _mainPageUserVM andFrame: CGRectMake(0, 0, w, 90)];

??? _headerView.layer.borderColor = [kHJBorderColor CGColor];

??? _headerView.layer.borderWidth = 0.5;

??? _postTableView = [[UITableView alloc]initWithFrame: CGRectMake(0, 0, w, h) style: UITableViewStylePlain];

??? [_postTableView registerClass: [HJPostInfoCell class] forCellReuseIdentifier: kHJPostInfoCellIdentifier];

??? self.postTableView.tableHeaderView = _headerView;


2.2.10 不跟隨滾動的頭部視圖

????即把headerView放在某個Section的頭部視圖中。

??? _headerView = [[HJMainPageHeaderView alloc] initWithPersonalDataModel: _mainPageUserVM andFrame: CGRectMake(0, 0, w, 90)];

??? _headerView.layer.borderColor = [kHJBorderColor CGColor];

??? _headerView.layer.borderWidth = 0.5;


- (CGFloat) tableView: (UITableView *) tableView heightForHeaderInSection: (NSInteger)section

{

??? return _headerView.frame.size.height;

}


- (UIView *) tableView: (UITableView *)tableView viewForHeaderInSection: (NSInteger)section

{

??? return _headerView;

}


2.2.11 UITableViewCell分割線左邊部分缺少一些

- (void) viewDidLayoutSubviews{

????if([self.mytableview respondsToSelector: @selector(setSeparatorInset:)]) {

????????[self.mytableview setSeparatorInset: UIEdgeInsetsZero];

????}

????if([self.mytableview respondsToSelector: @selector(setLayoutMargins:)])??{

????????[self.mytableview setLayoutMargins: UIEdgeInsetsZero];

????}

}


- (void) tableView: (UITableView*)tableView willDisplayCell: (UITableViewCell *) cellforRowAtIndexPath: (NSIndexPath *)indexPath{

????if([cell respondsToSelector: @selector(setLayoutMargins:)]) {

????????[cell setLayoutMargins: UIEdgeInsetsZero];

????}

????if([cell respondsToSelector: @selector(setSeparatorInset:)]){

????????[cell setSeparatorInset: UIEdgeInsetsZero];

????}

}


2.2.12 禁止section的懸浮問題

//處理uitableview section的懸浮問題,禁止section懸浮停留

- (void) scrollViewDidScroll: (UIScrollView*)scrollView {

??? if ([super respondsToSelector: @selector(scrollViewDidScroll:)]) {

??????? [super scrollViewDidScroll: scrollView];

??? }


??? CGFloat sectionHeaderHeight = 50;

??? if (scrollView.contentOffset.y <= sectionHeaderHeight && scrollView.contentOffset.y >= 0) {

??????? scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);

??? }

????else if (scrollView.contentOffset.y >= sectionHeaderHeight) {

??????? scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);

??? }

}

2.2.13 為什么iphone6下手動打印UITableViewCell的寬度是320高度是44

????????因為在iOS5的時候, 默認Cell就是320寬(那陣屏幕就是那么寬,然后高度是44) 現(xiàn)在是在layoutSubViews 重新繪制這個cell的寬度和高度,所以才是屏幕上的寬度。

????解決方案:

? ? ? ? ? 盡量將子視圖的layout操作放到layoutSubviews方法中;另外,可以在cell初始化時手動設(shè)置寬度:

- (instancetype) initWithStyle: (UITableViewCellStyle)style reuseIdentifier: (NSString*)reuseIdentifier {

??? if (self = [super initWithStyle: style reuseIdentifier: reuseIdentifier]) {

???????self.selectionStyle = UITableViewCellSelectionStyleNone;

???????CGRect frame = self.frame;

??????? frame.size.width = SCREEN_BOUNDS.size.width;

??????? self.frame = frame;

??? }


??? return self;

}


2.2.14 實現(xiàn)UITableViewCell展開/收縮效果

http://blog.sina.com.cn/s/blog_6b8c3d7a0101apmd.html

當初始化UITableView后,代理回調(diào)順序如下

?1: //返回cell個數(shù)

- (NSInteger) tableView: (UITableView *)tableView numberOfRowsInSection: (NSInteger)section

?2: //返回每行的高度

- (CGFloat)tableView: (UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath

?3: //請求數(shù)據(jù)元代理為tableView插入需要的cell

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

?4: //監(jiān)聽點擊的cell

- (void) tableView: (UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath


??????需要聲明一個全局BOOL變量isOpen,記錄當前cell的狀態(tài),聲明一個NSInterger類型selectedIndex,記錄選擇的cell的row。

??????在heightForRowAtIndexPath代理里面實現(xiàn)。

????//選中狀態(tài)返回的高度

???if (indexPath.row == selectedIndex.row && selectedIndex != nil ) {

???????if (isOpen == YES) {

??????????//cell上的label高度自適應(yīng)

???????????CGSize size = [textStr sizeWithFont: [UIFont systemFontOfSize: 14] constrainedToSize: CGSizeMake(290, 1000) lineBreakMode: NSLineBreakByWordWrapping];

???????????CGFloat f = size.height;


???????????if (indexPath.row == [self.dataArr count]-1){

???????????????return 153.8+(f - 21);

???????????}


???????????return 155+(f - 21);

???????}else{

???????????return 67;

???????}

???}

????????同樣在- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath里實現(xiàn)一樣的條件。

???if (indexPath.row == selectedIndex.row && selectedIndex != nil) {

???????//如果是展開

???????if (isOpen == YES) {

???????????//xxxxxx

????????}else{

???????????//收起

?????????}

??????????//不是自身

???} else {

? ?}


????????當點擊時候在

- (void) tableView: (UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath*)indexPath{

????//將索引加到數(shù)組中

? ? NSArray *indexPaths = [NSArray arrayWithObject: indexPath];

? ? //判斷選中不同row狀態(tài)時候

? ? if (self.selectedIndex != nil && indexPath.row== selectedIndex.row) {

???????isOpen = !isOpen;

? ? }else if (self.selectedIndex != nil &&indexPath.row != selectedIndex.row) {

???????indexPaths = [NSArray arrayWithObjects: indexPath, selectedIndex, nil];

???????isOpen = YES;

????}


? ? //記下選中的索引

? ? self.selectedIndex = indexPath;

? ? //刷新

? ? [tableView reloadRowsAtIndexPaths: indexPaths withRowAnimation: UITableViewRowAnimationFade];

}


????經(jīng)過不斷調(diào)試,終于實現(xiàn)了點擊任意一個cell展開收縮效果。


2.2.15 AccessoryDisclosureIndicator按鈕旋轉(zhuǎn)效果實現(xiàn)

[ios]如何旋轉(zhuǎn)UITableViewCellAccessoryDisclosureIndicator?

http://www.itstrike.cn/Question/64f895e0-6e7f-4ea0-b8c3-8c96f989ce30.html

2.2.15.1 方案一CGAffineTransform

UIButton *button = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];

下一步,旋轉(zhuǎn)90度按鈕:

CGAffineTransformrotationTransform = CGAffineTransformIdentity;

rotationTransform = CGAffineTransformRotate(rotationTransform, DegreesToRadians(90));

button.transform = rotationTransform;

最后,作為accessoryView使用按鈕:

cell.accessoryView = button;


2.2.15.2 方案二UIImageOrientation

???????????if (_isShowServiceSupportView) {

??????????????? orientation = UIImageOrientationRight;

??????????????? [cell addSubview: self.serviceSupportWebView];

???????????}

???????????else

???????????{

??????????????? [self.serviceSupportWebView removeFromSuperview];

???????????}


???????????UIImage *orientationImg = [self changeImageOrientation: orientation];

???????????UIButton *btn = [[UIButton alloc] init];

???????????btn.frame = CGRectMake(SCREEN_BOUNDS.size.width - 24, 14, 16, 16);

???????????[btn setImage: orientationImg forState: UIControlStateNormal];

??????????? [cell addSubview: btn];


#pragma mark - 圖片旋轉(zhuǎn)

- (UIImage*) changeImageOrientation: (UIImageOrientation)orientation

{

??? UIImage *orientationImg = [UIImage imageNamed: @"disclosureIndicator"];

??? orientationImg = [UIImage imageWithCGImage: orientationImg.CGImage scale: [UIScreen mainScreen].scale orientation: orientation];


??? return orientationImg;

}


2.3 集成第三方效果

2.3.1 上提加載效果

iOS下拉刷新上拉加載更多EGOTableViewPullRefresh類庫

http://blog.csdn.net/duxinfeng2010/article/details/9007311

https://github.com/emreberge/EGOTableViewPullRefresh


2.3.2 下拉刷新效果

iOS開發(fā)-ios7下拉刷新,上提加載快速集成

http://blog.csdn.net/fkuewfnh/article/details/36000129


2.4 性能優(yōu)化

2.4.1 快速滑動性能優(yōu)化方法

2.4.1.1 使用不透明視圖

? ? ? ?不透明的視圖可以極大地提高渲染的速度。因此如非必要,可以將tablecell及其子視圖的opaque屬性設(shè)為YES(默認值)。其中的特例包括背景色,它的alpha值應(yīng)該為1(例如不要使用clearColor);圖像的alpha值也應(yīng)該為1,或者在畫圖時設(shè)為不透明。

2.4.1.2 不要重復(fù)創(chuàng)建不必要的table cell

? ? ? ? 前面說了,UITableView只需要一屏幕的UITableViewCell對象即可。因此在cell不可見時,可以將其緩存起來,而在需要時繼續(xù)使用它即可。而UITableView也提供了這種機制,只需要簡單地設(shè)置一個identifier即可:

static NSString *CellIdentifier = @"xxx";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];

if (cell == nil) {

? ? cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier] autorelease];

}

????????值得一提的是,cell被重用時,它內(nèi)部繪制的內(nèi)容并不會被自動清除,因此你可能需要調(diào)用setNeedsDisplayInRect:或setNeedsDisplay方法。而且必須在父類TableCell的直接繼續(xù)類中調(diào)用才起作用


2.4.1.3 減少視圖的數(shù)目。

? ? ? ?UITableViewCell包含了textLabel、detailTextLabel和imageView等view,而你還可以自定義一些視圖放在它的contentView里。然而view是很大的對象,創(chuàng)建它會消耗較多資源,并且也影響渲染的性能。如果你的table cell包含圖片,且數(shù)目較多,使用默認的UITableViewCell會非常影響性能。奇怪的是,使用自定義的view,而非預(yù)定義的view,明顯會快些。當然,最佳的解決辦法還是繼承UITableViewCell,并在其drawRect:中自行繪制:

- (void) drawRect: (CGRect)rect {

? ? if (image) {

? ? ? ? [image drawAtPoint: imagePoint];

? ? ? ? self.image =nil;

? ? } else {

? ? ? ? [placeHolder drawAtPoint: imagePoint];

? ? }


? ? [text drawInRect: textRect withFont: font lineBreakMode: UILineBreakModeTailTruncation];

}

? ? ? 不過這樣一來,你會發(fā)現(xiàn)選中一行后,這個cell就變藍了,其中的內(nèi)容就被擋住了。最簡單的方法就是將cell的selectionStyle屬性設(shè)為UITableViewCellSelectionStyleNone,這樣就不會被高亮了。此外還可以創(chuàng)建CALayer,將內(nèi)容繪制到layer上,然后對cell的contentView.layer調(diào)用addSublayer:方法。這個例子中,layer并不會顯著影響性能,但如果layer透明,或者有圓角、變形等效果,就會影響到繪制速度了。解決辦法可參見后面的預(yù)渲染圖像。

2.4.1.4 不要做多余的繪制工作。

? ? ?在實現(xiàn)drawRect:的時候,它的rect參數(shù)就是需要繪制的區(qū)域,這個區(qū)域之外的不需要進行繪制。例如上例中,就可以用CGRectIntersectsRect、CGRectIntersection或CGRectContainsRect判斷是否需要繪制image和text,然后再調(diào)用繪制方法。

2.4.1.5 預(yù)渲染圖像。

????????你會發(fā)現(xiàn)即使做到了上述幾點,當新的圖像出現(xiàn)時,仍然會有短暫的停頓現(xiàn)象。解決的辦法就是在bitmap context里先將其畫一遍,導(dǎo)出成UIImage對象,然后再繪制到屏幕,詳細做法可見《利用預(yù)渲染加速iOS設(shè)備的圖像顯示》。


IOS7.x下UIGraphicsGetImageFromCurrentImageContext引發(fā)內(nèi)存暴漲,導(dǎo)致應(yīng)用被結(jié)束掉

http://blog.163.com/l1_jun/blog/static/1438638820155593641529/


解決方案:

? ? ? ? 因為是修改別人的代碼,優(yōu)化時無意中解決了此問題,原來的調(diào)用方法是在A函數(shù)中調(diào)用UIGraphicsGetImageFromCurrentImageContext(在C函數(shù)中)生成UIImage,然后傳遞給B函數(shù)去處理,這樣內(nèi)存會暴漲?,F(xiàn)在將C函數(shù)調(diào)用生成UIImage放到B函數(shù)中生成并使用,這樣就能得到及時釋放。


2.4.1.6 不要阻塞主線程。

? ? ? ?做到前幾點后,你的table view滾動時應(yīng)該足夠流暢了,不過你仍可能讓用戶感到不爽。常見的現(xiàn)象就是在更新數(shù)據(jù)時,整個界面卡住不動,完全不響應(yīng)用戶請求。出現(xiàn)這種現(xiàn)象的原因就是主線程執(zhí)行了耗時很長的函數(shù)或方法,在其執(zhí)行完畢前,無法繪制屏幕和響應(yīng)用戶請求。其中最常見的就是網(wǎng)絡(luò)請求了,它通常都需要花費數(shù)秒的時間,而你不應(yīng)該讓用戶等待那么久。解決辦法就是使用多線程,讓子線程去執(zhí)行這些函數(shù)或方法。這里面還有一個學(xué)問,當下載線程數(shù)超過2時,會顯著影響主線程的性能。因此在使用ASIHTTPRequest時,可以用一個NSOperationQueue來維護下載請求,并將其maxConcurrentOperationCount設(shè)為2。而NSURLRequest則可以配合GCD來實現(xiàn),或者使用NSURLConnection的setDelegateQueue:方法。當然,在不需要響應(yīng)用戶請求時,也可以增加下載線程數(shù),以加快下載速度:

- (void) scrollViewDidEndDragging: (UIScrollView*) scrollView willDecelerate: (BOOL)decelerate {

? ? if (!decelerate) {

? ? ? ?queue.maxConcurrentOperationCount = 5;

? ? }

}

- (void) scrollViewDidEndDecelerating: (UIScrollView *)scrollView {

? ? queue.maxConcurrentOperationCount = 5;

}

- (void) scrollViewWillBeginDragging: (UIScrollView *)scrollView {

? ? queue.maxConcurrentOperationCount = 2;

}

????????此外,自動載入更新數(shù)據(jù)對用戶來說也很友好,這減少了用戶等待下載的時間。例如每次載入50條信息,那就可以在滾動到倒數(shù)第10條以內(nèi)時,加載更多信息:

- (void) tableView: (UITableView *)tableView willDisplayCell: (UITableViewCell *)cell forRowAtIndexPath: (NSIndexPath *)indexPath {

? ? if (count - indexPath.row <10 && !updating) {

? ? ? ? updating = YES;

? ? ? ? [self update];

? ? }

}

// update方法獲取到結(jié)果后,設(shè)置updating為NO

還有一點要注意的就是當圖片下載完成后,如果cell是可見的,還需要更新圖像:

NSArray *indexPaths = [self.tableView indexPathsForVisibleRows];

for (NSIndexPath *visibleIndexPath in indexPaths) {

? ? if (indexPath == visibleIndexPath) {

? ? ? ? MyTableViewCell *cell = (MyTableViewCell *)[self.tableView cellForRowAtIndexPath: indexPath];

? ? ? ? cell.image = image;

? ? ? ? [cell setNeedsDisplayInRect: imageRect];

? ? ? ? break;

? ? }

}

? ? ? ? //也可不遍歷,直接與頭尾相比較,看是否在中間即可。

????????最后還是前面所說過的insertRowsAtIndexPaths:withRowAnimation:方法,插入新行需要在主線程執(zhí)行,而一次插入很多行的話(例如50行),會長時間阻塞主線程。而換成reloadData方法的話,瞬間就處理完了。


3 參考鏈接

(good)優(yōu)化UITableView性能

http://www.keakon.net/2011/08/03/優(yōu)化UITableView性能


利用預(yù)渲染加速iOS設(shè)備的圖像顯示

http://www.keakon.net/2011/07/26/利用預(yù)渲染加速iOS設(shè)備的圖像顯示


優(yōu)化UITableView滾動性能

http://blog.csdn.net/chaoyuan899/article/details/25467617


(good)復(fù)雜TableView在iOS上的性能優(yōu)化

http://www.2cto.com/kf/201312/262041.html


(ok)提升UITableView性能-復(fù)雜頁面的優(yōu)化

http://www.imooc.com/wenda/detail/249535


關(guān)于UITableView的性能優(yōu)化(歷上最全面的優(yōu)化分析)

http://bbs.51cto.com/thread-1123666-1.html


(ok)詳細整理:UITableView優(yōu)化技巧

http://www.cocoachina.com/ios/20150602/11968.html


iOS開發(fā)UI篇—UITableviewcell的性能優(yōu)化和緩存機制

http://www.cnblogs.com/wendingding/p/3756257.html


優(yōu)化UITableView性能

http://www.cnblogs.com/pengyingh/articles/2354714.html


(good)【原/轉(zhuǎn)】UITableview性能優(yōu)化總結(jié)

http://www.cnblogs.com/wengzilin/p/4288027.html


iOS保持界面流暢的技巧

http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/


UIImage縮放

http://286725277.blog.163.com/blog/static/12672858620113823553731/


UITableView劃動刪除的實現(xiàn)

http://rainbird.blog.51cto.com/211214/634587/


自定義UITableViewCell:Cell高度、分割線、間距等

http://blog.csdn.net/tt5267621/article/details/39584513


UITableView設(shè)置Section間距

http://blog.aizhet.com/Apple/6977.html


去除UITableView多余分割線

http://blog.csdn.net/wohenjinzhang/article/details/18262565


UITableVIew滾動流暢性優(yōu)化

http://blog.csdn.net/enuola/article/details/41942963


uitableview處理section的不懸浮,禁止section停留的方法

http://www.wahenzan.com/a/mdev/ios/2015/0105/1412.html


實現(xiàn)UITableViewCell展開/收縮效果

http://blog.sina.com.cn/s/blog_6b8c3d7a0101apmd.html

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

相關(guān)閱讀更多精彩內(nèi)容

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