Skip to content

Instantly share code, notes, and snippets.

@KalpeshTalkar
Last active October 29, 2018 15:14
Show Gist options
  • Save KalpeshTalkar/aaa6d41bb6b0b10a8ceb2b8cd8c1b791 to your computer and use it in GitHub Desktop.
Save KalpeshTalkar/aaa6d41bb6b0b10a8ceb2b8cd8c1b791 to your computer and use it in GitHub Desktop.
Extension for UITableView, UITableViewCell, UICollectionView, UICollectionViewCell.
//
// TableCollectionUtils.swift
//
// Created by Kalpesh on 25/05/18.
// Copyright © 2018 Kalpesh Talkar. All rights reserved.
//
// Support: https://gist.github.com/KalpeshTalkar/aaa6d41bb6b0b10a8ceb2b8cd8c1b791
// GitHub: https://github.com/KalpeshTalkar
// Gists: https://gist.github.com/KalpeshTalkar
//
import UIKit
/// Protocol thet provides identfier for reusing UICollectionViewCells and UITableViewCells
public protocol ReuseIdentifying {
/// Reuse identifier
static var reuseIdentifier: String { get }
}
// MARK: - Extension for ReuseIdentifying
public extension ReuseIdentifying {
/// Reuse identifier implementation. This will return a string of the class name.
public static var reuseIdentifier: String {
return String(describing: self)
}
}
// MARK: - UICollectionViewCell extension conforming to ReuseIdentifying
extension UICollectionViewCell: ReuseIdentifying {}
// MARK: - UITableViewCell extension conforming to ReuseIdentifying
extension UITableViewCell: ReuseIdentifying {}
// MARK: - UICollectionView extension
public extension UICollectionView {
// MARK: - Reusable Cell
/// Returns a reusable cell object located by its identifier.
///
/// - Parameters:
/// - indexPath: The index path specifying the location of the cell.
/// - type: The class of your custom collection view cell.
/// - Returns: A valid UICollectionReusableView object.
public func dequeueReusableCell<T: UICollectionViewCell>(for indexPath: IndexPath, ofType type: T.Type) -> T? {
return dequeueReusableCell(withReuseIdentifier: T.reuseIdentifier, for: indexPath) as? T
}
// MARK: - Empty States
/// Shows empty view if the collection view has no data.
///
/// - Parameter emptyView: view to be shown as empty state.
public func showEmptyStateIfNeeded(emptyView: UIView?) {
var collectionHasData = false
let sections = numberOfSections
for i in 0..<sections {
let itemsInSec = numberOfItems(inSection: i)
if itemsInSec > 0 {
collectionHasData = true
break
}
}
if refreshControl != nil {
// Enable scroll if refresh control is set
isScrollEnabled = true
} else {
// Enable scroll if not empty
isScrollEnabled = collectionHasData
}
if !collectionHasData {
emptyView?.frame = frame
backgroundView = emptyView
} else {
backgroundView = UIView()
}
}
}
// MARK: - UITableView extension
public extension UITableView {
// MARK: - Reusable Cell
/// Returns a reusable table-view cell object located by its identifier.
///
/// - Parameter type: The class of your custom tableview cell.
/// - Returns: A UITableViewCell object with the associated identifier or nil if no such object exists in the reusable-cell queue.
public func dequeueReusableCell<T: UITableViewCell>(ofType type: T.Type) -> T? {
return dequeueReusableCell(withIdentifier: T.reuseIdentifier) as? T
}
/// Returns a reusable table-view cell object for the specified reuse identifier and adds it to the table.
///
/// - Parameters:
/// - indexPath: The index path specifying the location of the cell.
/// - type: The class of your custom tableview cell.
/// - Returns: A UITableViewCell object with the associated reuse identifier. This method always returns a valid cell.
public func dequeueReusableCell<T: UITableViewCell>(for indexPath: IndexPath, ofType type: T.Type) -> T? {
return dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as? T
}
// MARK: - Empty States
/// Shows empty view if the collection view has no data.
///
/// - Parameter emptyView: view to be shown as empty state.
public func showEmptyStateIfNeeded(emptyView: UIView?) {
var tableHasData = false
let sections = numberOfSections
for i in 0..<sections {
let rowsInSec = numberOfRows(inSection: i)
if rowsInSec > 0 {
tableHasData = true
break
}
}
if refreshControl != nil {
// Enable scroll if refresh control is set
isScrollEnabled = true
} else {
// Enable scroll if not empty
isScrollEnabled = tableHasData
}
if !tableHasData {
emptyView?.frame = frame
backgroundView = emptyView
} else {
backgroundView = UIView()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment