UITableView headers on the left side of sections (e.g. Spotlight)

I searched for this for a while, and I still have not found a way to do this. I would like to play iPhone Spotlight section headings in a UITableView.

The β€œregular” table window titles remain visible at the top of the section when scrolling, as we all know. But there is one kind of heading that I have never seen anywhere except the Spotlight page in the Springboard: there the headings cover the entire height of the section and do not get stuck at the top of the section, but on the left side.

How is this achieved?

+6
ios iphone cocoa-touch uitableview
source share
3 answers
Good question. I did a little experiment. It is almost like a view from attention. But it lacks one import function. The bottom "image" does not push the top image to the top if they collide.

I doubt that there is an embedded solution without using private frameworks.


I have achieved this: enter image description here

As you can see two header images in the top overlap. They do not push each other, as usual headings. And I had to deactivate the cell separators. If I used them, they would appear in the whole cell. Therefore, you must draw them yourself. Not so hot thing.

But I have no idea how I can fix the overlap.

Here is the code that did this:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 1; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 44)]; contentView.backgroundColor = [UIColor lightGrayColor]; UIImageView *imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 34, 34)] autorelease]; imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%d", section]];; [contentView addSubview:imageView]; return [contentView autorelease]; } 
+5
source share

Ok, I did something similar to what the music app and search do in the spotlight.

I did not subclass UITableView, I just traced the sections using the scrollViewDidScroll method and added the headers to the left of the tableView (so you will need to put the viewview to the right in the view view view view, which means you cannot use the UITableViewController).

this method should be called in scrollViewDidScroll, ViewDidLoad and in didRotateFromInterfaceOrientation: (if you support rotation)

Keep in mind that you will need to make the space on the left equal to the size of the headers in any orientation of the interface that you support.

 -(void)updateHeadersLocation { for (int sectionNumber = 0; sectionNumber != [self numberOfSectionsInTableView:self.tableView]; sectionNumber++) { // get the rect of the section from the tableview, and convert it to it superview coordinates CGRect rect = [self.tableView convertRect:[self.tableView rectForSection:sectionNumber] toView:[self.tableView superview]]; // get the intersection between the section rect and the view rect, this will help in knowing what portion of the section is showing CGRect intersection = CGRectIntersection(rect, self.tableView.frame); CGRect viewFrame = CGRectZero; // we will start off with zero viewFrame.size = [self headerSize]; // let set the size viewFrame.origin.x = [self headerXOrigin]; /* three cases: 1. the section origin is still showing -> header view will follow the origin 2. the section origin isn't showing but some part of the section still shows -> header view will stick to the top 3. the part of the section that showing is not sufficient for the view height -> will move the header view up */ if (rect.origin.y >= self.tableView.frame.origin.y) { // case 1 viewFrame.origin.y = rect.origin.y; } else { if (intersection.size.height >= viewFrame.size.height) { // case 2 viewFrame.origin.y = self.tableView.frame.origin.y; } else { // case 3 viewFrame.origin.y = self.tableView.frame.origin.y + intersection.size.height - viewFrame.size.height; } } UIView* view = [self.headerViewsDictionary objectForKey:[NSString stringWithFormat:@"%i", sectionNumber]]; // check if the header view is needed if (intersection.size.height == 0) { // not needed, remove it if (view) { [view removeFromSuperview]; [self.headerViewsDictionary removeObjectForKey:[NSString stringWithFormat:@"%i", sectionNumber]]; view = nil; } } else if(!view) { // needed, but not available, create it and add it as a subview view = [self headerViewForSection:sectionNumber]; if (!self.headerViewsDictionary && view) self.headerViewsDictionary = [NSMutableDictionary dictionary]; if (view) { [self.headerViewsDictionary setValue:view forKey:[NSString stringWithFormat:@"%i", sectionNumber]]; [self.view addSubview:view]; } } [view setFrame:viewFrame]; } } 

we also need to declare a property that will retain visible views:

 @property (nonatomic, strong) NSMutableDictionary* headerViewsDictionary; 

these methods return the size and offset of the X axis of the header representations:

 -(CGSize)headerSize { return CGSizeMake(44.0f, 44.0f); } -(CGFloat)headerXOrigin { return 10.0f; } 

I created the code so that all the headers that are not needed are deleted, so we need a method that would return a view if necessary:

 -(UIView*)headerViewForSection:(NSInteger)index { UIImageView* view = [[UIImageView alloc] init]; if (index % 2) { [view setImage:[UIImage imageNamed:@"call"]]; } else { [view setImage:[UIImage imageNamed:@"mail"]]; } return view; } 

this is how it will look:

the section's header is moving out of the screen as it's section does

the section's header is moving with the section's origin

How it will look in lanscape, I used contraindications to give 44px on the left side of the View table

in landscape orientation hope this helps :).

+4
source share

Good news: see answer How to achieve an extended table view header

result http://i.minus.com/jyea3I5qbUdoQ.png

0
source share

All Articles