Uitable View's Unfolding

Source: Internet
Author: User

UITableView Division Expansion and CollectionOverview

Today, we teach you to use the section of UITableView to realize the effect of starting and collecting like QQ. In fact, the implementation is very simple, but still write an article to everyone to talk about ideas and the source code for the Novice reference.

Simple, but different people come to realize maybe there will be different ways of implementation, the simplicity of the same OH. In fact, and AppStore in the category of the effect of the page is quite similar, but people that is not the animation effect, but more beautiful animation!

Article content

After reading this article, you will learn:

    • How to use the section of UITableView to realize the effect of unfolding and collecting
    • How to re-use UITableView header view
    • How to better solve cell multiplexing problems by using models that correspond to UI structure one by one

The words are not as good as a GIF, see the following effect:


Image Assumption

When you see this, what do you think? How to achieve it? Is there a ready-made one? Does the animation meet the needs? Is scalability enough?

If you are familiar with UITableView, then you should be able to easily think of the UITableView section, after the expansion is UITableView multiple cells.

Of course, if you do not use the UITableView section to implement, then you need to solve the problem of reuse, instead of trouble. Therefore, this article teaches you how to use UITableView to achieve.

Building a model

The hierarchy of the UI is the same as the structure of the model, which is most streamlined. First, we define the partitioning model, where each partition model represents a zone, and there can be many cells under the zone:

