Optimization techniques for IOS---uitableview

Source: Internet
Author: User

In iOS development, UITableView is the most commonly used complex control. It is not difficult to use, but it is not easy to use it well. Need to consider the background data design, Tableviewcell design and optimization, as well as tableview efficiency and so on.
This article mainly introduces the common optimization techniques of uitableview, the main reference blog:
Vvebotableviewdemo.

The main ideas of TableView optimization are:
1. Asynchronously renders the content to the picture.
2. Load content on demand according to sliding speed.
3. Rewrite processing network picture loading.
4. Cache all cacheable, use space to change time. Reusing a cell

The reuse mechanism of UITableViewCell is one of the most common and most effective optimization methods.
Using Dequeuereusablecellwithidentifier to reuse a cell with the same layout, you can also use a cell directly by Cellforrowatindexpath. Such as

-(UITableViewCell *) TableView: (UITableView *) TableView Cellforrowatindexpath: (Nsindexpath *) indexPath{
    Weibotableviewcell *cell = [TableView dequeuereusablecellwithidentifier:@ "Cell"];
    if (cell = = nil) {
        cell = [[Weibotableviewcell alloc] Initwithstyle:uitableviewcellstyledefault reuseidentifier:@ " Cell "];
    }
    [Self Drawcell:cell withindexpath:indexpath];
    return cell;
]

Because Cellforrowatindexpath method calls are very frequent, initialized, scrolled up and down, and refreshes are invoked. So it's better to declare the cell's label as a static variable.

static NSString *cellidentifier = @ "Tracks";
avoid the redistribution of the cell

Cell layout padding and other operations are time-consuming, and can generally be laid out at the time of creation. If the cell can be placed in a separate class Weibotableviewcell, rewrite its Initwithstyle method, in which the cell layout settings are completed.
After creating the cell, call Drawcell to populate it with the contents of the cell, separate the layout and fill, and try to prepare the data to be populated in advance.

-(void) Drawcell: (Weibotableviewcell *) cell Withindexpath: (Nsindexpath *) Indexpath {nsdictionary *data
    = [datas ObjectAtIndex:indexPath.row]; Cache the contents of the cell in advance
    Cell.selectionstyle = Uitableviewcellselectionstylenone;
    [Cell clear];
    Cell.data = data;
    if (needloadarr.count>0 && [Needloadarr indexofobject:indexpath]==nsnotfound) {
        [cell clear];
        return;
    }
    if (scrolltotoping) {return
        ;
    }
    [Cell draw];
}
calculate and cache cell attributes and contents in advance

Because UITableView inherits from Uiscrollview, its layout mainly displays as plain and grouped two kinds of styles. The contentsize and the position of each cell must be determined before it is put in. Such as:

To display 100 cell, the current screen can only display 5. When reload, the Heightforrowatindexpath method is called 100 times, and then the Cellforrowatindexpath method is called 5 times. When you scroll the screen, the Heightforrowatindexpath and Cellforrowatindexpath methods are invoked whenever the cell enters the screen. Cellforrowatindexpath and Heightforrowatindexpath are the most frequently invoked methods, and they are called as few as possible.

Cell padding is separated from the calculation layout.

Cellforrowatindexpath only fills the cell,
The Heightforrowatindexpath is responsible for calculating the height and caching the layout of the height to the data source.

For rich text attributedstring and other cell contents, can be created in advance, data caching, and then need to directly fill the cell.

Use Estimatedrowheight to estimate heights and prevent wasting time calculating the cell outside the screen, such as

Self.tableView.estimatedRowHeight = 88.

Asynchronous loading of cell contents
such as the content of the Web asynchronously loaded, the picture with Sdwebimage cache, the network request results cache. Drawing of Subview

If you have several different styles of cell, you can specify a different reuse identifier for each cell. Then use Dequeue each time you use it. Such as:

Less use AddView to add view to cell dynamically, reduce the number of create Subview as the cell is roughly the same layout, you can define a cell, add it at initialization, and control the display of the content by hidden. As far as possible, cache subview. Careful use of clearcolor, multiple view layer overlay rendering will consume more time, so try not to use or less transparent layer, because the system will be transparent layer and the view of the following mix to calculate color, rendering speed. So, careful use of clearcolor. Try to set the opaque to Yes, try to set the Subview opaque to Yes, to avoid the GPU to draw the contents of the cell. Avoid useless calayer rendering effects. When you need to draw a shadow, increase the efficiency by specifying the path of the shadow. DrawRect method for overloaded Subview if you need more than one small element in the process of customizing a cell, it's a good idea to draw directly on multiple items to display, rather than adding multiple subview. local update for UITableView

