IOS 8 automatically adjusts UITableView and uicollectionview layouts

Source: Internet
Author: User

This article was reproduced from: http://tech.techweb.com.cn/thread-635784-1-1.html

This article describes the knowledge of the UITableView, Uicollectionview implementation of the Self-sizing cell layout, and how to optimize Uicollectionview layout updates with Invalidationcontext.

Background
IOS is becoming more user-friendly, and users can dynamically adjust the font size in the settings-general-accessibility feature. You'll find that the font size of all IOS-brought apps has changed, but the third-party app we've developed is still a previous font. After IOS 7, we can use the Uifont Preferredfontfortextstyle: Class method to specify a style and let the font size match the font size set by the user. There are currently six styles to choose from:

        Uifonttextstyleheadline        uifonttextstylebody        uifonttextstylesubheadline        uifonttextstylefootnote        UIFontTextStyleCaption1        


iOS adjusts the font appropriately to suit the purpose of the style.

The problem comes, such as the font size of this "dynamic type", we need to make dynamic UI adjustment, otherwise we always feel that our interface is strange:

We want to make the cell's height adjust with the font size:

In short, there are other dynamic factors that cause us to modify the layout.

Solution Solutions
UITableView
There are three strategies to adjust the height of the cell (or header and footer):

A. Adjusting the Height property
B. Tableview:heightforrowatindexpath by means of the delegation method:
C.cell "self-Arrangement" (self-sizing)

The first two strategies are familiar to us, and the third strategy is described later. Both UITableViewCell and Uicollectionviewcell support self-sizing.

In IOS 7, Uitableviewdelegate has added three methods to meet the user's method of setting the cell, header, and footer expected Heights:

        - Tableview:estimatedheightforrowatindexpath:        - tableview:estimatedheightforheaderinsection:        


Of course the corresponding three methods UITableView also Estimatedrowheight, Estimatedsectionheaderheight and estimatedsectionfooterheight three properties, The limitation is that only the height of all rows and sections can be defined uniformly.

In cell, for example, iOS creates a cell based on the projected height given, but when it is actually shown, iOS 8 will display the cell drawing after Self-sizing calculates the new Size and adjusts the table's contentsize. The key is how to derive the new Size,ios of the Cell provides two methods:

Automatic layout
The artifact, launched two years ago, was poor at first, but with the increasing power of Xcode, the automatic layout in iOS7 has become the default tick, by setting a series of constraints to make our UI adaptable to screens of all sizes. If you have experience using constraints, you must have a solution: Add a constraint to the Cell's Contentview. IOS will first call UIView's Systemlayoutsizefittingsize: method to calculate the new size based on the constraint, if you don't implement the constraint, Systemlayoutsizefittingsize: The Sizethatfits: method is then called.

Manual Code
We can rewrite the Sizethatfits: method to define the new size yourself so that we don't have to learn to constrain the relevant knowledge.

Below I give a demo-hardchoice written in Swift language, using automatic layout to adjust the height of UITableViewCell. I realized the automatic layout by implementing a UITableViewCell subclass Dynamiccell, and you can download the source code on GitHub:

Import UIKitclassDynamiccell:uitableviewcell {required init (Coder:nscoder) {Super.init (coder:c oder)ifTextlabel! =Nil {Textlabel.font=Uifont.preferredfontfortextstyle (uifonttextstyleheadline) textlabel.numberoflines=0                }                ifDetailtextlabel! =Nil {Detailtextlabel.font=Uifont.preferredfontfortextstyle (uifonttextstylebody) detailtextlabel.numberoflines=0                }            }                         OverrideFunc constraints ()[Anyobject] {var constraints=[Anyobject] ()ifTextlabel! =Nil {constraints.extend (Constraintsforview (Textlabel))}ifDetailtextlabel! =Nil {constraints.extend (Constraintsforview (Detailtextlabel))} cons Traints.append (Nslayoutconstraint (Item:contentview, Attribute:NSLayoutAttribute.Height, Relatedby: Nslayoutrelation.greaterthanorequal, Toitem:contentview, Attribute:NSLayoutAttribute.Height, multiplier:0, Constant: -)) contentview.addconstraints (constraints)returnconstraints} func Constraintsforview (View:uiview)-[anyobject]{var constraints=[Nslayoutconstraint] () constraints.append (Nslayoutconstraint (Item:view, Attribute:nslayoutattribute. Firstbaseline, RelatedBy:NSLayoutRelation.Equal, Toitem:contentview, Attribute:NSLayoutAttribute.Top, multiplier: 1.8, Constant:30.0)) Constraints.append (Nslayoutconstraint (Item:contentview, Attribute:NSLayoutAttribute.Bottom, relate DBy:NSLayoutRelation.GreaterThanOrEqual, Toitem:view, Attribute:NSLayoutAttribute.Baseline, multiplier:1.3, Constant:8))                returnconstraints}}



The above code should note that classes in OBJECTIVE-C can be treated as anyobject in Swift, which works well for type compatibility issues.
Don't forget to add the Viewdidload method in the corresponding Uitableviewcontroller:

44


The adaptive effect is as follows:

