传递信息

时间:2017-10-01 05:04:59

标签: ios swift cocoa-touch

所以,我在TableViewCell中有一个CollectionView,当有人点击单元格时,我想将该嵌入的Collection视图的单元格视图传递给ViewControllerAnimatedTransioning。我的问题是,当你单击单元格时我将indexPath保存在var中,所以当我在转换中执行委托时我可以检索那个单元格,那就是委托工作正常但是它返回nil。我有几个小时试图弄明白,而且我真的不知道发生了什么。我不知道它是否是实例的问题,但它不起作用。我把代码留给了你。我试图传递的单元格在ForYouCell中。

HomeCellTransition

    import UIKit

protocol HomeCellTransitionDelegate {
    func transition(for: HomeCellTransition) -> UIView!
}

class HomeCellTransition: NSObject, UIViewControllerAnimatedTransitioning {

    enum TransitionType {
        case presenting
        case dismissing
        case none
    }

    enum TransitionState {
        case initial
        case final
    }

    let duration: TimeInterval = 0.8
    var type: TransitionType = .none
    var topSnapshot: UIView!
    var cellSnapshot: UIView!
    var bottomSnapshot: UIView!
    var secondViewTopSnapshot: UIView!
    var secondViewBottomSnapshot: UIView!
    var delegate: HomeCellTransitionDelegate = ForYouCell()

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return duration
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let toVC = transitionContext.viewController(forKey: .to), let fromVC = transitionContext.viewController(forKey: .from) else {
            return
        }
        let containerView = transitionContext.containerView
        let presentingViewController = type == .presenting ? fromVC : toVC
        let dismissingViewController = type == .presenting ? toVC : fromVC
        let cellView = delegate.transition(for: self)
        let targetFrame = cellView?.convert((cellView?.frame)!, to: cellView?.superview)
        let percentCutImage: CGFloat = 0.10
        let secondImageView = (dismissingViewController as! DetailController).topImage
        snapshotViews(presentingVC: presentingViewController, dismissingVC: dismissingViewController, cellView: cellView!, targetFrame: targetFrame!, percentCutImage: percentCutImage, secondImageView: secondImageView)
        containerView.addSubview(toVC.view)
        containerView.addSubview(topSnapshot)
        containerView.addSubview(cellSnapshot)
        containerView.addSubview(bottomSnapshot)
        containerView.addSubview(secondViewTopSnapshot)
        containerView.addSubview(secondViewBottomSnapshot)


        toVC.view.isHidden = true
        topSnapshot.frame = CGRect.init(x: 0, y: 0, width: (presentingViewController.view.frame.width), height: (targetFrame?.minY)!)
        cellSnapshot.frame = CGRect.init(x: 0, y: 0, width: (cellView?.frame.width)!, height: (cellView?.frame.height)! - ((cellView?.frame.height)! * percentCutImage))
        bottomSnapshot.frame = CGRect.init(x: 0, y: targetFrame!.maxY, width: (presentingViewController.view.frame.width), height: (presentingViewController.view.frame.height) - (targetFrame?.maxY)!)

        UIView.animate(withDuration: duration, animations: {
            self.topSnapshot.frame.size.height = 0
            self.bottomSnapshot.frame.origin.y = 0
            self.cellSnapshot.frame = secondImageView.frame

        }) { (completed) in
            print("completed")
        }
    }

    func snapshotViews(presentingVC: UIViewController, dismissingVC: UIViewController, cellView: UIView, targetFrame: CGRect, percentCutImage: CGFloat, secondImageView: UIImageView) {
        let presentingView = presentingVC.view
        let dismissingView = dismissingVC.view
        let percentCutImage: CGFloat = percentCutImage
        let secondImageView = secondImageView
        let targetFrame = targetFrame

        topSnapshot = presentingView?.resizableSnapshotView(from: CGRect.init(x: 0, y: 0, width: (presentingView?.frame.width)!, height: targetFrame.minY), afterScreenUpdates: false, withCapInsets: .zero)
        cellSnapshot = cellView.resizableSnapshotView(from: CGRect.init(x: 0, y: 0, width: cellView.frame.width, height: cellView.frame.height - (cellView.frame.height * percentCutImage)), afterScreenUpdates: false, withCapInsets: .zero)
        bottomSnapshot = presentingView?.resizableSnapshotView(from: CGRect.init(x: 0, y: targetFrame.maxY, width: (presentingView?.frame.width)!, height: (presentingView?.frame.height)! - targetFrame.maxY), afterScreenUpdates: false, withCapInsets: .zero)
        secondViewTopSnapshot = dismissingView?.resizableSnapshotView(from: CGRect.init(x: 0, y: 0, width: (dismissingView?.frame.width)!, height: secondImageView.frame.height - (secondImageView.frame.height * percentCutImage)), afterScreenUpdates: true, withCapInsets: .zero)
        secondViewBottomSnapshot = dismissingView?.resizableSnapshotView(from: CGRect.init(x: 0, y: secondImageView.frame.maxY - (secondImageView.frame.height * percentCutImage), width: (dismissingView?.frame.width)!, height: (dismissingView?.frame.height)! - (secondImageView.frame.height - (secondImageView.frame.height * percentCutImage))), afterScreenUpdates: true, withCapInsets: .zero)



    }
}

