[IOS] imitates the YFMetroListBox and vblistbox indexes of the windowsphone List Index Control.

Source: Internet
Author: User

[IOS] imitates the YFMetroListBox and vblistbox indexes of the windowsphone List Index Control.

Do you think that the index on the Right of UITableView is difficult to use? I always think that the List Index in WindowsPhone is very useful.

Therefore, we can implement a list index (this is the belief) similar to that in Windows Phone ).

Final Implementation:

1. Complete initial index 2. Header name index

 

Idea: Should this control inherit UITableView, UIView, or others?

The control that you want to write, onlyAdd an index on the basis of UITableView. Click the HeaderView event to bring up the index.

The index size is the size of the control and is directly added to the parent view.

Therefore, it is more convenient to directly inherit the UITableView. Although inheriting the UIView is easier to write, it is not very good.

 

An example of implementing the UITableView animation is displayed, so the click event for implementing the HeaderView is referenced.

Https://github.com/applidium/ADLivelyTableView

The principle is to add an intermediate proxy and only implement the willDisplayCell protocol in the control to control the animation during sliding,

If the protocol is also implemented when the control is used in VC, the control proxy will send the message to VC. This is equivalent

The implementation part of UITableView remains unchanged, and the animation is handed over to the control for implementation.

------------------------------------- I am a split line ----------------------------------------------

1. inherit UITableView-add Intermediate proxy

General process: UIViewController <UITableViewDelegate> ---> UITableView

TableView. delegate = self;

Control Process: inherits UITableView: YFMetroListBox: UITableView

Add the private property: id <UITableViewDelegate> _ selfDelegate;

UIViewController <UITableViewDelegate> ---> YFMetroListBox <UITableViewDelegate> ---> UITableView

TableView. delegate = self; For the rewrite YFMetroListBox proxy, see the following code:

Override YFMetroListBox to set Proxy: (this is an attribute inherited from UITableView)

-(Void) setDelegate :( id <UITableViewDelegate>) delegate {// The form parameter here is VC object _ selfDelegate = delegate; // Let this class (YFMetroListBox) listen to the VC [super setDelegate: self]; // Let the parent class (UITableView) Listen to the Child class
}
// Rewrite method: YFMetroListBox or whether the parent class implements the protocol-(BOOL) respondsToSelector :( SEL) aSelector {return [super respondsToSelector: aSelector] | [_ selfDelegate respondsToSelector: aSelector];} // forward the message-(void) forwardInvocation :( NSInvocation *) anInvocation {if ([_ selfDelegate respondsToSelector: [anInvocation selector]) {[anInvocation failed: _ selfDelegate];} else {[super forwardInvocation: anInvocation];}

 

2. YFMetroListBox implements the willDisplayHeaderView protocol,Add a click gesture for adding HeaderView

Detour 1:At the beginning, I want to use viewForHeaderInSection to add a custom View and then add a gesture,

However, in this case, the HeaderView content is required here, So NSArray is passed in directly during initialization (it doesn't feel good, but there is no other solution ).

In addition to the above protocols, titleForHeaderInSection can also be used to directly set the default title content. How can we get headerView?

In addition, the above two protocols are in UITableViewDataSource, and this will be even more confusing in the control.

 

Solution:No matter how the title is set in VC, you can add a gesture when HeaderView is to be displayed.

 

# Pragma mark-m UITableViewDelegate-(void) tableView :( UITableView *) tableView willDisplayHeaderView :( UIView *) view forSection :( NSInteger) section {// If VC implements this protocol, if ([_ selfDelegate respondsToSelector: @ selector (tableView: willDisplayHeaderView: forSection :)]) {[_ selfDelegate tableView: tableView willDisplayHeaderView: view forSection: section];}
// Add the gesture counter * tapRegesture = [[initalloc] initWithTarget: self action: @ selector (tapHeaderViewInSection)]; view. gestureRecognizers = @ [tapRegesture];}

 

3. Get the title content array in YFMetroListBox

Detour 2:If headerViewForSection exists, the method obtains the headerView of a section. As a result,

Since the header title has been set in VC, I can certainly Dynamically Retrieve all titles internally. (Incorrect idea)

 

-(NSArray *) getHeaderViewTextArray {NSMutableArray * array = [NSMutableArray array]; for (int I = 0; I <[self numberOfSections]; I ++) {// Number of circular sections NSArray * subviews = [[self headerViewForSection: I] subviews]; // obtain the UIlabel content for (id subview in subviews) {if ([subview isKindOfClass: [UILabel class]) {UILabel * label = (UILabel *) subview; [array addObject: label. text]; break ;}}return array ;}

However, in this method, only the headers in the visible part of the screen are obtained, instead of all headers.

Cause: Because the reuse mechanism is used, only the display part is created, so you want to obtain all the content.

It is impossible. This type of problem should be triggered from the data source.

Solution:As in the UITableViewDataSource protocol, sectionIndexTitlesForTableView is implemented through the Protocol.

Customize a Protocol to implement this protocol in VC, and assign the YFMetroListBox header array data.

@ Protocol YFMetroListBoxDelegate <NSObject> @ required-(NSArray <NSString *> *) sectionIndexTitlesForYFMetroListBox :( YFMetroListBox *) metroListBox; // The returned header array has two formats: 1. custom title header 2. ("# ABCD... Z @ "), # represents a number @ temporarily represents a character other than a number, letter, or English character. @ End

Specifically, we will sort a group of data that contains numbers, Chinese characters, English letters, and symbols into the format of # ABC... Z notation.

 

4. Draw the page after clicking

There are two interface types, which can be set through the metroListBoxType enumeration attribute.

Correspond to the top two graphs respectively. There is nothing to say about this. Get the header array from the previous point. .

If it is YFMetroListBoxTypeAllAlphabet, draw all #. A. B. C... Z. @ and add click events to the header array.

Click [self scrollToRowAtIndexPath: [NSIndexPath indexPathForRow: 0 inSection: section]

AtScrollPosition: UITableViewScrollPositionTop animated: NO.

 

5. Rewrite the insert, delete, and reload data methods.

So far, it has basically been done. Only reloadData,

You can also perform insertSections, deleteSections, moveSection, and other operations on the section. The index list will not change.

Therefore, rewrite them and manually call the method for updating the index interface.

//Data-(void)reloadData{    [self updateZoomOutView];    [super reloadData];}-(void)reloadSectionIndexTitles{    [self updateZoomOutView];    [super reloadSectionIndexTitles];}// only call insert/delete/reload calls or change the editing state inside an update block.  otherwise things like row count, etc. may be invalid.- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation{    [self updateZoomOutView];    [super insertSections:sections withRowAnimation:animation];}- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation{    [self updateZoomOutView];    [super deleteSections:sections withRowAnimation:animation];}- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation{    [self updateZoomOutView];    [super reloadSections:sections withRowAnimation:animation];}- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection{    [self updateZoomOutView];    [super moveSection:section toSection:newSection];}

 

In this way, we are done.

GitHub address: YFMetroListBox

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.