【问题标题】:Passing data from CollectionVewCell to another view controller将数据从 CollectionVewCell 传递到另一个视图控制器
【发布时间】:2020-08-17 07:35:57
【问题描述】:

假设我们有带有 Cells 的 CollectionViewController 因此,我的目标是在单击该 CELL 后将数据从活动的 CollectionViewControllerCell(假设我想传递类别名称)发送到另一个控制器。那么,我怎样才能从

import UIKit

class CategoriesViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!
    
    var activeCategoryItemTitle:String = ""
    var categories = Category.fetchCategories()
    let cellScale: CGFloat = 0.7
        
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let screenSize = UIScreen.main.bounds.size
        let cellWidth =  floor(screenSize.width * cellScale)
        let cellHeight = floor(screenSize.height * cellScale)
        let insetX  = (view.bounds.width - cellWidth) / 2
        let insetY  = (view.bounds.height - cellHeight) / 2
        let layout = collectionView!.collectionViewLayout as! UICollectionViewFlowLayout
        layout.itemSize = CGSize(width:cellWidth,height:cellHeight)

    //  collectionView.contentInset = UIEdgeInsets(top:insetY,left:insetX,bottom:insetY,right:insetX)
        print(insetY)
        
        collectionView.dataSource = self
        collectionView.delegate = self
    }
   
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let destinationVC: ProductsViewController = segue.destination as! ProductsViewController
        destinationVC.titleOfCategory = self.activeCategoryItemTitle
    //  let product = ProductsViewController()
    //  product.titleOfCategory = "asd"
    }
}

// MARK UICollectionViewDataSource

extension CategoriesViewController:
    UICollectionViewDataSource
{
    
    func numberOfSections(in collectionView: UICollectionView) ->
        Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
        return categories.count
    }
    
    func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell =
            collectionView.dequeueReusableCell(withReuseIdentifier: "CategoriesCollectionViewCell",for:indexPath) as!
        CategoriesCollectionViewCell
        let category = categories[indexPath.item]
        cell.category = category

        return cell
    }
}

extension CategoriesViewController: UIScrollViewDelegate, UICollectionViewDelegate
{
    
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        let layout = self.collectionView?.collectionViewLayout as! UICollectionViewFlowLayout
        
        let cellWidthincludingSpacing = layout.itemSize.width+layout.minimumLineSpacing
        
        var offset = targetContentOffset.pointee
        
        let index = (offset.x + scrollView.contentInset.left) / cellWidthincludingSpacing
        
        let roundedIndex = round(index)
        
        offset = CGPoint(x: roundedIndex*cellWidthincludingSpacing-scrollView.contentInset.left, y: scrollView.contentInset.top)
        
        targetContentOffset.pointee = offset
       
    }
}

第二个是我的产品列表控制器,它必须接收类别名称并放入视图

//
import UIKit

class ProductsViewController: UIViewController {

    @IBOutlet weak var categoryTitle: UILabel!
    var titleOfCategory:String = ""
    
    @IBOutlet weak var collectionView: UICollectionView!
    
    var products = Product.fetchProducts()
//  let cellScale: CGFloat = 0.63
        
    override func viewDidLoad() {
        super.viewDidLoad()
        categoryTitle.text = titleOfCategory
//      let screenSize = UIScreen.main.bounds.size
//      let cellWidth =  floor(screenSize.width * cellScale)
//      let cellHeight = floor(screenSize.height * cellScale)
//      let insetX  = (view.bounds.width - cellWidth) / 2
//      let insetY  = (view.bounds.height - cellHeight) / 2
//      let layout = collectionView!.collectionViewLayout as! UICollectionViewFlowLayout
//      layout.itemSize = CGSize(width:cellWidth,height:cellHeight)
//      collectionView.contentInset = UIEdgeInsets(top:insetY,left:insetX,bottom:insetY,right:insetX)
//      collectionView.dataSource = self
//      collectionView.delegate = self
    }
}

// MARK UICollectionViewDataSource
extension ProductsViewController:
    UICollectionViewDataSource
{
    func numberOfSections(in collectionView: UICollectionView) ->
        Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
        return products.count
    }
    
    func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell =
            collectionView.dequeueReusableCell(withReuseIdentifier: "ProductsCollectionViewCell",for:indexPath) as!
        ProductsCollectionViewCell
        
        let product = products[indexPath.item]
        
        cell.product = product
        
        return cell
    }
}

extension ProductsViewController: UIScrollViewDelegate, UICollectionViewDelegate
{
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        let layout = self.collectionView?.collectionViewLayout as! UICollectionViewFlowLayout
        
        let cellWidthincludingSpacing = layout.itemSize.width+layout.minimumLineSpacing
        
        var offset = targetContentOffset.pointee
        
        let index = (offset.x + scrollView.contentInset.left) / cellWidthincludingSpacing
        
        let roundedIndex = round(index)
        
        offset = CGPoint(x: roundedIndex*cellWidthincludingSpacing-scrollView.contentInset.left, y: scrollView.contentInset.top)
        
        targetContentOffset.pointee = offset
        
    }
}

【问题讨论】:

    标签: swift iphone xcode delegates segue


    【解决方案1】:

    1,将didSelectItemAt添加到你的collectionView,这将处理单元格的点击。

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        performSegue(withIdentifier: "showProducts", sender: categories[indexPath.item])
    
    }
    

    2,在您的 CategoriesViewController 开始输入“prepare”,您将看到 prepare for segue 方法。

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "showProducts" {
                let destination = segue.destination as! ProductsViewController
                destination.titleOfCategory = sender as? String
            }
        }
    

    【讨论】:

    • 当然,您需要在 IB 中创建一个从第一个控制器(而不是单元)到第二个控制器的 segue。我也会让代码更具防御性:if let destination = segue.destination as? ProductsViewController {destination.titleOfCategory = 发件人为?字符串 }
    • 你是对的,但这只是一个 sn-p。而不是 if let,我建议guard let,更具可读性。
    • 谢谢!此外,在运行收到此错误线程 1:signal SIGABRT 后,已经将 # showProducts 添加到我的 segue 中
    • 您是否创建了一个 segue 并为其指定了 showProducts ID ?
    • 是的,当然,segue.identifier == "showProducts",并且在第一和第二个控制器之间的故事板 segue 中给出了 ID "showProducts"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多