Spotsis a view controller framework that makes your setup and future development blazingly fast. Because of its internal architecture and generic view models, you can easily move your view models into the cloud. This is super easy to do because Spots can translate JSON data into view model data right out-of-the-box. It is packed with convenience methods that are at your disposal through the public API.
SpotsController
. Spotable
object has their own set of ViewModel
’s. which is maintained internally and is there at your disposable if you decide to make changes to them. UICollectionView
’s, UITableView
's and any custom spot implementation that you add. This improves code reuse and helps to theme your app and ultimately keep your application consistent. Spotable
ViewModel
s. CarouselSpot
, GridSpot
, ListSpot
Spotable
objects. Write one view cell and use it across your application, when and where you want to use it. We wrote a Medium article about how and why we built Spots
. You can find it here: Hitting the sweet spot of inspiration
let controller = SpotsController(json) navigationController?.pushViewController(controller, animated: true)
The JSON data will be parsed into view model data and your view controller is ready to be presented, it is just that easy.
let myContacts = Component(title: "My contacts", items: [ ViewModel(title: "John Hyperseed"), ViewModel(title: "Vadym Markov"), ViewModel(title: "Ramon Gilabert Llop"), ViewModel(title: "Khoa Pham"), ViewModel(title: "Christoffer Winterkvist") ]) let listSpot = ListSpot(component: myContacts) let controller = SpotsController(spots: [listSpot]) navigationController?.pushViewController(controller, animated: true)
The SpotsController
inherits from UIViewController
but it sports some core features that makes your everyday mundane tasks a thing of the past. SpotsController
has four different delegates
public protocol SpotsDelegate: class { func spotDidSelectItem(spot: Spotable, item: ViewModel) func spotsDidChange(spots: [Spotable]) }
spotDidSelectItem
is triggered when a user taps on an item inside of a Spotable
object. It returns both the spot
and the item
to add context to what UI element was touched.
spotsDidChange
notifies the delegate when the internal .spots
property changes.
public protocol SpotsRefreshDelegate: class { func spotsDidReload(refreshControl: UIRefreshControl, completion: (() -> Void)?) }
spotsDidReload
is triggered when a user pulls the SpotsScrollView
offset above its initial bounds.
public protocol SpotsScrollDelegate: class { func spotDidReachBeginning(completion: Completion) func spotDidReachEnd(completion: (() -> Void)?) }
spotDidReachBeginning
notifies the delegate when the scrollview has reached the top. This has a default implementation and is rendered optional for anything that conform to SpotsScrollDelegate
.
spotDidReachEnd
is triggered when the user scrolls to the end of the SpotsScrollView
, this can be used to implement infinite scrolling.
public protocol SpotsCarouselScrollDelegate: class { func spotDidEndScrolling(spot: Spotable, item: ViewModel) }
spotDidEndScrolling
is triggered when a user ends scrolling in a carousel, it returns item that is being displayed and the spot to give you the context that you need.
{ "components":[ { "title":"Hyper iOS", "type":"list", "span":"1", "items":[ { "title":"John Hyperseed", "subtitle":"Build server", "image":"{image url}", "type":"profile", "action":"profile:1", "meta":{ "nationality":"Apple" } }, { "title":"Vadym Markov", "subtitle":"iOS Developer", "image":"{image url}", "type":"profile", "action":"profile:2", "meta":{ "nationality":"Ukrainian" } }, { "title":"Ramon Gilabert Llop", "subtitle":"iOS Developer", "image":"{image url}", "type":"profile", "action":"profile:3", "meta":{ "nationality":"Catalan" } }, { "title":"Khoa Pham", "subtitle":"iOS Developer", "image":"{image url}", "type":"profile", "action":"profile:4", "meta":{ "nationality":"Vietnamese" } }, { "title":"Christoffer Winterkvist", "subtitle":"iOS Developer", "image":"{image url}", "type":"profile", "action":"profile:5", "meta":{ "nationality":"Swedish" } } ] } ] }
public struct Component: Mappable { public var index = 0 public var title = "" public var kind = "" public var span: CGFloat = 0 public var items = [ViewModel]() public var size: CGSize? public var meta = [String : String]() }
UITableView
view. carousel
, list
, grid
are there by default but you can register your own. UICollectionViewFlowLayout
to render UICollectionView
based views. public struct ViewModel: Mappable { public var index = 0 public var title = "" public var subtitle = "" public var image = "" public var kind = "" public var action: String? public var size = CGSize(width: 0, height: 0) public var meta = [String : AnyObject]() }
UITableViewCell
it is normally used for textLabel.text
but you are free to use it as you like. UITableViewCell
it is normally used for detailTextLabel.text
. reuseIdentifier
of your UITableViewCell
or UICollectionViewCell
. UITableViewCell
/ UICollectionViewCell
, or be manually set by the height calculations inside of your view. Spotsis available through CocoaPods . To install it, simply add the following line to your Podfile:
pod 'Spots'
ViewModel
comes from Brick
. Component
and ViewModel
caching when initializing a SpotsController
or Spotable
object with a cache key. Component
and ViewModel
. Hyper made this with
We would love you to contribute to Spots , check theCONTRIBUTING file for more info.
SpotsScrollView
, we salute you. Reference: http://oleb.net/blog/2014/05/scrollviews-inside-scrollviews/ Spotsis available under the MIT license. See the LICENSE file for more info.