Ios 传递信息
因此,我在TableViewCell中有一个CollectionView,当有人单击该单元格时,我想将该嵌入集合视图的单元格视图传递给ViewControlleranimatedTransoning。我的问题是,当您单击单元格时,我将indexPath保存在一个var中,这样当我在转换中执行委托时,我可以检索该单元格,问题是委托工作正常,但它返回nil。我有几个小时想弄清楚,但我真的不知道发生了什么。我不知道实例是否有问题,但它不起作用。我给你留了密码。我要通过的牢房在你的牢房里 HomeCellTransitionIos 传递信息,ios,swift,cocoa-touch,Ios,Swift,Cocoa Touch,因此,我在TableViewCell中有一个CollectionView,当有人单击该单元格时,我想将该嵌入集合视图的单元格视图传递给ViewControlleranimatedTransoning。我的问题是,当您单击单元格时,我将indexPath保存在一个var中,这样当我在转换中执行委托时,我可以检索该单元格,问题是委托工作正常,但它返回nil。我有几个小时想弄清楚,但我真的不知道发生了什么。我不知道实例是否有问题,但它不起作用。我给你留了密码。我要通过的牢房在你的牢房里 HomeCel
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.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)
}
}
//
//头部控制器
//空中导航
//
//由莱昂纳多·多明格斯于2017年9月19日创作。
//版权所有©2017莱昂纳多·多明格斯。版权所有。
//
导入UIKit
枚举标题{
案例min
病例医学
case max
}
协议头控制器远程门{
func didclapse()
func didExpand()
}
类标题控制器:UIViewController{
//状态栏
var isHiddenStatusBar:Bool=false{
迪塞特{
UIView.animate(持续时间:0.3){
self.setNeedsStatusBarAppearanceUpdate()
}
}
}
覆盖变量prefersStatusBarHidden:Bool{
返回isHiddenStatusBar
}
重写变量preferredStatusBarStyle:UIStatusBarStyle{
如果currentHeaderSize=.min{
返回默认值
}
return.lightContent
}
重写变量preferredStatusBarUpdateAnimation:UIStatusBarAnimation{
回来,退色
}
//性质
让tableView:UITableView={
让tv=UITableView(帧:.0)
tv.separatorStyle=.none
返回电视
}()
设maxHeight:CGFloat=300
let medHeight:CGFloat=135//55 del height+10 padding superior+10 de padding superior+10 de padding superior+10 statusbar
让最小高度:CGFloat=65//55高度del菜单+10填充
var-previousScroll:CGFloat=0
var currentHeaderSize:HeaderSizes=.max
var currentHeaderHeight:NSLayoutConstraint?
fileprivate let cellIdentifier=“cellIdentifier”
设detailController=detailController()
var selectedCell:UITableViewCell?
lazy var headerView:headerView={
设hv=HeaderView(最大高度:self.maxHeight,中间高度:self.medHeight,中间高度:self.minHeight,中间填充:10)
返回高压
}()
重写func viewDidLoad(){
super.viewDidLoad()
设置视图()
tableView.delegate=self
tableView.dataSource=self
tableView.register(ForYouCell.self,forCellReuseIdentifier:cellIdentifier)
headerView.headerControllerDelegate=self
}
func setupViews(){
视图.添加子视图(headerView)
view.addSubview(tableView)
currentHeaderHeight=headerView.anchor(顶部:view.topAnchor,底部:零,右侧:view.rightAnchor,左侧:view.leftAnchor,顶部常数:0,底部常数:0,右侧常数:0,左侧常数:0,宽度常数:0,高度常数:maxHeight)[3]
_=tableView.anchor(顶部:headerView.bottomAnchor,底部:view.bottomAnchor,右侧:view.rightAnchor,左侧:view.leftAnchor)
}
}
扩展标头控制器:UITableViewDataSource、UITableViewDelegate{
func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
返回10
}
func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
如果let cell=tableView.dequeueReusableCell(标识符为:cellIdentifier,for:indexPath)作为?ForYouCell{
cell.delegate=self
返回单元
}
返回UITableViewCell()
}
func tableView(tableView:UITableView,heightForRowAt indexath:indexPath)->CGFloat{
返回250
}
func scrollViewDidScroll(scrollView:UIScrollView){
设absoluteTop:CGFloat=0
让absoluteBottom:CGFloat=scrollView.contentSize.height-scrollView.frame.height
让scrollRange:CGFloat=scrollView.contentOffset.y-previousScroll
让isScrollingDown=scrollView.contentOffset.y>previousScroll&&scrollView.contentOffset.y>absoluteTop
让isScrollingUp=scrollView.contentOffset.y=minMedAverage&¤tHeaderHeight!.constant=medMaxAverage,则为else{
currentHeaderSize=.max
}
updateHeader()
}
previousScroll=scrollView.contentOffset.y
}
func snapHeader(toSize:HeaderSize){
开关大小{
case.max:
currentHeaderHeight?常数=最大高度
病例.医学:
currentHeaderHeight?常数=medHeight
case.min:
currentHeaderHeight?常数=最小高度
}
UIView.animate(持续时间:0.3){
self.view.layoutifneed()