extension HomeCellTransition: UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        type = .presenting
        return self
    }
}

ForYouCell

//
//  ForYouCell.swift
//  AirbnbNav
//
//  Created by Leonardo Dominguez on 9/24/17.
//  Copyright © 2017 Leonardo Dominguez. All rights reserved.
//

import UIKit

protocol HeaderControllerPresentDelegate {
    func didSelectCell()
}

class ForYouCell: UITableViewCell {

    let cellIdentifier = "forYouCell"
    var delegate: HeaderControllerPresentDelegate?
    let itemsInsets: CGFloat = 15
    var selectedCell: IndexPath?

    let sectionLabel: UILabel = {
        let lbl = UILabel()
        lbl.text = "Section"
        lbl.font = UIFont.boldSystemFont(ofSize: 14)
        return lbl
    }()

    let collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .white
        return cv
    }()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        collectionView.register(ItemCell.self, forCellWithReuseIdentifier: cellIdentifier)
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.contentInset = UIEdgeInsets(top: 0, left: itemsInsets, bottom: 0, right: itemsInsets)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupViews() {
        addSubview(sectionLabel)
        addSubview(collectionView)

        _ = sectionLabel.anchor(top: topAnchor, bottom: nil, right: rightAnchor, left: leftAnchor, topConstant: 0, bottomConstant: 0, rightConstant: 0, leftConstant: itemsInsets, widthConstant: 0, heightConstant: 30)

        _ = collectionView.anchor(top: sectionLabel.bottomAnchor, bottom: bottomAnchor, right: rightAnchor, left: leftAnchor, topConstant: 0, bottomConstant: 0, rightConstant: 0, leftConstant: 0, widthConstant: 0, heightConstant: 0)
    }


}

extension ForYouCell: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 5
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as? ItemCell {
            cell.backgroundColor = .red
            return cell
        }
        return UICollectionViewCell()
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        selectedCell = indexPath
        delegate?.didSelectCell()
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.frame.size.height + 50, height: collectionView.frame.size.height - 20)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 15
    }

}

extension ForYouCell: HomeCellTransitionDelegate {
    func transition(for: HomeCellTransition) -> UIView! {
        let celll = collectionView.cellForItem(at: selectedCell!)
        print(celll)
        print("k")
        return celll
    }


}

HeaderController

//
//  HeaderController.swift
//  AirbnbNav
//
//  Created by Leonardo Dominguez on 9/19/17.
//  Copyright © 2017 Leonardo Dominguez. All rights reserved.
//

import UIKit

enum HeaderSizes {
    case min
    case med
    case max
}

protocol HeaderControllerDelegate {
    func didCollapse()
    func didExpand()
}

class HeaderController: UIViewController {

    // Status bar

    var isHiddenStatusBar: Bool = false {
        didSet {
            UIView.animate(withDuration: 0.3) {
                self.setNeedsStatusBarAppearanceUpdate()
            }
        }
    }

    override var prefersStatusBarHidden: Bool {
        return isHiddenStatusBar
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        if currentHeaderSize == .min {
        return .default
        }
        return .lightContent
    }

