Analysis of the Three Calculation dynamic Row Height methods of tableView, tableview Row Height

Source: Internet
Author: User

Analysis of the Three Calculation dynamic Row Height methods of tableView, tableview Row Height

TableView is a magic thing. It can be said that even if a beginner can play tableView 6 very well, the general iOS coding requirements will not matter. TableView is a bad control used in daily development. However, there are still some xuanjicang about the dynamic Row Height of the custom cell in tableView. This is mainly because of the problem of the method of estimating the Row Height. As an opportunity, I wrote this article to analyze several dynamic Row Height methods.

If you did not see this article in Dong Boran's blog, click to view the original article.

 

Old Method

Currently, the general calculation method for dynamic row height is still used.

[str boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size

In this case, you need to first input a maximum size and an attribute dictionary. Special format requirements are all written in the attribute dictionary.

 NSDictionary *attrs = @{NSFontAttributeName : font};

The basic idea of the entire process is to call this method using a String object. An Attribute dictionary is required to inform the font and style, then, calculate the size of the frame according to the length of the string. Generally, you can set the maximum width of the size that is passed in. This method is generally categorized for easy calling.

# Import "NSString + Size. h "@ implementation NSString (Size)/*** class calculation size */+ (CGSize) sizeWithString :( NSString *) str andFount :( UIFont *) font andMaxSize :( CGSize) size {NSDictionary * attrs =@{ NSFontAttributeName: font}; return [str boundingRectWithSize: size options: NSStringDrawingUsesLineFragmentOrigin attributes: attrs context: nil]. size;}/*** calculation size of Object Method */-(CGSize) sizeWithFount :( UIFont *) font andMaxSize :( CGSize) size; {NSDictionary * attrs =@{ NSFontAttributeName: font}; return [self boundingRectWithSize: size options: NSStringDrawingUsesLineFragmentOrigin attributes: attrs context: nil]. size;} @ end

These methods are literally easier to understand.

The code used for calling is to get a string and input a font and a maximum size. The following Code sets the width to 270, which means that the maximum width is 270, and the height is written as MAXFLOAT.

    NSString *text = _message.text;    CGSize textSize = [text sizeWithFount:[UIFont systemFontOfSize:14] andMaxSize:CGSizeMake(270, MAXFLOAT)];

Then, the maxY of the bottom space is obtained in the frame, so that each cell can get its own row height in the set method, and then return the result through the cell class method.

 

New Method

As iOS8's Automatic Layout and Interface builder become more and more mature, a method is developed to calculate the custom line height by using the storyboard or xib Interface.

In this method, you need to build a graphical interface first. For example, a complicated cell is constructed.

Figure 1

First of all, we can clearly see that building with IB looks like it can be quickly completed, and some images or view backgrounds can be seen after being set. Note that the label setting method is used to set constraints. Generally, four constraints must be set for a general control to fix the position. Only two constraints are set for the label and button (only two constraints at a fixed position need to be written, if you do not need to write the constraints on your own width and height, no error will be reported. However, you need to set sizeToFit in the editor so that you can automatically allocate the size of a control based on the number of words.

Figure 2

Generally, the comments label must have a large number of words. At this time, the two constraints are not enough. You need to set a maximum width constraint. 1. the method I set is, set the gap between the comment label and the left and right boundary. In IB, this is called Leading (Front) and Training (back ), if the number of words exceeds the limit of one line, he will extend the limit. Compared with writing the width constraint, this write will automatically return several pixels regardless of the size of the screen. This method also has limitations, that is, to set a background color for this label. If the number of words is five characters, the background color will be extended to a whole line. If you do the same on the QQ chat page, it will be ugly to have a full line of chat bubbles. So there is a method of setting the width of the label less than the width of the label and setting the width of the label less than to set the maximum width. In this case, if the number of words is less than one line, the constraint will be automatically scaled to match the label length.

[Cell layoutIfNeeded];

It will automatically Layout Based on the entered values, and then we will directly return the bottom position of the bottom Control + a number of gaps in this method, as a line height.

The real layout is actually using this line of code, and screen adaptation can be achieved without the use of if to judge various frames. But there are also some problems with this writing. The first thing is that this writing is unreasonable in terms of structure. These value assignment statements should not be written in this line method. The official website is still the reason why other great gods say it is unreasonable. This method should only be used to calculate the travel height and display it. It will be called multiple times. If it is assigned here, the performance will be poor. So it makes sense to read every line of code here. We can see that the method for poor performance is mainly the two lines: 1. assign a value to the Model in cell 2. layoutIfNeed. If this method is called multiple times, the two rows will be executed multiple times, so this should be unscientific. In practice, I set a high-Cache row dictionary in it and find a unique identifier for key value. The cell of each row takes its id to the row cache dictionary to check whether there is a value. If yes, the corresponding value is directly returned. If no value is calculated. In this way, the two lines of code with poor performance can be executed only once. To achieve the optimization effect.

MTFBNoReplyCell * feedbackNoreplyCell = [MTFBNoReplyCell cell]; NSString * thisId = [NSString stringWithFormat: @ "% d", feedbackModel. feedbackid]; // MTLog (@ "% @", [self. cellHeightCache valueForKey: thisId]); CGFloat cacheHeight = [[self. cellHeightCache valueForKey: thisId] doubleValue]; if (cacheHeight) {// MTLog (@ "return cached Row Height"); return cacheHeight ;} // MTLog (@ "High Performance consumption rows"); feedbackNoreplyCell. feedbackDetailModel = feedbackModel; [feedbackNoreplyCell layoutIfNeeded]; [self. cellHeightCache setValue: @ (feedbackNoreplyCell. replyBtn. bottom + 16) forKey: thisId]; return feedbackNoreplyCell. replyBtn. bottom + 16;

The general idea is shown above. If the data of this tableView is not changed at any time, you can use the obtained model as the value and use indexpath. row as the key to store a cache dictionary, which can also be optimized. After the Row Height method is obtained, cellForRow can be used directly. (Dong Boran)

 

Estimation Row Height Method

Here I want to focus on estimatedHeightForRowAtIndexPath, a method with a high estimation line. Most people may say this method is good when talking about it. Estimating a high method can reduce the number of heightForRow calls and optimize the performance. I don't know whether there are some problems in practical use.

The entire tableView is inherited from scrowView. scrowView can be rolled because it has contentSize. When loading tableView for the first time, you also need to calculate the contentSize (and more than once). That is to say, you need to adjust the height of all rows and then accumulate the entire contentSize for it. If you set a print in the row height method, the method will be called many times. At this time, if there is an estimation method return 100. Then it can quickly calculate the total value. It will reduce the call of the row height method and call it when a row is actually used.

However, the following problem may occur on the left.

The cause of the problem is that the estimation method at the beginning estimates a row height for each row, and then the actual loaded Row Height is different from the estimated Row Height, there will be the feeling of cell tampering. My idea is that if it is dynamic and the cell complexity is high, and the gap between rows is large, don't write a high estimation method, let him calculate it by himself, even if he calls it several times. After all, he has written a high Dictionary of cache lines, so the performance can be held and there will be no "tampering. As shown in the right figure.

However, if there is one or three different cells with fixed Row Height, the row height is 120,150,200. You write a return 150 higher than the predicted row. In the case of high and estimated values, there will be no "tampering ". I assume that estimatedHeightForRow cannot coexist with layoutIfNeed in HeightForRow. If both exist, the bug of "tampering" will occur. Therefore, my suggestion is: Write the estimated Row Height as long as the row height is fixed to reduce the number of rows with high calls and improve performance. If it is dynamic, do not write the estimation method. Use a high-row cache dictionary to reduce the number of calls to the code.

My conclusion is that the performance of the new method is definitely worse than that of the old one. It is embodied in two aspects: 1. Something developed on the IB page. once started, all the programs will be loaded into the memory and managed by the system, in this way, you have sent the stack top controller of the navigation controller to pop on some interfaces and found that the memory has not decreased. 2. There is an essential difference between the new method and the old method. The old method is to calculate the size of the new method, the new rule is to force the layout first and then tell you the size of the layout. The new method is to force the layout process, this will definitely have a certain impact on the performance. What is the specific impact? I still don't know anything about the height of the sliding computing line to identify a data comparison. I can only distinguish the comparison by looking at the sliding of the screen. I feel that there is basically no difference, if there is a new method, it may be very slow. In other words, it is the same page. It takes 10 hours to complete the old method and 3 hours to complete the new method, however, the performance of the new method is slightly worse than that of the old method. It depends on your own measurement. Of course, it is recommended to use the old method for a very large project. After all, the "slightly worse" accumulation at is very poor.

 

New Features of iOS8

First, there is a new usage. Written in viewdidload

self.tableView.estimatedRowHeight = 50.0f;self.tableView.rowHeight = UITableViewAutomaticDimension;

There is nothing to say about it. Apple will help you perform dynamic high computing on its own, so you don't have to worry about all the mess. However, for the time being, this is basically useless, because we can't see which company's projects are not compatible with iOS7, so we can figure out that iOS9 won't allow you to adapt to ios8, there will be a long period of time for iOS7. After all, there will be no major changes from iOS 6 to iOS 7 in the future, unless Apple's chief designer Jonathan Yve stepped down.

All of the above are my personal understanding of the high method. If you have any wrong understanding or are too one-sided, please point out.

If you did not see this article in Dong Boran's blog, click to view the original article.

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.