Function not triggering on scroll - ios

I am trying to trigger a certain function in a collection view when I scroll. Basically Im trying to implement pagination so that when it scrolls to the bottom more items are loaded.
override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if indexPath.item >= allEvents.count - 1 {
// print("paginating for post")
paginationHelper.paginate(completion: { [unowned self] (events) in
self.allEvents.append(contentsOf: events)
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
})
}else{
print("Not paginating")
}
}
This is the entire Function
import Foundation
import UIKit
import Alamofire
import AlamofireNetworkActivityIndicator
import SwiftLocation
import CoreLocation
import AMScrollingNavbar
class HomeFeedController: UICollectionViewController, UICollectionViewDelegateFlowLayout,UIGestureRecognizerDelegate {
// let dropDownLauncher = DropDownLauncher()
var isFinishedPaging = false
let detailView = EventDetailViewController()
let refreshControl = UIRefreshControl()
var emptyLabel: UILabel?
var allEvents = [Event]()
//will containt array of event keys
var eventKeys = [String]()
let customCellIdentifier = "customCellIdentifier"
var grideLayout = GridLayout(numberOfColumns: 2)
lazy var dropDownLauncer : DropDownLauncher = {
let launcer = DropDownLauncher()
launcer.homeFeed = self
return launcer
}()
let paginationHelper = PaginationHelper<Event>(serviceMethod: PostService.showEvent)
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = UIColor.white
collectionView?.collectionViewLayout = grideLayout
collectionView?.reloadData()
self.collectionView?.contentInset = UIEdgeInsetsMake(15, 0, 0, 0)
navigationItem.title = "Home"
collectionView?.register(CustomCell.self, forCellWithReuseIdentifier: customCellIdentifier)
// self.navigationItem.hidesBackButton = true
let backButton = UIBarButtonItem(image: UIImage(named: "menu"), style: .plain, target: self, action: #selector(handleDropDownMenu))
self.navigationItem.leftBarButtonItem = backButton
// PostService.showEvent(location: User.current.location!) { (event) in
// self.allEvents = event
// print(self.allEvents)
//
// DispatchQueue.main.async {
// self.collectionView?.reloadData()
// }
// }
configureCollectionView()
reloadHomeFeed()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let navigationController = self.navigationController as? ScrollingNavigationController {
navigationController.followScrollView(self.collectionView!, delay: 50.0)
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if let navigationController = navigationController as? ScrollingNavigationController {
navigationController.stopFollowingScrollView()
}
}
override func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
if let navigationController = navigationController as? ScrollingNavigationController {
navigationController.showNavbar(animated: true)
}
return true
}
func handleDropDownMenu(){
dropDownLauncer.showDropDown()
}
//will query by selected category
func categoryFetch(dropDown: DropDown){
navigationItem.title = dropDown.name
paginationHelper.category = dropDown.name
configureCollectionView()
reloadHomeFeed()
}
func reloadHomeFeed() {
self.paginationHelper.reloadData(completion: { [unowned self] (events) in
self.allEvents = events
if self.refreshControl.isRefreshing {
self.refreshControl.endRefreshing()
}
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
})
}
func configureCollectionView() {
// add pull to refresh
refreshControl.addTarget(self, action: #selector(reloadHomeFeed), for: .valueChanged)
collectionView?.addSubview(refreshControl)
}
// need to tell it how many cells to have
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return allEvents.count
}
// need to tell the collection view controller what type of cell we want to return
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let customCell = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier, for: indexPath) as! CustomCell
let imageURL = URL(string: allEvents[indexPath.item].currentEventImage)
print(imageURL ?? "")
customCell.sampleImage.af_setImage(withURL: imageURL!)
return customCell
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//let selectedEvent = self.imageArray[indexPath.row]
//let eventDetailVC
if let cell = collectionView.cellForItem(at: indexPath){
// print("Look here for event name")
// print(detailView.eventName)
detailView.eventKey = allEvents[indexPath.row].key!
detailView.eventPromo = allEvents[indexPath.row].currentEventPromo!
detailView.currentEvent = allEvents[indexPath.row]
present(detailView, animated: true, completion: nil)
//self.navigationController?.pushViewController(detailView, animated: true)
}
print("Cell \(indexPath.row) selected")
}
override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if indexPath.item >= allEvents.count - 1 {
// print("paginating for post")
paginationHelper.paginate(completion: { [unowned self] (events) in
self.allEvents.append(contentsOf: events)
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
})
}else{
print("Not paginating")
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
//will make surepictures keep same orientation even if you flip screen
// will most likely lock into portrait mode but still good to have
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
grideLayout.invalidateLayout()
}
//Will allow the first two cells that are displayed to be of varying widths
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if indexPath.item == 0 || indexPath.item == 1 {
return CGSize(width: view.frame.width, height: grideLayout.itemSize.height)
}else{
return grideLayout.itemSize
}
}
func showLeftView(sender: AnyObject?){
print("Button Pressed")
// sideMenuController?.leftViewController = LeftViewController()
//sideMenuController?.showLeftView(animated: true, completionHandler: nil)
}
}
//responsible for populating each cell with content
class CustomCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
let sampleImage: UIImageView = {
let firstImage = UIImageView()
firstImage.clipsToBounds = true
firstImage.translatesAutoresizingMaskIntoConstraints = false
firstImage.contentMode = .scaleToFill
firstImage.layer.masksToBounds = true
return firstImage
}()
let nameLabel: UILabel = {
let name = UILabel()
name.text = "Custom Text"
name.translatesAutoresizingMaskIntoConstraints = false
return name
}()
func setupViews() {
addSubview(sampleImage)
backgroundColor = UIColor.white
//addSubview(nameLabel)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": sampleImage]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": sampleImage]))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// responsible for creating the grid layout that you see in the home view feed
class GridLayout: UICollectionViewFlowLayout {
var numberOfColumns:Int = 2
init(numberOfColumns: Int) {
super.init()
// controlls spacing inbetween them as well as spacing below them to next item
self.numberOfColumns = numberOfColumns
self.minimumInteritemSpacing = 3
self.minimumLineSpacing = 5
}
// just needs to be here because swift tells us to
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var itemSize: CGSize{
get{
if collectionView != nil {
let collectionVieweWidth = collectionView?.frame.width
let itemWidth = (collectionVieweWidth!/CGFloat(self.numberOfColumns)) - self.minimumInteritemSpacing
let itemHeight: CGFloat = 200
return CGSize(width: itemWidth, height: itemHeight)
}
return CGSize(width: 100, height: 100)
}set{
super.itemSize = newValue
}
}
}
This is the function that is responsible for triggering the event but it seems to go to the else statement literally every time. Any insight would be helpful

Related

UICollectionView disappear when refreshing after pop back

I have a problem when pull-to-refresh with UICollectionView. The refreshing control work well but when I click on a cell, push another view controller, and pop back, try refreshing, UICollectionView is disappeared( I don't use storyboard).
Screen record video:
https://www.youtube.com/watch?v=3bsaqqv6x_8
Here is my code:
AccountController
class AccountController: UICollectionViewController, UICollectionViewDelegateFlowLayout{
var menuData: [Any]? {
didSet{
self.collectionView?.reloadData()
}
}
let collectionLayout = UICollectionViewFlowLayout()
let refreshControl = UIRefreshControl()
override func viewDidLoad() {
...
setupCollectionView()
self.collectionView?.isHidden = false
refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged)
collectionView!.addSubview(refreshControl)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
super.collectionViewLayout.invalidateLayout()
}
func setupCollectionView(){
self.collectionView?.isHidden = true
collectionView?.backgroundColor = UIColor(white: 0.95, alpha: 1)
collectionView?.alwaysBounceVertical = true
collectionView?.register(MenuCell.self, forCellWithReuseIdentifier: cellId)
collectionView?.register(MenuSupplementary.self, forCellWithReuseIdentifier: supplementaryId)
collectionLayout.minimumLineSpacing = 0
collectionView?.collectionViewLayout = collectionLayout
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let count = menuData?.count {
return count
}
return 0
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let dt = menuData?[indexPath.item] {
if dt is MenuCellData{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuCell
cell.data = dt as? MenuCellData
return cell
}
if dt is MenuSupplementaryData {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: supplementaryId, for: indexPath) as! MenuSupplementary
cell.data = dt as? MenuSupplementaryData
return cell
}
}
return UICollectionViewCell()
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize.init(width: view.frame.width, height: 45)
}
#objc func refresh(sender:UIRefreshControl){
let api = AccountApi(jwt: appDelegate.userDefault.string(forKey: "jwt"))
api.getMenuData { (data) in
var dt: [Any] = []
if data.isEmpty { return }
for d in data as! [MenuData] {
if d.type == "supplementary" {
dt.append(MenuSupplementaryData( d.text ))
}
if d.type == "cell" {
dt.append(MenuCellData(d.icon!, d.text, isTheLastItem: d.isTheLastItem ?? false, url: d.url, httpMethod: d.httpMethod ))
}
}
if !dt.isEmpty {
self.menuData = dt
}
sender.endRefreshing()
}
}
}
TabBarController
class TabBarController: UITabBarController, UITabBarControllerDelegate {
...
private func setUpNavControllerFrom(viewController: UIViewController, title: String, imageName: String)-> UINavigationController{
let navController = UINavigationController(rootViewController: viewController)
navController.tabBarItem.title = title
navController.tabBarItem.image = UIImage(named: imageName)
let imageView = UIImageView.init(frame: CGRect())
imageView.image = UIImage(named: "logo")
imageView.contentMode = .scaleAspectFit
imageView.heightAnchor.constraint(equalToConstant: 20).isActive = true // Set logo height
viewController.navigationItem.titleView = imageView
navController.navigationBar.barTintColor = themeColor
return navController
}
// Set up color, logo, font ...
private func setupViewControllers(){
tabBar.tintColor = UIColor.white
tabBar.barTintColor = themeColor
let accountVC = AccountController(collectionViewLayout: UICollectionViewFlowLayout())
let accNavController = setUpNavControllerFrom(viewController: accountVC, title: "Account", imageName: "account-icon")
...
}
}
Additional info:
Refreshing without pop back: numberOfItemsInSection, cellForItemAt, sizeForItemAt of delegate is invoked when call collectionView?.reloadData().
But, when refreshing after pop back, cellForItemAt, sizeForItemAt of delegate is not invoked when call collectionView?.reloadData().
Thanks for help!
Thanks for trying help me!
I finally find out my mistake.
When handling menu is selected, I create new controller with current collectionViewLayout, and I think this current layout is changed when pop back, make menu is disappeared.
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let dt = menuData?[indexPath.item]{
if dt is MenuCellData {
let d = dt as! MenuCellData
// let controller = AccountMenuController(collectionViewLayout: collectionView.collectionViewLayout)
let controller = AccountMenuController(collectionViewLayout: UICollectionViewLayout())
controller.menuData = d
navigationController?.pushViewController(controller, animated: true)
}
}
}