Uicollectionview
UITableView and Uicollectionview are both Data-source and delegate-driven. The Uicollectionview is further abstracted on top of this. It delegates control over the location, size, and appearance of its child views to a separate layout object. By providing a custom layout object, you can implement almost any layout you can imagine. The layout inherits from the Uicollectionviewlayout abstract base class. A specific layout implementation is presented in IOS 6 in the form of a uicollectionviewflowlayout class. In Uicollectionviewflowlayout, Self-sizing also applies:

After using self-sizing:

Uicollectionview implementation self-sizing can not only be constrained and rewritten sizethatfits on the contentview of the cell: it can also be used at the cell level (formerly the Self on Contentsize -sizing): Rewrite Uicollectionreusableview's preferredlayoutattributesfittingattributes: method to modify the Size after self-sizing calculation , thus achieving full control of the cell layout properties (uicollectionviewlayoutattributes).

Ps:preferredlayoutattributesfittingattributes: The method defaults to resizing the Size property to fit the self-sizing Cell, so you need to call the parent class method when overriding, and then return the Do the changes you want to make on the Uicollectionviewlayoutattributes object.

Thus we force the calculation of attributes from the most classic Uicollectionviewlayout (remember Uicollectionviewlayoutattributes's series of factory methods?). To use self-sizing to adjust the size of the attribute according to our needs, and then to rewrite Uicollectionreusableview (Uicollectionviewcell is also inherited from it) Preferredlayoutattributesfittingattributes: Method to modify all properties from the cell plane:

Here's how to implement Self-sizing in Uicollectionviewflowlayout:
First, Uicollectionviewflowlayout adds the Estimateditemsize attribute, which is associated with the "estimated ..." in UITableView. Height "very much like (note I use the ellipsis to include the three attributes), but after all, the Item in Uicollectionview need to constrain the Height and width, so it is a cgsize, except that it and UITableView in the" estimate D... Height "usage is no different.
Its... No second, implement self-sizing in Uicollectionview, just give Estimateditemsize property assignment (can't be Cgsizezero), one line of code is sufficient.

Invalidationcontext
If the device screen rotates, or needs to show some of its wonderful effects (such as coverflow), we need to invalidate the current layout and recalculate the layout. Of course, each calculation has a certain overhead, so we should be careful to call the Invalidatelayout method only when we need it to invalidate the layout.

In the era of IOS 6, some people would "intelligently" do this:

- (BOOL) Shouldinvalidatelayoutforboundschange: (CGRect) Newbounds {            CGRect oldbounds  = Self.collectionView.bounds;  if  (Cgrectgetwidth (newbounds)!= Cgrectgetwidth (oldbounds) {  YES;         return   NO; } 


and the newly added Uicollectionviewlayoutinvalidationcontext class for IOS 7 declares which parts of the layout will need to be updated when the layout fails. When the data source changes, both the read-only Bool property of Invalidateeverything and invalidatedatasourcecounts marks the Uicollectionview data source "all expires" and " The section and item numbers are invalidated, and Uicollectionview will automatically set them up and provide it to you.

You can call the Invalidatelayoutwithcontext: Method and pass in a Uicollectionviewlayoutinvalidationcontext object, which optimizes the efficiency of the layout update.

When you customize a uicollectionviewlayout subclass, you can call the Invalidationcontextclass method to return a Uicollectionviewlayoutinvalidationcontext, so your layout subclass will use your custom Invalidationcontext subclass to optimize the update layout when it fails.

You can also override the Invalidationcontextforboundschange: method to return a Invalidationcontext object by overriding this method when implementing a custom Layout.

All of the above are new additions to IOS 7 and can also be applied to uicollectionviewflowlayout. In IOS 8, Uicollectionviewlayoutinvalidationcontext is also used on the Self-sizing cell. In

IOS8, Uicollectionviewlayoutinvalidationcontext has added three new methods that allow us to more carefully and precisely make a row of a section item (Cell), supplementary View or decoration View expiration:

        Invalidateitemsatindexpaths:        invalidatesupplementaryelementsofkind:atindexpaths:        


Copy Code
corresponding to the addition of three read-only group attributes to mark the above three components:

        Invalidateditemindexpaths        invalidatedsupplementaryindexpaths        invalidateddecorationindexpaths     


The photo app that comes with iOS will stay at the top of each photo's information (time, place), and the ability to stick the Header to the top is simply to invalidate the Index's supplementary View.

Uicollectionviewlayoutinvalidationcontext the newly added contentoffsetadjustment and Contentsizeadjustment properties allow us to update The displacement and size of the content of the CollectionView.

In addition Uicollectionviewlayout has added a couple of methods to help us use self-sizing:

        Shouldinvalidatelayoutforpreferredlayoutattributes:withoriginalattributes:        


When a self-sizing cell property changes, the first method is called, it asks if the layout should be updated (that is, the original layout is invalidated), the default is no, and the second method more granular indicates which properties should be updated. You need to call the parent class's method to get a Invalidationcontext object, then make some changes you want, and finally return.

Imagine that if, in your custom layout, the size of a cell has changed for some reason (for example, because of a change in font size), other cells will change position due to self-sizing, you need to implement the above two methods to let the specified cell update some of the properties in the layout Don't forget that the entire CollectionView contentsize and Contentoffset will change as well, and you need to assign values to the Contentoffsetadjustment and Contentsizeadjustment properties.

IOS 8 automatically adjusts UITableView and uicollectionview layouts

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.