Skip to content

Commit

Permalink
Update readme, bump version to v2.0.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
kreeger committed Apr 10, 2015
1 parent b039d9c commit a78b6be
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 50 deletions.
4 changes: 2 additions & 2 deletions BDKCollectionIndexView.podspec
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Pod::Spec.new do |s|
s.name = 'BDKCollectionIndexView'
s.version = '1.0.2'
s.version = '2.0.0'
s.summary = "Gives a UICollectionView the sectionIndexTitles scrub bar that a UITableView gets for almost free."
s.homepage = "https://github.com/kreeger/BDKCollectionIndexView"
s.license = { :type => 'MIT', :file => 'license.markdown' }
s.author = { "Ben Kreeger" => "[email protected]" }
s.source = { :git => "https://github.com/kreeger/BDKCollectionIndexView.git", :tag => "v#{s.version}" }
s.platform = :ios, '5.0'
s.platform = :ios, '7.0'
s.source_files = '*.{h,m}'
s.framework = 'QuartzCore'
s.requires_arc = true
Expand Down
89 changes: 41 additions & 48 deletions readme.markdown
Original file line number Diff line number Diff line change
@@ -1,62 +1,46 @@
# BDKCollectionIndexView

> An index-title-scrubber-bar, for use with a `UICollectionView` (or even a `PSTCollectionView`). Gives a collection view the index title bar for `-sectionIndexTitles` that a `UITableView` gets for (almost) free. A huge thank you to @Yang from [this Stack Overflow post][so], which saved my bacon here.
> An index-title-scrubber-bar, for use with a `UICollectionView` or as a replacement for the one provided by a `UITableView`. Gives a collection/table view the index title bar for `-sectionIndexTitles` that a `UITableView` gets for (almost) free. A huge thank you to @Yang from [this Stack Overflow post][so], which saved my bacon here.
## The problem
## Usage

When you're using a `UITableView` and you define the `UITableViewDataSource` method `-sectionIndexTitlesForTableView:`, you get a sweet right-hand-side view for scrubbing through a long table view of fields, separated by sections. The titles are the names of the sections, by default (or at least letters based on the section names).
Drop it in your `Podfile`!

![UITableView with section index titles](http://s3.media.squarespace.com/production/1368321/16106782/_ULITs-nDV7k/TPRg9P_NtHI/AAAAAAAAEi8/gFWaiTD3Ygw/s1600/Apple%2BDefault%2BSection%2BTitle%2BViews.png)

Unfortunately, you get jack when you use a `UICollectionView` (or in my case, a [`PSTCollectionView`][pst]). There's no similar method defined on the `UICollectionViewDataSource` protocol. Stack Overflow to the rescue!

## The solution

This solution was presented by [Yang][ya] on [Stack Overflow][so]. Just roll your own! By subclassing `UIControl`, laying out a series of `UILabel` views in a vertical (or horizontal) fashion, and watching over them with a `UITapGestureRecognizer` and `UIPanGestureRecognizer`, you can get your own `sectionIndexTitles` bar thing. [I've written a gist that covers the header and implementation][gst] in full, based on Yang's proposal. I use it in a controller like so.

``` objective-c
@property (strong, nonatomic) BDKCollectionIndexView *indexView;

- (BDKCollectionIndexView *)indexView {
if (_indexView) return _indexView;
CGFloat indexWidth = 28;
CGRect frame = CGRectMake(CGRectGetWidth(self.collectionView.frame) - indexWidth,
CGRectGetMinY(self.collectionView.frame),
indexWidth,
CGRectGetHeight(self.collectionView.frame));
_indexView = [BDKCollectionIndexView indexViewWithFrame:frame indexTitles:@[]];
_indexView.autoresizingMask = (UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleLeftMargin);
[_indexView addTarget:self
action:@selector(indexViewValueChanged:)
forControlEvents:UIControlEventValueChanged];
return _indexView;
}
```ruby
pod 'BDKCollectionIndexView'
```

When my collection view has loaded data in it, I set the `indexTitles` property of my `self.indexView` (I'm using a `NSFetchedResultsController` in a parent class that also serves a sub-class that manages a `UITableView`; go-go-gadget code reuse!).
And then run `pod install`, naturally. After that, create an instance of `BDKCollectionIndexView`, and add it as a subview of whatever `view` contains your `tableView` or `collectionView` (but not the `tableView` or `collectionView` itself). Then assign it a `width` value of 28 (or `height`, if you're using it as a horizontal index view). Attach whatever other layout constraints you see fit!

```swift
override func viewDidLoad() {
super.viewDidLoad()

let indexWidth = 28
let frame = CGRect(x: collectionView.frame.size.width - indexWidth,
y: collectionView.frame.size.height,
width: indexWidth,
height: collectionView.frame.size.height)
var indexView = BDKCollectionIndexView(frame: frame, indexTitles: nil)
indexView.autoresizingMask = .FlexibleHeight | .FlexibleLeftMargin
indexView.addTarget(self, action: "indexViewValueChanged:", forControlEvents: .ValueChanged)
view.addSubview(indexView)
}

``` objective-c
self.indexView.indexTitles = self.resultsController.sectionIndexTitles;
func indexViewValueChanged(sender: BDKCollectionIndexView) {
let path = NSIndexPath(forItem: 0, inSection: sender.currentIndex)
collectionView.scrollToItemAtIndexPath(path, atScrollPosition: .Top, animated: false)
// If you're using a collection view, bump the y-offset by a certain number of points
// because it won't otherwise account for any section headers you may have.
collectionView.contentOffset = CGPoint(x: collectionView.contentOffset.x,
y: collectionView.contentOffset.y - 45.0)
}
```

Then I merely watch for changes using this method (which was assigned to watch for `UIControlEventValueChanged`).

``` objective-c
- (void)indexViewValueChanged:(BDKCollectionIndexView *)sender {
NSIndexPath *path = [NSIndexPath indexPathForItem:0 inSection:sender.currentIndex];
Then, when you have the section index titles (rather, the label values that you want to appear on the index bar), assign that array to the index bar instance's `indexTitles` value.

// If you're using UICollectionView, substitute "PST" for "UI" and you're all set.
[self.collectionView scrollToItemAtIndexPath:path
atScrollPosition:PSTCollectionViewScrollPositionTop
animated:NO];

// I bump the y-offset up by 45 points here to account for aligning the top of
// the section header view with the top of the collectionView frame. It's
// hardcoded, but you get the idea.
self.collectionView.contentOffset = CGPointMake(self.collectionView.contentOffset.x,
self.collectionView.contentOffset.y - 45);
}
```swift
self.indexView.indexTitles = self.resultsController.sectionIndexTitles
```

Again, big thanks to @Yang for [the solution on which this is based][so].
Expand All @@ -82,5 +66,14 @@ If you use this in your project, drop me a line and let me know! I'd love to hea
[ya]: http://stackoverflow.com/users/45018/yang
[gst]: https://gist.github.com/kreeger/4755877

## Contact

- [Ben Kreeger](https://github.com/kreeger)

## Contributors

- [Adrian Maurer](https://github.com/VerticodeLabs)
- [hipwelljo](https://github.com/hipwelljo)
- [Alex Skorulis](https://github.com/skorulis)
- [Rinat Khanov](https://github.com/rinatkhanov)
- [huperniketes](https://github.com/huperniketes)

0 comments on commit a78b6be

Please sign in to comment.