CollectionView not registering cells

I have a viewController with a collectionView inside of it. I'm pretty sure that I have configured everything right yet it is not rendering any cells. I have added the appropriate delegates and data sources and double checked to see if the data is loading and it is but cells are not being populated
import UIKit
import UIKit
import Alamofire
import AlamofireNetworkActivityIndicator
import SwiftLocation
import CoreLocation
import AMScrollingNavbar
class NewHomeFeedControllerViewController: UIViewController {
let detailView = EventDetailViewController()
var allEvents = [Event]()
let customCellIdentifier1 = "customCellIdentifier1"
var grideLayout = GridLayout(numberOfColumns: 2)
let refreshControl = UIRefreshControl()
var newHomeFeed: NewHomeFeedControllerViewController?
let paginationHelper = PaginationHelper<Event>(serviceMethod: PostService.showEvent)
lazy var dropDownLauncer : DropDownLauncher = {
let launcer = DropDownLauncher()
launcer.newHomeFeed = self
return launcer
}()
// 1 IGListKit uses IGListCollectionView, which is a subclass of UICollectionView, which patches some functionality and prevents others.
let collectionView: UICollectionView = {
// 2 This starts with a zero-sized rect since the view isn’t created yet. It uses the UICollectionViewFlowLayout just as the ClassicFeedViewController did.
let view = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout())
// 3 The background color is set to white
view.backgroundColor = UIColor.white
return view
}()
func handleDropDownMenu(){
dropDownLauncer.showDropDown()
}
func configureCollectionView() {
// add pull to refresh
refreshControl.addTarget(self, action: #selector(reloadHomeFeed), for: .valueChanged)
collectionView.addSubview(refreshControl)
}
func reloadHomeFeed() {
self.paginationHelper.reloadData(completion: { [unowned self] (events) in
self.allEvents = events
if self.refreshControl.isRefreshing {
self.refreshControl.endRefreshing()
}
DispatchQueue.main.async {
self.collectionView.reloadData()
}
})
}
func categoryFetch(dropDown: DropDown){
navigationItem.title = dropDown.name
paginationHelper.category = dropDown.name
configureCollectionView()
reloadHomeFeed()
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
collectionView.contentInset = UIEdgeInsetsMake(15, 0, 0, 0)
navigationItem.title = "Home"
collectionView.dataSource = self
collectionView.delegate = self
collectionView.collectionViewLayout = grideLayout
collectionView.reloadData()
collectionView.register(CustomCell.self, forCellWithReuseIdentifier: customCellIdentifier1)
// self.navigationItem.hidesBackButton = true
let backButton = UIBarButtonItem(image: UIImage(named: "menu"), style: .plain, target: self, action: #selector(handleDropDownMenu))
self.navigationItem.leftBarButtonItem = backButton
configureCollectionView()
reloadHomeFeed()
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let navigationController = self.navigationController as? ScrollingNavigationController {
navigationController.followScrollView(self.collectionView, delay: 50.0)
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if let navigationController = navigationController as? ScrollingNavigationController {
navigationController.stopFollowingScrollView()
}
}
func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
if let navigationController = navigationController as? ScrollingNavigationController {
navigationController.showNavbar(animated: true)
}
return true
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
grideLayout.invalidateLayout()
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
extension NewHomeFeedControllerViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return allEvents.count
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let customCell = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier1, for: indexPath) as! CustomCell
let imageURL = URL(string: allEvents[indexPath.item].currentEventImage)
print(imageURL ?? "")
customCell.sampleImage.af_setImage(withURL: imageURL!)
return customCell
}
}
extension NewHomeFeedControllerViewController: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if indexPath.item == 0 || indexPath.item == 1 {
return CGSize(width: view.frame.width, height: grideLayout.itemSize.height)
}else{
return grideLayout.itemSize
}
}
}
Any idea what could be going on?
Sorry you guys forgot to add this
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.frame = view.bounds
}
Haha thanks for the help