We often use [Self.tableview reloaddata] to update the data in TableView. If you are only updating a section, you can use Reloadsections to make local updates

Self.tableview reloadrowsatindexpaths:<# (Nsarray *) #> withrowanimation:<# (UITableViewRowAnimation) #> 

[Self.tableview reloadsections:[nsindexset indexsetwithindex:0] Withrowanimation:uitableviewrowanimationnone ];
asynchronous drawing of TableView

For complex TableView interfaces, you can consider asynchronous rendering. Separate business logic from UI drawing with Dispatch_async and Dispatch_sync. Such as:

Asynchronous Drawing Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{cgrect rect = [_data[@] fra
        Me "] cgrectvalue];
        Uigraphicsbeginimagecontextwithoptions (rect.size, YES, 0);
Cgcontextref context = Uigraphicsgetcurrentcontext ();
        The background of the entire content [[Uicolor colorwithred:250/255.0 green:250/255.0 blue:250/255.0 alpha:1] set];
Cgcontextfillrect (context, rect); The background of the forwarded content if ([_data valueforkey:@ "Subdata"]) {[[Uicolor colorwithred:243/255.0 green:243/255.0 Blue:
            243/255.0 Alpha:1] set];
            CGRect subFrame = [_data[@ "Subdata"][@ "frame"] cgrectvalue];
            Cgcontextfillrect (context, subFrame);
            [[Uicolor colorwithred:200/255.0 green:200/255.0 blue:200/255.0 alpha:1] set];
        Cgcontextfillrect (context, CGRectMake (0, SUBFRAME.ORIGIN.Y, Rect.size.width,. 5));
            } {//name float LEFTX = Size_gap_left+size_avatar+size_gap_big;
          float x = LEFTX;  Float y = (size_avatar-(size_font_name+size_font_subtitle+6))/2-2+size_gap_top+size_gap_small-5;
                             [_data[@ ' name '] drawincontext:context withposition:cgpointmake (x, y) andfont:fontwithsize (size_font_name)
                                Andtextcolor:[uicolor colorwithred:106/255.0 green:140/255.0 blue:181/255.0 alpha:1]
    AndHeight:rect.size.height];
            Time + Equipment Y + + size_font_name+5;
            float FromX = LEFTX;
            float size = [UIScreen screenwidth]-leftx;
            NSString *from = [NSString stringwithformat:@ "%@%@", _data[@ "Time"], _data[@ "from"]];
                   [From Drawincontext:context Withposition:cgpointmake (FromX, y) andfont:fontwithsize (size_font_subtitle) Andtextcolor:[uicolor colorwithred:178/255.0 green:178/255.0 blue:178/255.0 alpha:1] AndHeight:rect
        . Size.Height Andwidth:size]; ///Return the drawn content as a picture, and tune the main thread to display uiimage *temp = UigraphicsgetimagefromcurrentimageconText ();
        Uigraphicsendimagecontext (); Dispatch_async (Dispatch_get_main_queue (), ^{if (flag==drawcolorflag) {postbgview.frame = Rec
                T
                Postbgview.image = nil;
            Postbgview.image = temp;
}//Content if it is a text mixed row, add view, draw with coretext [self drawText]; }}
the failure of Nstimer in cell

Nstimer is invalidated in UITableViewCell reuse, so do not add a timer to the cell. The timer does not trigger the time function when sliding tableview. Because they use a common runloop, the TableView slip blocks the timer's time function.
May consider:
1. Use a timer for text or other objects displayed in the cell.
2. Parallel implementation, mainly set the mode parameter:

nstimer* timer = [Nstimer timerwithtimeinterval:0.005 target:self selector: @selector (timerfiremethod:) userinfo:@ " Finishanimation "Repeats:yes];
    Nsrunloop *currentrunloop = [Nsrunloop currentrunloop];
    [Currentrunloop Addtimer:timer formode:nsrunloopcommonmodes];

Or

Timer = [Nstimer timerwithtimeinterval:5.0 target:self selector: @selector (sendheartbeat) Userinfo:nil Repeats:yes];
 [[Nsrunloop Mainrunloop] Addtimer:hearttimer Formode:nsdefaultrunloopmode];
Optimizing Touch Event Delivery

Set the userinteractionenabled of view that does not need to accept touch to 0. Custom Cell Drawing

Adding a large number of controls can result in a large resource overhead, and you might consider drawing drawrect directly.
This article is not yet clear how to achieve, so it is not detailed enough to be further supplemented. on-demand loading of cell

From the Uiscrollview point of view, the cell is loaded on demand, that is, scrolling quickly, only the cell within the target range is loaded.

if (needloadarr.count>0 && [Needloadarr indexofobject:indexpath]==nsnotfound) {
    [cell clear]; return;
}

For example, if the target row is more than the specified number of rows than the current row, specify only 3 rows before and after the target scrolling range.

-(void) scrollviewwillenddragging: (Uiscrollview *) ScrollView withvelocity: (cgpoint) Velocity targetcontentoffset: ( InOut cgpoint *) targetcontentoffset{Nsindexpath *ip = [self indexpathforrowatpoint:cgpointmake (0, TargetContentOffset
    ->y)];
    Nsindexpath *CIP = [[self indexpathsforvisiblerows] firstobject];
    Nsinteger Skipcount = 8; if (Labs (Cip.row-ip.row) >skipcount) {Nsarray *temp = [self indexpathsforrowsinrect:cgrectmake (0, Targetcontent
        Offset->y, Self.width, Self.height)];
        Nsmutablearray *arr = [Nsmutablearray arraywitharray:temp];
            if (velocity.y<0) {Nsindexpath *indexpath = [temp lastobject];
                if (indexpath.row+33) {[arr Addobject:[nsindexpath indexpathforrow:indexpath.row-3 insection:0]];
                [Arr Addobject:[nsindexpath indexpathforrow:indexpath.row-2 insection:0]];
            [Arr Addobject:[nsindexpath indexpathforrow:indexpath.row-1 insection:0]];
 }
        }       [Needloadarr Addobjectsfromarray:arr]; }
}
do not implement the useless delegate method

Use TableView to follow two protocols, and we just need to implement the required proxy methods. uitableviewdelegate

Mainly provide cell display and style control, cell selection, designated section of the end of the display, to help complete the cell sorting and deletion functions.

//_____________________________________________________________________________________________________________

__//This represents the display and behaviour of the cells. @protocol Uitableviewdelegate<nsobject, uiscrollviewdelegate> @optional/Display customization-(void) Tablevi
EW: (UITableView *) TableView Willdisplaycell: (UITableViewCell *) cell Forrowatindexpath: (Nsindexpath *) IndexPath; -(void) TableView: (UITableView *) TableView Willdisplayheaderview: (UIView *) View forsection: (nsinteger) Section NS_
Available_ios (6_0); -(void) TableView: (UITableView *) TableView Willdisplayfooterview: (UIView *) View forsection: (nsinteger) Section NS_
Available_ios (6_0); -(void) TableView: (UITableView *) TableView Didenddisplayingcell: (UITableViewCell *) cell Forrowatindexpath: (
nsindexpath*) Indexpath Ns_available_ios (6_0); -(void) TableView: (UITableView *) TableView Didenddisplayingheaderview: (UIView *) View forsection: (nsinteger) Section
Ns_available_ios (6_0); -(void) TableView: (UITableView *) tabLeview Didenddisplayingfooterview: (UIView *) View forsection: (nsinteger) Section ns_available_ios (6_0); Variable Height Support-(cgfloat) TableView: (UITableView *) TableView Heightforrowatindexpath: (Nsindexpath *)
Indexpath;
-(CGFloat) TableView: (UITableView *) TableView heightforheaderinsection: (nsinteger) Section;

-(CGFloat) TableView: (UITableView *) TableView heightforfooterinsection: (nsinteger) Section;
Use the Estimatedheight methods to quickly calcuate guessed values which would allow for fast load times of the table. If These methods are implemented, the ABOVE-TABLEVIEW:HEIGHTFORXXX calls'll be deferred until views are ready to be
displayed, so the expensive logic can be placed there. -(CGFloat) TableView: (UITableView *) TableView Estimatedheightforrowatindexpath: (Nsindexpath *) IndexPath NS_
Available_ios (7_0); -(CGFloat) TableView: (UITableView *) TableView estimatedheightforheaderinsection: (nsinteger) Section NS_AVAILABLE_
IOS (7_0); -(CGFloat) TableView: (UITableView *) TablevIew estimatedheightforfooterinsection: (nsinteger) Section ns_available_ios (7_0); Section Header & footer information. Views are preferred the title should you decide to provide both-(UIView *) TableView: (UITableView *) TableView Viewforhe   Aderinsection: (nsinteger) Section; Custom view for header. 'll is adjusted to default or specified header height-(UIView *) TableView: (UITableView *) TableView viewforfooterinsecti   On: (nsinteger) Section; Custom view for footer. 

Would be adjusted to default or specified footer height//Accessories (disclosures). -(Uitableviewcellaccessorytype) TableView: (UITableView *) TableView Accessorytypeforrowwithindexpath: (NSIndexPath *
) Indexpath Ns_deprecated_ios (2_0, 3_0);

-(void) TableView: (UITableView *) TableView Accessorybuttontappedforrowwithindexpath: (Nsindexpath *) IndexPath; 
Selection//-tableview:shouldhighlightrowatindexpath:is called when a touching comes down on a row. Returning NO to this message halts the selection process And does not cause the currently selected row to lose its selected look while the "touch" down. -(BOOL) TableView: (UITableView *) TableView Shouldhighlightrowatindexpath: (Nsindexpath *) Indexpath NS_AVAILABLE_IOS (
6_0); -(void) TableView: (UITableView *) TableView Didhighlightrowatindexpath: (Nsindexpath *) Indexpath NS_AVAILABLE_IOS (6_0
); -(void) TableView: (UITableView *) TableView Didunhighlightrowatindexpath: (Nsindexpath *) Indexpath NS_AVAILABLE_IOS (6

_0); Called before the user changes the selection.
Return a new Indexpath, or nil, to change the proposed selection.
-(Nsindexpath *) TableView: (UITableView *) TableView Willselectrowatindexpath: (Nsindexpath *) IndexPath; -(Nsindexpath *) TableView: (UITableView *) TableView Willdeselectrowatindexpath: (Nsindexpath *) IndexPath NS_AVAILABLE
_ios (3_0);
Called after the user changes the selection.
-(void) TableView: (UITableView *) TableView Didselectrowatindexpath: (Nsindexpath *) Indexpath; -(void) TableView: (UITableView *) TableView DiddeselectroWatindexpath: (Nsindexpath *) Indexpath Ns_available_ios (3_0); Editing//Allows customization of the editingstyle for a particular cell located at ' Indexpath '.  If not implemented, all editable cells'll have uitableviewcelleditingstyledelete set for them when the table has editing
Property set to YES. -(Uitableviewcelleditingstyle) TableView: (UITableView *) TableView Editingstyleforrowatindexpath: (NSIndexPath *)
Indexpath; -(NSString *) TableView: (UITableView *) TableView Titlefordeleteconfirmationbuttonforrowatindexpath: (NSIndexPath *)
Indexpath Ns_available_ios (3_0); -(Nsarray *) TableView: (UITableView *) TableView Editactionsforrowatindexpath: (Nsindexpath *) IndexPath NS_AVAILABLE_ IOS (8_0); Supercedes-tableview:titlefordeleteconfirmationbuttonforrowatindexpath:if return value is Non-nil//Controls Wheth  Er the background is indented while editing.  If not implemented, the default is YES.  This is unrelated to the indentation level below. This method is only applies to grouped styLe table views.

-(BOOL) TableView: (UITableView *) TableView Shouldindentwhileeditingrowatindexpath: (Nsindexpath *) IndexPath;  The willbegin/didend methods are called whenever the ' editing ' property was automatically changed by the table (allowing Insert/delete/move). This is doing by a swipe activating a single row-(void) TableView: (uitableview*) TableView Willbegineditingrowatindexpath: (
Nsindexpath *) Indexpath;

-(void) TableView: (uitableview*) TableView Didendeditingrowatindexpath: (Nsindexpath *) Indexpath; Moving/reordering//Allows customization of the target row for a particular row as it is being moved/reordered-(NSI Ndexpath *) TableView: (UITableView *) TableView Targetindexpathformovefromrowatindexpath: (NSIndexPath *)               

Sourceindexpath Toproposedindexpath: (Nsindexpath *) Proposeddestinationindexpath; Indentation-(Nsinteger) TableView: (UITableView *) TableView Indentationlevelforrowatindexpath: (NSIndexPath *) Indexpath;

Return ' depth ' 's Row for hierarchiesCopy/paste.

All three methods must is implemented by the delegate. -(BOOL) TableView: (UITableView *) TableView Shouldshowmenuforrowatindexpath: (Nsindexpath *) Indexpath NS_AVAILABLE_
IOS (5_0); -(BOOL) TableView: (UITableView *) TableView canperformaction: (SEL) Action Forrowatindexpath: (Nsindexpath *) Indexpath
Withsender: (ID) Sender Ns_available_ios (5_0); -(void) TableView: (UITableView *) TableView performaction: (SEL) Action Forrowatindexpath: (Nsindexpath *) Indexpath

Withsender: (ID) Sender Ns_available_ios (5_0); @end

There are a number of ways to control the cell properties, display styles, and so on.
In addition to a few necessary, heightforrowatindexp

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.