OkDataSources
Wrappers for iOS TableView and CollectionView DataSources to simply its api at a minimum. Also it has a cool PagerView and SlidingTabs!
Setup
Add OkDataSources pod to the podfile
pod 'OkDataSources'
For RxSwift extension, this project will include it as a dependency. So you can do this via CocoaPods subspecs.
pod 'OkDataSources'
pod 'OkDataSources/RxSwift'
OkDataSources also is available using Carthage. To install it add the following dependency to your Cartfile
:
github "robertofrontado/OkDataSources"
Usage
OkDataSources provides several dataSources and delegates to deal with iOS TableViews and CollectionViews
TableViews
class TableViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var dataSource: OkTableViewDataSource<Item, TableViewCell>!
override func viewDidLoad() {
super.viewDidLoad()
dataSource = OkTableViewDataSource()
tableView.dataSource = dataSource
}
}
Look that OkTableViewDataSource<Item, TableViewCell>
needs an object and a tableViewCell
(which has to conform OkViewCell protocol)
class TableViewCell: UITableViewCell, OkViewCell {
@IBOutlet weak var valueLabel: UILabel!
func configureItem(item: Item) {
valueLabel.text = item.value
}
}
In the Storyboard the cell needs to have an identifier like this "\(CLASSNAME)" (For instance: TableViewCell)
If you want to receive feedback about items selection, you need to add an OkTableViewDelegate
to your ViewController
, so onItemClicked
block its going to be called every time the user clicks an item.
class TableViewController: UIViewController, OkViewCellDelegate {
@IBOutlet weak var tableView: UITableView!
var dataSource: OkTableViewDataSource<Item, TableViewCell>!
var delegate: OkTableViewDelegate<OkTableViewDataSource<Item, TableViewCell>, TableViewController>!
override func viewDidLoad() {
super.viewDidLoad()
dataSource = OkTableViewDataSource()
delegate = OkTableViewDelegate(dataSource: dataSource,
onItemClicked: { (item, position) in
self.showAlertMessage("\(item.value) clicked")
})
tableView.dataSource = dataSource
tableView.delegate = delegate
}
}
CollectionView
class CollectionViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
var dataSource: OkCollectionViewDataSource<Item, CollectionViewCell>!
override func viewDidLoad() {
super.viewDidLoad()
dataSource = OkCollectionViewDataSource()
collectionView.dataSource = dataSource
}
}
Look that OkCollectionViewDataSource<Item, CollectionViewCell>
needs an object and a collectionViewCell
(which has to conform OkViewCell protocol)
class CollectionViewCell: UICollectionViewCell, OkViewCell {
@IBOutlet weak var valueLabel: UILabel!
func configureItem(item: Item) {
valueLabel.text = item.value
}
}
In the Storyboard the cells needs to have an identifier like this "\(CLASSNAME)" (For instance: CollectionViewCell)
If you want to receive feedback about items selection, you need to add an OkCollectionViewDelegate
to your ViewController
, so onItemClicked
block its going to be called every time the user clicks an item.
class CollectionViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
var dataSource: OkCollectionViewDataSource<Item, CollectionViewCell>!
var delegate: OkCollectionViewDelegate<OkCollectionViewDataSource<Item, CollectionViewCell>, CollectionViewController>!
override func viewDidLoad() {
super.viewDidLoad()
dataSource = OkCollectionViewDataSource()
delegate = OkCollectionViewDelegate(dataSource: dataSource,
onItemClicked: { (item, position) in
self.showAlertMessage("\(item.value) clicked")
})
collectionView.dataSource = dataSource
collectionView.delegate = delegate
}
}
##Also they have PullToRefresh and Pagination functionalities in their OkDelegates
PullToRefresh
Using tableViews
delegate.setOnPullToRefresh(tableView) { (refreshControl) -> Void in
print("refreshed")
// You need to stop the UIRefreshControl manually when you want to
refreshControl.endRefreshing()
}
Using collectionViews
delegate.setOnPullToRefresh(collectionView) { (refreshControl) -> Void in
print("refreshed")
// You need to stop the UIRefreshControl manually when you want to
refreshControl.endRefreshing()
}
Pagination
For tableViews and collectionViews
delegate.setOnPagination { (item) -> Void in
// Ask for more items
}
##For more Customization
If you need a fully customization of DataSource
or Delegate
(TableView
, CollectionView
) you can simply create a class that inherits from them and just override the methods that you need
class ExampleTableViewDataSource: OkTableViewDataSource<Item, TableViewCell> {
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let item = itemAtIndexPath(indexPath)
var cell: TableViewCell!
// Some condition
if indexPath.row == 0 {
cell = tableView.dequeueReusableCellWithIdentifier("Some Custom Identifier 1", forIndexPath: indexPath) as! TableViewCell
} else {
cell = tableView.dequeueReusableCellWithIdentifier("Some Custom Identifier 2", forIndexPath: indexPath) as! TableViewCell
}
cell.configureItem(item)
return cell
}
##RxSwift
There are 2 delegates OkRxTableViewDelegate and OkRxCollectionViewDelegate, use them instead of the regular ones
RxSwift provides extra flavor to the Pagination and PullToRequest functionalities
TableView
delegate = OkRxTableViewDelegate(dataSource: dataSource,
onItemClicked: { (item, position) in
self.showAlertMessage("\(item.value) clicked")
})
delegate.setOnPullToRefresh(tableView) {
return Observable.just(self.getMockItems())
}
delegate.setOnPagination { (item) -> Observable<[Item]> in
return Observable.just(self.getMockItems(self.dataSource.items.count))
}
CollectionView
delegate = OkRxCollectionViewDelegate(dataSource: dataSource,
onItemClicked: { (item, position) in
self.showAlertMessage("\(item.value) clicked")
})
delegate.setOnPullToRefresh(collectionView) {
return Observable.just(self.getMockItems())
}
delegate.setOnPagination { (item) -> Observable<[Item]> in
return Observable.just(self.getMockItems(self.dataSource.items.count))
}
PagerView
Here is an example PagerViewController
The most convinient way is to use Storyboard. Drag a view to Storyboard and set Class to OkPagerView
Your ViewController will need to implement the OkPagerViewDataSource protocol
public protocol OkPagerViewDataSource {
func viewControllerAtIndex(index: Int) -> UIViewController?
func numberOfPages() -> Int?
}
And if you want, there is a OkPagerViewDelegate protocol
public protocol OkPagerViewDelegate {
func onPageSelected(viewController: UIViewController, index: Int)
}
SlidingTabs
Here is an example PagerViewController
The most convinient way is to use Storyboard. Drag a view to Storyboard and set Class to OkSlidingTabs
You can customize this attributes through the Storyboard:
xPadding: CGFloat
xMargin: CGFloat
labelTextColor: UIColor
labelBgColor: UIColor
indicatorColor: UIColor
indicatorHeight: CGFloat
distributeEvenly: Bool
And If you want to use a different font you'll need to do:
slidingTabs.font = newFont
Your ViewController will need to implement the OkSlidingTabsDataSource protocol
public protocol OkSlidingTabsDataSource {
func numberOfTabs() -> Int
func titleAtIndex(index: Int) -> String
}
And if you want, there is a OkSlidingTabsDelegate protocol
public protocol OkSlidingTabsDelegate {
func onTabSelected(index: Int)
}
##Credits This approach is based on https://github.com/Karumi/BothamUI