CollectionView infinite scroll in Swift with Json parse

I wrote the code for collectionView infinite scroll with json parse. Next want to view 20 data each time. After print 20data i will show footer.
Now it is going to view all data in a time. Json parse is ok, also footer view is ok. But the problem is infinite-scroll is not working at all.
Here is my all code:
import Foundation
import UIKit
enum LoadMoreStatus{
case loading
case finished
case haveMore
}
class Product: NSObject {
var id: Int?
var category_id: Int?
var image: String?
var name: String?
var ar_name: String?
var ar_description: String?
var price: NSNumber?
var quantity: String?
var is_featured: String?
var seller_id: String?
var payment_required: String?
var is_editors_choice: String?
var created_at: String?
var updated_at: String?
}
let categoryCellid = "categoryCellid"
class ProductByCategoryCollectionView: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var headercellId = "headercellId"
var footerCellid = "firstfootercellid"
var numberOfCells = 5
var loadingStatus = LoadMoreStatus.haveMore
var arrProduct = [Product]()
var category_id:Int = 0;
var product_count:Int = 0;
func reloadData(){
collectionView?.reloadData()
if numberOfCells > 0 {
collectionView?.scrollToItem(at: IndexPath(row: 0, section: 0), at: .left, animated: true)
}
}
func loadMore() {
if numberOfCells >= arrProduct.count{ // here will show untill 22
loadingStatus = .finished
collectionView?.reloadData()
return
}
Timer.schedule(delay: 2) { timer in
self.numberOfCells += 10
self.collectionView?.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.getPropductListByCategory()
collectionView?.backgroundColor = .white
navigationItem.title = "Product"
navigationItem.backBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: nil, action: nil)
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Sort By", style: .plain, target: nil, action: nil)
self.setupHeaderView()
collectionView?.register(ProductByCategoryCollectionViewCell.self, forCellWithReuseIdentifier: categoryCellid)
collectionView?.register(ProductByCategoryFooterCell.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: footerCellid)
}
override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
var text=""
switch UIDevice.current.orientation{
case .portrait:
text="Portrait"
case .portraitUpsideDown:
text="PortraitUpsideDown"
case .landscapeLeft:
text="LandscapeLeft"
case .landscapeRight:
text="LandscapeRight"
default:
text="Another"
}
NSLog("You have moved: \(text)")
collectionView?.reloadData()
}
func showCategoryDetailSegue() {
let detailcontroller = UIViewController()
navigationController?.pushViewController(detailcontroller, animated: true)
}
func sortBtnTarget() {
}
func filterBtnTarget() {
}
let dividedLine: UIView = {
let view = UIView()
view.backgroundColor = UIColor(white: 0.4, alpha: 0.4)
return view
}()
let totalItemLabel: UILabel = {
let label = UILabel()
label.text = ""
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 15)
label.backgroundColor = UIColor.white
return label
}()
let dividerLineView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.white
return view
}()
func setupHeaderView(){
view.backgroundColor = UIColor(white: 0.4, alpha: 0.4)
dividedLine.frame = CGRect(x: 0, y: 95, width: view.frame.width, height: 1)
totalItemLabel.frame = CGRect(x: 0, y: 55, width: view.frame.width, height: 40)
view.addSubview(totalItemLabel)
view.addSubview(dividedLine)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrProduct.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if(indexPath.row==arrProduct.count-1){
if loadingStatus == .haveMore {
self.perform(#selector(ProductByCategoryCollectionView.loadMore), with: nil, afterDelay: 0)
}
}
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: categoryCellid, for: indexPath) as! ProductByCategoryCollectionViewCell
cell.callProductObject4Cell = arrProduct[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 172, height: 300)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(32, 10, 0, 10)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let controller1 = UICollectionViewController(collectionViewLayout: layout)
navigationController?.pushViewController(controller1, animated: true)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
collectionView?.collectionViewLayout.invalidateLayout()
}
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
var footerView:ProductByCategoryFooterCell!
if (kind == UICollectionElementKindSectionFooter) && (loadingStatus != .finished){
footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: footerCellid, for: indexPath) as! ProductByCategoryFooterCell
}
return footerView
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return (loadingStatus == .finished) ? CGSize.zero : CGSize(width: self.view.frame.width, height: 50)
}
}
class ProductByCategoryCollectionViewCell: UICollectionViewCell {
var callProductObject4Cell: Product?{
didSet {
productLabel.text = callProductObject4Cell?.name
if let price = callProductObject4Cell?.price {
//priceLabel.text = "$\(price)"
priceLabel.text = "\(price) TK"
} else {
priceLabel.text = ""
}
if let profileImageUrl = callProductObject4Cell?.image {
productImage.loadImageUsingUrlString(profileImageUrl)
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setupcategoryCell()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let productImage: UIImageView = {
let image = UIImageView()
image.image = UIImage(named: "default")
image.contentMode = .scaleAspectFit
image.layer.borderWidth = 1
image.layer.borderColor = UIColor.orange.cgColor
image.layer.masksToBounds = true
return image
}()
let productLabel: UILabel = {
let label = UILabel()
label.text = "productName"
label.textColor = .black
label.numberOfLines = 0
label.font = UIFont.boldSystemFont(ofSize: 10)
return label
}()
let priceLabel: UILabel = {
let label = UILabel()
// label.backgroundColor = .lightGray
label.text = ""
label.textColor = .orange
label.font = UIFont.systemFont(ofSize: 13)
return label
}()
func setupcategoryCell() {
addSubview(productImage)
addSubview(productLabel)
addSubview(priceLabel)
addConstraintsWithFormat("H:|[v0]|", views: productImage)
addConstraintsWithFormat("V:|[v0(230)]-2-[v1][v2(10)]-5-|", views: productImage,productLabel, priceLabel)
addConstraintsWithFormat("H:|[v0]|", views: productLabel)
addConstraintsWithFormat("H:|[v0]|", views: priceLabel)
}
}
class ProductByCategoryFooterCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .white
setupCell()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let menuHeaderLabel: UILabel = {
let label = UILabel()
label.text = "loadin more waiting"
label.textColor = .green
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 15)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
func setupCell() {
addSubview(menuHeaderLabel)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-8-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": menuHeaderLabel]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-5-[v0(30)]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": menuHeaderLabel]))
}
}
extension Timer {
class func schedule(delay: TimeInterval, handler: #escaping (Timer!) -> Void) -> Timer {
let fireDate = delay + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, 0, 0, 0, handler)
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer!
}
class func schedule(repeatInterval interval: TimeInterval, handler: #escaping (Timer!) -> Void) -> Timer {
let fireDate = interval + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, interval, 0, 0, handler)
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer!
}
}
enum LoadMoreStatus {
case loading
case finished
case haveMore
}
class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var verticalDataSource = [String]()
var firstCellid = "firstcellid"
var firstFooterCellid = "firstfootercellid"
var numberOfCells = 5
var loadingStatus = LoadMoreStatus.haveMore
func reloadData() {
//numberOfCells = 10
collectionView?.reloadData()
if numberOfCells > 0 {
collectionView?.scrollToItem(at: IndexPath(row: 0, section: 0), at: .left, animated: true)
}
}
func loadMore() {
if numberOfCells >= 40 {
// here will show untill finished number
loadingStatus = .finished
collectionView?.reloadData()
return
}
// Replace code with web service and append to data source
Timer.schedule(delay: 2) { timer in
self.numberOfCells += 2
self.collectionView?.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
collectionView?.register(VerticalCollectionViewCell.self, forCellWithReuseIdentifier: firstCellid)
collectionView?.register(VerticalCollectionViewCell2.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: firstFooterCellid)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK - Rotation methods
override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
var text=""
switch UIDevice.current.orientation {
case .portrait:
text="Portrait"
case .portraitUpsideDown:
text="PortraitUpsideDown"
case .landscapeLeft:
text="LandscapeLeft"
case .landscapeRight:
text="LandscapeRight"
default:
text="Another"
}
NSLog("You have moved: \(text)")
collectionView?.reloadData()
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numberOfCells
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if(indexPath.row==numberOfCells-1) {
if loadingStatus == .haveMore {
self.perform(#selector(ViewController.loadMore), with: nil, afterDelay: 0)
}
}
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: firstCellid, for: indexPath) as! VerticalCollectionViewCell
cell.menuHeaderLabel.text = "Labet text no \(indexPath.item)"
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.view.frame.width, height: 100)
}
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
var footerView:VerticalCollectionViewCell2!
if (kind == UICollectionElementKindSectionFooter) && (loadingStatus != .finished) {
footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: firstFooterCellid, for: indexPath) as! VerticalCollectionViewCell2
}
return footerView
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return (loadingStatus == .finished) ? CGSize.zero : CGSize(width: self.view.frame.width, height: 50)
}
}
class VerticalCollectionViewCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupCell()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let menuHeaderLabel: UILabel = {
let label = UILabel()
label.text = "lable text"
label.textColor = .orange
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 15)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
func setupCell() {
addSubview(menuHeaderLabel)
// addTaskButton.addTarget(self, action: #selector(MenuHeader.addTask), for: .touchUpInside)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-8-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": menuHeaderLabel]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-5-[v0(30)]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": menuHeaderLabel]))
}
}

