Hey,
This is a part of my code:
SecondViewController.swift
import UIKit
class DemoViewController: ExpandingViewController {
typealias ItemInfo = (imageName: String, title: String)
fileprivate var cellsIsOpen = [Bool]()
fileprivate let items: [ItemInfo] = [("item0", "Boston"), ("item1", "New York"), ("item2", "San Francisco"), ("item3", "Washington")]
@IBOutlet var pageLabel: UILabel!
}
extension DemoViewController{
override func viewDidLoad() {
itemSize = CGSize(width: 256, height: 460)
super.viewDidLoad()
registerCell()
fillCellIsOpenArray()
addGesture(to: collectionView!)
configureNavBar()
}
}
extension DemoViewController {
fileprivate func registerCell() {
let nib = UINib(nibName: String(describing: UICollectionViewCell.self), bundle: nil)
collectionView?.register(nib, forCellWithReuseIdentifier: String(describing: UICollectionViewCell.self))
}
fileprivate func fillCellIsOpenArray() {
cellsIsOpen = Array(repeating: false, count: items.count)
}
fileprivate func getViewController() -> ExpandingTableViewController {
let storyboard = UIStoryboard(storyboard: .Main)
let toViewController: DemoTableViewController = storyboard.instantiateViewController()
return toViewController
}
fileprivate func configureNavBar() {
navigationItem.leftBarButtonItem?.image = navigationItem.leftBarButtonItem?.image!.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
}
}
/// MARK: Gesture
extension DemoViewController {
fileprivate func addGesture(to view: UIView) {
let upGesture = Init(UISwipeGestureRecognizer(target: self, action: #selector(DemoViewController.swipeHandler(_:)))) {
$0.direction = .up
}
let downGesture = Init(UISwipeGestureRecognizer(target: self, action: #selector(DemoViewController.swipeHandler(_:)))) {
$0.direction = .down
}
view.addGestureRecognizer(upGesture)
view.addGestureRecognizer(downGesture)
}
@objc func swipeHandler(_ sender: UISwipeGestureRecognizer) {
let indexPath = IndexPath(row: currentIndex, section: 0)
guard let cell = collectionView?.cellForItem(at: indexPath) as? DemoCollectionViewCell else { return }
// double swipe Up transition
if cell.isOpened == true && sender.direction == .up {
pushToViewController(getViewController())
if let rightButton = navigationItem.rightBarButtonItem as? AnimatingBarButton {
rightButton.animationSelected(true)
}
}
let open = sender.direction == .up ? true : false
cell.cellIsOpen(open)
cellsIsOpen[indexPath.row] = cell.isOpened
}
}
// MARK: UIScrollViewDelegate
extension DemoViewController {
func scrollViewDidScroll(_: UIScrollView) {
pageLabel.text = "\(currentIndex + 1)/\(items.count)"
}
}
// MARK: UICollectionViewDataSource
extension DemoViewController {
override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
super.collectionView(collectionView, willDisplay: cell, forItemAt: indexPath)
guard let cell = cell as? DemoCollectionViewCell else { return }
let index = indexPath.row % items.count
let info = items[index]
cell.backgroundImageView?.image = UIImage(named: info.imageName)
cell.customTitle.text = info.title
cell.cellIsOpen(cellsIsOpen[index], animated: false)
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? DemoCollectionViewCell
, currentIndex == indexPath.row else { return }
if cell.isOpened == false {
cell.cellIsOpen(true)
} else {
pushToViewController(getViewController())
if let rightButton = navigationItem.rightBarButtonItem as? AnimatingBarButton {
rightButton.animationSelected(true)
}
}
}
}
// MARK: UICollectionViewDataSource
extension DemoViewController {
override func collectionView(_: UICollectionView, numberOfItemsInSection _: Int) -> Int {
return items.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: DemoCollectionViewCell.self), for: indexPath)
}
}
TableViewController.swift
import UIKit
/// Base class for UITableViewcontroller which have back transition method
open class ExpandingTableViewController: UITableViewController {
// MARK: Vars
/// The height of the table view header, set before transition
open var headerHeight: CGFloat = 236
var transitionDriver: TransitionDriver?
}
// MARK: Helpers
extension ExpandingTableViewController {
fileprivate func getScreen() -> UIImage? {
let height = (headerHeight - tableView.contentOffset.y) < 0 ? 0 : (headerHeight - tableView.contentOffset.y)
let backImageSize = CGSize(width: view.bounds.width, height: view.bounds.height - height + getTabBarHeight())
let backImageOrigin = CGPoint(x: 0, y: height + tableView.contentOffset.y)
return view.takeSnapshot(CGRect(origin: backImageOrigin, size: backImageSize))
}
fileprivate func getTabBarHeight() -> CGFloat {
guard let navigationController = self.navigationController else {
return 0
}
let insets = automaticallyAdjustsScrollViewInsets
let tabBarHeight = insets == true ? navigationController.navigationBar.frame.size.height : 0
let stausBarHeight = insets == true ? UIApplication.shared.statusBarFrame.size.height : 0
return tabBarHeight + stausBarHeight
}
}
// MARK: Methods
extension ExpandingTableViewController {
/**
Pops the top view controller from the navigation stack and updates the display with custom animation.
*/
public func popTransitionAnimation() {
guard let transitionDriver = self.transitionDriver else {
return
}
let backImage = getScreen()
var offset = tableView.contentOffset.y > headerHeight ? headerHeight : tableView.contentOffset.y
offset += getTabBarHeight()
transitionDriver.popTransitionAnimationContantOffset(offset, backImage: backImage)
_ = navigationController?.popViewController(animated: false)
}
}
There is an error in SecondViewController.swift at the line 37 :
return toViewController
And the error message is "Cannot convert return expression of type 'DemoTableViewController' to return type 'ExpandingTableViewController' "
What should I do to make it right?
Thanks.