Search code examples
iosios5ios6uicollectionview

SectionIndexTitles for a UICollectionView


So I implemented a proper TableView with a search functionality and sectionIndexTitles. Now, I am trying to implement a UICollectionView and it is working so far, except that I can't easily have sectionIndexTitles (the right scroll bar).

If I look at the Facebook Application, it looks like a UICollectionView, but with indeed sectionIndexTitles and a searchbar. I can't seem to find such functions for the UICollectionView model.

Any ideas?!

Thanks!

enter image description here


Solution

  • I had a similar requirement (for a horizontal collection view) and ended up building an index view subclass myself.

    I plan to open-source it but that will likely have to wait until next month, so here's a stub to get you started:

    YMCollectionIndexView.h

    @interface YMCollectionIndexView : UIControl
    
    - (id) initWithFrame:(CGRect)frame indexTitles:(NSArray *)indexTitles;
    
    // Model
    @property (strong, nonatomic) NSArray *indexTitles; // NSString
    @property (readonly, nonatomic) NSUInteger currentIndex;
    - (NSString *)currentIndexTitle;
    
    @end
    

    YMCollectionIndexView.m

    #import "YMCollectionIndexView.h"
    
    @interface YMCollectionIndexView ()
    @property (readwrite, nonatomic) NSUInteger currentIndex;
    @property (strong, nonatomic) NSArray *indexLabels;
    @end
    
    @implementation YMCollectionIndexView
    
    - (id) initWithFrame:(CGRect)frame indexTitles:(NSArray *)indexTitles {
        self = [super initWithFrame:frame];
        if (self) {
            self.indexTitles = indexTitles;
            self.currentIndex = 0;
            // add pan recognizer
        }
        return self;
    }
    
    - (void)setIndexTitles:(NSArray *)indexTitles {
        if (_indexTitles == indexTitles) return;
        _indexTitles = indexTitles;
        [self.indexLabels makeObjectsPerformSelector:@selector(removeFromSuperview)];
        [self buildIndexLabels];
    }
    
    - (NSString *)currentIndexTitle {
        return self.indexTitles[self.currentIndex];
    }
    
    #pragma mark - Subviews
    
    - (void) buildIndexLabels {
        CGFloat cumulativeItemWidth = 0.0; // or height in your (vertical) case
        for (NSString *indexTitle in self.indexTitles) {
                // build and add label
            // add tap recognizer
        }
        self.indexLabels = indexLabels;
    }
    
    #pragma mark - Gestures
    
    - (void) handleTap:(UITapGestureRecognizer*)recognizer {
        NSString *indexTitle = ((UILabel *)recognizer.view).text;
        self.currentIndex = [self.indexTitles indexOfObject:indexTitle];
        [self sendActionsForControlEvents:UIControlEventTouchUpInside];
    }
    
    // similarly for pan recognizer
    
    @end
    

    In your view controller:

    - (void)viewDidLoad {
        [super viewDidLoad];
        [self.collectionIndexView addTarget:self action:@selector(indexWasTapped:) forControlEvents:UIControlEventTouchUpInside];
        // similarly for pan recognizer
    }
    
    - (void)indexWasTapped:(id)sender {
        [self.collectionView scrollToIndexPath:...];
    }
    
    // similarly for pan recognizer