Infinite Scroll in collectionView swift programmatically

i want to infinite scrolling 10 images in collectionView programmatically of swift. the image came from web by json according to my choice. i have been unable to scrolling 20 image in a times.
here is my code
import Foundation
import UIKit
let categoryCellid = "categoryCellid"
class ProductByCategoryCollectionView: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var headercellId = "headercellId"
var callCategoryObject = [Product]()
func getPropductListByCategory(){
// has api code, that was well
}
override func viewDidLoad() {
super.viewDidLoad()
self.getPropductListByCategory()
collectionView?.backgroundColor = .white
navigationItem.title = "Product"
navigationItem.backBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: nil, action: nil)
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Sort By", style: .plain, target: nil, action: nil)
self.setupHeaderView()
collectionView?.register(ProductByCategoryCollectionViewCell.self, forCellWithReuseIdentifier: categoryCellid)
}
func showCategoryDetailSegue() {
let detailcontroller = UIViewController()
navigationController?.pushViewController(detailcontroller, animated: true)
}
func sortBtnTarget() {
}
func filterBtnTarget() {
}
let dividedLine: UIView = {
let view = UIView()
view.backgroundColor = UIColor(white: 0.4, alpha: 0.4)
return view
}()
let totalItemLabel: UILabel = {
let label = UILabel()
label.text = ""
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 15)
label.backgroundColor = UIColor.white
return label
}()
let dividerLineView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.white
return view
}()
func setupHeaderView(){
view.backgroundColor = UIColor(white: 0.4, alpha: 0.4)
dividedLine.frame = CGRect(x: 0, y: 95, width: view.frame.width, height: 1)
totalItemLabel.frame = CGRect(x: 0, y: 55, width: view.frame.width, height: 40)
view.addSubview(totalItemLabel)
view.addSubview(dividedLine)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return callCategoryObject.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: categoryCellid, for: indexPath) as! ProductByCategoryCollectionViewCell
cell.callProductObject4Cell = callCategoryObject[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 172, height: 300)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(32, 10, 0, 10)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let controller1 = DetailsController(collectionViewLayout: layout)
navigationController?.pushViewController(controller1, animated: true)
}
}
class ProductByCategoryCollectionViewCell: UICollectionViewCell {
var callProductObject4Cell: Product? {
didSet {
productLabel.text = callProductObject4Cell?.name
// priceLabel.text = String(describing: callProductObject4Cell?.price)
if let price = callProductObject4Cell?.price {
priceLabel.text = "$\(price)"
} else {
priceLabel.text = ""
}
if let profileImageUrl = callProductObject4Cell?.image {
productImage.loadImageUsingUrlString(profileImageUrl)
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setupcategoryCell()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let productImage: UIImageView = {
let image = UIImageView()
image.image = UIImage(named: "default")
image.contentMode = .scaleAspectFit
image.layer.borderWidth = 1
image.layer.borderColor = UIColor.orange.cgColor
image.layer.masksToBounds = true
return image
}()
let productLabel: UILabel = {
let label = UILabel()
label.text = "productName"
label.textColor = .black
label.numberOfLines = 0
label.font = UIFont.boldSystemFont(ofSize: 10)
return label
}()
let priceLabel: UILabel = {
let label = UILabel()
// label.backgroundColor = .lightGray
label.text = ""
label.textColor = .orange
label.font = UIFont.systemFont(ofSize: 13)
return label
}()
func setupcategoryCell() {
addSubview(productImage)
addSubview(productLabel)
addSubview(priceLabel)
addConstraintsWithFormat("H:|[v0]|", views: productImage)
addConstraintsWithFormat("V:|[v0(230)]-2-[v1][v2(10)]-5-|", views: productImage,productLabel, priceLabel)
addConstraintsWithFormat("H:|[v0]|", views: productLabel)
addConstraintsWithFormat("H:|[v0]|", views: priceLabel)
}
}
Use this code for an infinite UIScrollView:
import Foundation
import UIKit
enum LoadMoreStatus {
case loading
case finished
case haveMore
}
class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var verticalDataSource = [String]()
var firstCellid = "firstcellid"
var firstFooterCellid = "firstfootercellid"
var numberOfCells = 5
var loadingStatus = LoadMoreStatus.haveMore
func reloadData() {
//numberOfCells = 10
collectionView?.reloadData()
if numberOfCells > 0 {
collectionView?.scrollToItem(at: IndexPath(row: 0, section: 0), at: .left, animated: true)
}
}
func loadMore() {
if numberOfCells >= 40 {
// here will show untill finished number
loadingStatus = .finished
collectionView?.reloadData()
return
}
// Replace code with web service and append to data source
Timer.schedule(delay: 2) { timer in
self.numberOfCells += 2
self.collectionView?.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
collectionView?.register(VerticalCollectionViewCell.self, forCellWithReuseIdentifier: firstCellid)
collectionView?.register(VerticalCollectionViewCell2.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: firstFooterCellid)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK - Rotation methods
override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
var text=""
switch UIDevice.current.orientation {
case .portrait:
text="Portrait"
case .portraitUpsideDown:
text="PortraitUpsideDown"
case .landscapeLeft:
text="LandscapeLeft"
case .landscapeRight:
text="LandscapeRight"
default:
text="Another"
}
NSLog("You have moved: \(text)")
collectionView?.reloadData()
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numberOfCells
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if(indexPath.row==numberOfCells-1) {
if loadingStatus == .haveMore {
self.perform(#selector(ViewController.loadMore), with: nil, afterDelay: 0)
}
}
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: firstCellid, for: indexPath) as! VerticalCollectionViewCell
cell.menuHeaderLabel.text = "Labet text no \(indexPath.item)"
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.view.frame.width, height: 100)
}
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
var footerView:VerticalCollectionViewCell2!
if (kind == UICollectionElementKindSectionFooter) && (loadingStatus != .finished) {
footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: firstFooterCellid, for: indexPath) as! VerticalCollectionViewCell2
}
return footerView
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return (loadingStatus == .finished) ? CGSize.zero : CGSize(width: self.view.frame.width, height: 50)
}
}
class VerticalCollectionViewCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupCell()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let menuHeaderLabel: UILabel = {
let label = UILabel()
label.text = "lable text"
label.textColor = .orange
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 15)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
func setupCell() {
addSubview(menuHeaderLabel)
// addTaskButton.addTarget(self, action: #selector(MenuHeader.addTask), for: .touchUpInside)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-8-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": menuHeaderLabel]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-5-[v0(30)]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": menuHeaderLabel]))
}
}
class VerticalCollectionViewCell2: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .white
setupCell()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let menuHeaderLabel: UILabel = {
let label = UILabel()
label.text = "loadin more waiting"
label.textColor = .green
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 15)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
func setupCell() {
addSubview(menuHeaderLabel)
// addTaskButton.addTarget(self, action: #selector(MenuHeader.addTask), for: .touchUpInside)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-8-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": menuHeaderLabel]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-5-[v0(30)]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": menuHeaderLabel]))
}
}
extension Timer {
class func schedule(delay: TimeInterval, handler: #escaping (Timer!) -> Void) -> Timer {
let fireDate = delay + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, 0, 0, 0, handler)
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer!
}
class func schedule(repeatInterval interval: TimeInterval, handler: #escaping (Timer!) -> Void) -> Timer {
let fireDate = interval + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, interval, 0, 0, handler)
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer!
}
}

Thread 5: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) - Cast from 'Result<AnyObject>' to unrelated type 'NSDictionary' always fail

I am following the Ray Wenderlich tutorial on Alamofire (and struggling), http://www.raywenderlich.com/85080/beginning-alamofire-tutorial#comments , and I am getting the error in the title, in the "loading more photos" part.
The error is on the line "let photoInfos = ((JSON as! NSDictionary).valueForKey("photos") as! [NSDictionary]).filter ({"
Here is my code.
//
// PhotoBrowserCollectionViewController.swift
// Photomania
//
// Created by Essan Parto on 2014-08-20.
// Copyright (c) 2014 Essan Parto. All rights reserved.
//
import UIKit
import Alamofire
class PhotoBrowserCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var photos = NSMutableArray()
#IBOutlet weak var PhotoBrowserCell: PhotoBrowserCollectionViewCell!
let refreshControl = UIRefreshControl()
var populatingPhotos = false
var currentPage = 1
let PhotoBrowserCellIdentifier = "PhotoBrowserCell"
let PhotoBrowserFooterViewIdentifier = "PhotoBrowserFooterView"
// MARK: Life-cycle
override func viewDidLoad() {
super.viewDidLoad()
setupView()
populatePhotos()
//// Alamofire.request(.GET, "https://api.500px.com/v1/photos").responseJSON() {
//// (_, _, data) in
//// print(data.value)}
//
// Alamofire.request(.GET, "https://api.500px.com/v1/photos", parameters: ["consumer_key": "Jj0vPllqD0zvxttgFZ1aTbRF5zy9g1yDcsTxJRFV"]).responseJSON() {
// (_,_,JSON) in
// print(JSON.value)
//
// let photoInfos = (JSON.value!.valueForKey("photos") as! [NSDictionary]).filter({
// ($0["nsfw"] as! Bool) == false
// }).map {
// PhotoInfo(id: $0["id"] as! Int, url: $0["image_url"] as! String)
// }
//
// self.photos.addObject(photoInfos)
// print(self.photos)
//
// self.collectionView?.reloadData()
// }
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: CollectionView
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return photos.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(PhotoBrowserCellIdentifier, forIndexPath: indexPath) as! PhotoBrowserCollectionViewCell
// let imageURL = (photos.objectAtIndex(indexPath.row) as! PhotoInfo).url
let imageURL = (photos.objectAtIndex(indexPath.row) as! PhotoInfo).url
Alamofire.request(.GET, imageURL).response() {
(_,_, data, _) in
let image = UIImage(data: data!)
cell.imageView.image = image
}
return cell
}
override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
return collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: PhotoBrowserFooterViewIdentifier, forIndexPath: indexPath)
}
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("ShowPhoto", sender: (self.photos.objectAtIndex(indexPath.item) as! PhotoInfo).id)
}
// MARK: Helper
func setupView() {
navigationController?.setNavigationBarHidden(false, animated: true)
let layout = UICollectionViewFlowLayout()
let itemWidth = (view.bounds.size.width - 2) / 3
layout.itemSize = CGSize(width: itemWidth, height: itemWidth)
layout.minimumInteritemSpacing = 1.0
layout.minimumLineSpacing = 1.0
layout.footerReferenceSize = CGSize(width: collectionView!.bounds.size.width, height: 100.0)
collectionView!.collectionViewLayout = layout
navigationItem.title = "Featured"
collectionView!.registerClass(PhotoBrowserCollectionViewCell.classForCoder(), forCellWithReuseIdentifier: PhotoBrowserCellIdentifier)
collectionView!.registerClass(PhotoBrowserCollectionViewLoadingCell.classForCoder(), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: PhotoBrowserFooterViewIdentifier)
refreshControl.tintColor = UIColor.whiteColor()
refreshControl.addTarget(self, action: "handleRefresh", forControlEvents: .ValueChanged)
collectionView!.addSubview(refreshControl)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowPhoto" {
(segue.destinationViewController as! PhotoViewerViewController).photoID = sender!.integerValue
(segue.destinationViewController as! PhotoViewerViewController).hidesBottomBarWhenPushed = true
}
}
// 1
override func scrollViewDidScroll(scrollView: UIScrollView) {
if scrollView.contentOffset.y + view.frame.size.height > scrollView.contentSize.height * 0.8 {
populatePhotos()
}
}
func populatePhotos() {
// 2
if populatingPhotos {
return
}
populatingPhotos = true
// 3
Alamofire.request(Five100px.Router.PopularPhotos(self.currentPage)).responseJSON() {
(_, _, JSON) in
// 4
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
// 5, 6, 7
let photoInfos = ((JSON as! NSDictionary).valueForKey("photos") as! [NSDictionary]).filter ({
($0["nsfw"] as! Bool) == false }).map { PhotoInfo(id: $0["id"] as! Int, url: $0["image_url"] as! String)}
//8
let lastItem = self.photos.count
//9
self.photos.addObject(photoInfos)
//10
let indexPaths = (lastItem..<self.photos.count).map { NSIndexPath(forItem: $0, inSection: $0) }
// 11
dispatch_async(dispatch_get_main_queue()) {
self.collectionView!.insertItemsAtIndexPaths(indexPaths)
}
self.currentPage++
}
self.populatingPhotos = false
}
}
func handleRefresh() {
}
}
class PhotoBrowserCollectionViewCell: UICollectionViewCell {
let imageView = UIImageView()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(white: 0.1, alpha: 1.0)
imageView.frame = bounds
addSubview(imageView)
}
}
class PhotoBrowserCollectionViewLoadingCell: UICollectionReusableView {
let spinner = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
spinner.startAnimating()
spinner.center = self.center
addSubview(spinner)
}
}
the answer is very simple. On the Five100px.swift file , you will see static let consumerKey. please update consumerKey. If you live to continue same problem. please download new version https://www.dropbox.com/s/e2unowffetv9h9c/Photomania.zip?dl=0 from this link.

Resources