Partitioning model@interfaceHybsectionmodel:NSObject@property (Nonatomic,CopyNSString *sectiontitle;//is an expanded  @property (nonatomic, Span class= "Hljs-keyword" >assign) bool isexpanded; There can be a number of cell-corresponding models nonatomic, strong) nsmutablearray *cellmodels; @end //each cell corresponds to one such model@ Interface hybcellmodel: nsobject@ Property (nonatomic, copy)  NSString *title;  @end             

It's very easy to use it when you build a hierarchical relationship between the model and the UI.

Custom Uitableviewheaderfooterview

We need to customize the uitableviewheaderfooterview here, so we need to subclass it. In fact, with the UITableViewCell of the sub-class is the same, there are similar properties, use is the same.

Maybe a lot of friends haven't seen anyone use this stuff. Yes, in project development, I have not seen anyone else using it, all directly customizing a uiview. This is not a no-no, but it cannot be linked to uitableview reuse.

We customize the Hybheaderview, then the registration multiplexing Headerfooterview can be reused:

[self.tableView registerClass:[HYBHeaderView class] forHeaderFooterViewReuseIdentifier:kHeaderIdentifier];

First, we first subclass the Uitableviewheaderfooterview, we need to pass Hybsectionmodel object come over, represent a partition header, through model rewrite setter method, automatic configuration data. Since we've added a simple animation to the expansion and unwinding, the external callback is required and we give a callback closure:

 @class hybsectionmodel; typedef void (^hybheaderviewexpandcallback) (bool isexpanded);  @interface hybheaderview: uitableviewheaderfooterview @property ( Nonatomic, strong) Hybsectionmodel *model;  @property (nonatomic, copy) Hybheaderviewexpandcallback Expandcallback;  @end             

Someone might ask, why Hybsectionmodel use @class to declare, instead of directly introducing header files? In fact, in project development, I usually use @class in the header file declaration, and in the implementation file is really introduced, this can avoid the loop contains the problem of compiling errors.

Our implementation of the file content is relatively small, we have to rewrite the Setmodel method to configure the data. In my project development, almost all of this configuration data is used, unless a cell is shared in multiple places. If a cell is shared by multiple places, and the model has the same, and some are different, this requires a specific write API to differentiate. We are adding rotation animations through tranform, which is very simple to implement:

#import"HYBHeaderView.h"#import"HYBSectionModel.h"@interfaceHybheaderview ()@property (Nonatomic,Strong)Uiimageview *arrowimageview;@property (Nonatomic,Strong)UILabel *titlelabel;@end@implementationhybheaderview-(Instancetype) Initwithreuseidentifier: (NSString *) Reuseidentifier {if (Self = [Super Initwithreuseidentifier:reuseidentifier]) {CGFloat w = [UIScreen Mainscreen]. Bounds. Size. width;Self. Arrowimageview = [[Uiimageview Alloc] initwithimage:[UIImage imagenamed:@ "expanded"];Self. Arrowimageview. frame =CGRectMake (10, (44-8)/2,15,8); [Self. Contentview Addsubview:Self. Arrowimageview];UIButton *button = [UIButton Buttonwithtype:Uibuttontypecustom]; [Button AddTarget:Self action:@selector (Onexpand:) forControlEvents:UIControlEventTouchUpInside]; [Self. Contentview Addsubview:button]; button. frame =CGRectMake (0,0, W,44);Self. Titlelabel = [[UILabel Alloc] initWithFrame:CGRectMake (35,0,200,44)];Self. Titlelabel. TextColor = [Uicolor Whitecolor];Self. Titlelabel. backgroundcolor = [Uicolor Clearcolor]; [Self. Contentview Addsubview:Self. Titlelabel];Self. Contentview. backgroundcolor = [Uicolor Purplecolor];UIView *line = [[UIView Alloc] initWithFrame:CGRectMake (0,44-0.5, W,0.5)]; Line. backgroundcolor = [Uicolor Lightgraycolor]; [Self. Contentview Addsubview:line]; }ReturnSelf;} - (void) Setmodel: (Hybsectionmodel *) Model {if (_model! = model) {_model = model;}if (model. isexpanded) {Self. Arrowimageview. Transform =cgaffinetransformidentity; }else {Self. Arrowimageview. Transform =Cgaffinetransformmakerotation (M_PI); }Self. Titlelabel. Text = Model. Sectiontitle;} - (void) Onexpand: (UIButton *) Sender {Self. Model. isexpanded =!Self. Model. isexpanded; [UIView animatewithduration:0.25 animations:^{if (self.model.isExpanded) { Span class= "Hljs-keyword" >self.arrowimageview.transform = cgaffinetransformidentity;} else {self.arrowImageView< Span class= "hljs-variable" >.transform = cgaffinetransformmakerotation (M_PI);}]; if (self.expandCallback) { Span class= "Hljs-keyword" >self.expandcallback (self.model.isexpanded); }} @end             

When we configure the data, we will also display the direction of the picture according to the isexpanded status, otherwise it will be returned to the original state after reuse.

Create a UITableView and configure the data source

First, we create the UITableView and register the cell, Headerview:

Self.tableview = [[UITableView Alloc]initWithFrame:Self.view.bounds]; [self.view addsubview: Self.tableview]; self.tableview.delegate = self; Self.tableView.dataSource = self;[ self.tableview registerclass:[ UITableViewCell class]  Forcellreuseidentifier:kcellidentfier]; [self.tableview registerclass:[ Hybheaderview class]  Forheaderfooterviewreuseidentifier:kheaderidentifier];       

Then, initialize the data source:

- (Nsmutablearray *) Sectiondatasources {if (_sectiondatasources = =Nil) {_sectiondatasources = [[Nsmutablearray alloc] init];for (Nsuinteger i =0; I <20; ++i) {Hybsectionmodel *sectionmodel = [[Hybsectionmodel alloc] init]; Sectionmodel. isexpanded =no; Sectionmodel.sectiontitle = [ nsstring stringwithformat:@ "section:%ld", I]; nsmutablearray *itemarray = [[nsmutablearray alloc] init]; for (nsuinteger j = 0; J < 10; ++J) {Hybcellmodel *cellmodel = [[Hybcellmodel alloc] init]; Cellmodel.title = [nsstring stringwithformat:@ "marker: Section=%ld, row=%ld", I, j]; [ItemArray Addobject:cellmodel]; } sectionmodel.cellmodels = ItemArray; [_sectiondatasources Addobject:sectionmodel]; }} return _sectiondatasources;}         

Tip: in development, I will use the rewrite getter method to create, including the UI is the same, for do not need to display immediately, the use of lazy loading.

Implement the Proxy method of UITableView

For us, the partition is the number of elements of the corresponding data source array, and the number of rows per section needs to be judged to be expanded or closed. When the expansion state is, it is the number of elements of the cellmodels array, otherwise it is 0.

We need to use Dequeuereusableheaderfooterviewwithidentifier:kheaderidentifier to get the Headerview for reuse:

#pragma mark-uitableviewdatasource-(Nsinteger) Numberofsectionsintableview: (UITableView *) TableView {ReturnSelf. sectiondatasources. Count;} - (Nsinteger) TableView: (UITableView *) TableView numberofrowsinsection: (Nsinteger) Section {Hybsectionmodel *sectionmodel =Self. Sectiondatasources[section];Return Sectionmodel. isexpanded? Sectionmodel. cellmodels. Count:0;} - (UITableViewCell *) TableView: (UITableView *) TableView Cellforrowatindexpath: (Nsindexpath *) Indexpath {UITableViewCell *cell = [TableView dequeuereusablecellwithidentifier:kcellidentfier Forindexpath:indexpath]; Hybsectionmodel *sectionmodel =Self. Sectiondatasources[indexpath. section]; Hybcellmodel *cellmodel = Sectionmodel. Cellmodels[indexpath. row]; Cell. Textlabel. Text = Cellmodel. title;return cell;} - (UIView *) TableView: (UITableView *) TableView viewforheaderinsection: (Nsinteger) Section {hybheaderview *view = [TableView dequeuereusableheaderfooterviewwithidentifier:kheaderidentifier ]; Hybsectionmodel *sectionmodel =Self. Sectiondatasources[section]; View. model = Sectionmodel; View.expandcallback = ^ (bool isexpanded) {[TableView Reloadsections:[nsindexset indexsetwithindex:section] WithRowAnimation:uitableviewrowanimationfade"; }; return view;}  #pragma mark-uitableviewdelegate-(CGFloat) TableView :(uitableview *) TableView Heightforrowatindexpath: ( Nsindexpath *) Indexpath {return 44;} -(cgfloat) TableView: (uitableview *) TableView Heightforheaderinsection: (nsinteger) section {return 44;}              

Tip: in the optimization of TableView, one of them is multiplexing cell, multiplexing header/footer view.

Tip: This article was reproduced in Http://www.jianshu.com/p/fc45624603f6

Uitable View's Unfolding

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.