    override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
        return .fade
    }

    // Properties

    let tableView: UITableView = {
        let tv = UITableView(frame: .zero)
        tv.separatorStyle = .none
        return tv
    }()

    let maxHeight: CGFloat = 300
    let medHeight: CGFloat = 135 // 55 del height + 10 padding superior + 10 de padding inferior + 10 statusbar
    let minHeight: CGFloat = 65 // 55 height del menu + 10 padding
    var previousScroll: CGFloat = 0
    var currentHeaderSize: HeaderSizes = .max
    var currentHeaderHeight: NSLayoutConstraint?
    fileprivate let cellIdentifier = "cellIdentifier"
    let detailController = DetailController()
    var selectedCell: UITableViewCell?

    lazy var headerView: HeaderView = {
       let hv = HeaderView(maxHeight: self.maxHeight, medHeight: self.medHeight, minHeight: self.minHeight, paddingBetween: 10)
        return hv
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(ForYouCell.self, forCellReuseIdentifier: cellIdentifier)

        headerView.headerControllerDelegate = self
    }

    func setupViews() {
        view.addSubview(headerView)
        view.addSubview(tableView)

        currentHeaderHeight = headerView.anchor(top: view.topAnchor, bottom: nil, right: view.rightAnchor, left: view.leftAnchor, topConstant: 0, bottomConstant: 0, rightConstant: 0, leftConstant: 0, widthConstant: 0, heightConstant: maxHeight)[3]

        _ = tableView.anchor(top: headerView.bottomAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, left: view.leftAnchor)
    }

}

extension HeaderController: UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? ForYouCell {
            cell.delegate = self
            return cell
        }
        return UITableViewCell()
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 250
    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let absoluteTop: CGFloat = 0
        let absoluteBottom: CGFloat = scrollView.contentSize.height - scrollView.frame.height
        let scrollRange: CGFloat = scrollView.contentOffset.y - previousScroll

        let isScrollingDown = scrollView.contentOffset.y > previousScroll && scrollView.contentOffset.y > absoluteTop
        let isScrollingUp = scrollView.contentOffset.y < previousScroll && scrollView.contentOffset.y < absoluteBottom
        var newHeight: CGFloat = currentHeaderHeight!.constant
        if isScrollingDown {
            newHeight = max(minHeight, ((currentHeaderHeight?.constant)! - abs(scrollRange)))
        } else if isScrollingUp {
            newHeight = min(maxHeight, ((currentHeaderHeight?.constant)! + abs(scrollRange)))
        }
        if newHeight != currentHeaderHeight?.constant {
            currentHeaderHeight?.constant = newHeight
            tableView.contentOffset = CGPoint(x: tableView.contentOffset.x, y: previousScroll)
            let minMedAverage: CGFloat = (minHeight + medHeight) / 2
            let medMaxAverage: CGFloat = (medHeight + maxHeight) / 2
            if currentHeaderHeight!.constant < minMedAverage {
                currentHeaderSize = .min

            } else if currentHeaderHeight!.constant >= minMedAverage && currentHeaderHeight!.constant < medMaxAverage {
                currentHeaderSize = .med
            } else if currentHeaderHeight!.constant >= medMaxAverage {
                currentHeaderSize = .max
            }
            updateHeader()
        }

        previousScroll = scrollView.contentOffset.y

    }

    func snapHeader(toSize: HeaderSizes) {
        switch toSize {
        case .max:
            currentHeaderHeight?.constant = maxHeight
        case .med:
            currentHeaderHeight?.constant = medHeight
        case .min:
            currentHeaderHeight?.constant = minHeight
        }
        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded()
        }
    }

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        snapHeader(toSize: currentHeaderSize)
        updateHeader()
    }

    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if !decelerate {
            snapHeader(toSize: currentHeaderSize)
            updateHeader()
        }
    }

    func updateHeader() {
        let range = maxHeight - medHeight
        let percent = (currentHeaderHeight!.constant - medHeight) / range
        headerView.updateHeader(percentage: percent, currentHeaderHeight: currentHeaderHeight!.constant)

        // Status bar
        isHiddenStatusBar = currentHeaderHeight!.constant < (medHeight / 2) && currentHeaderHeight!.constant > minHeight ? true : false
    }
}

extension HeaderController: HeaderControllerPresentDelegate {
    func didSelectCell() {
        present(detailController, animated: true, completion: nil)
    }
}

extension HeaderController: HeaderControllerDelegate {

    func didExpand() {
        print("")
    }

    func didCollapse() {
        snapHeader(toSize: .min)
    }
}

0 个答案:

没有答案
相关问题