【问题标题】:UICollectionView with Custom Cell Breaking UICollectionViewDataSource ProtocolUICollectionView 与自定义单元格中断 UICollectionViewDataSource 协议
【发布时间】:2015-09-10 07:12:45
【问题描述】:

我正在尝试将 UICollectionView 与自定义单元格一起使用。我的 ViewController 继承自 UICollectionViewDataSource 如下:

import UIKit
import Parse

class DressingRoomViewController:   UIViewController,
                                    UICollectionViewDelegateFlowLayout,
                                    UICollectionViewDataSource {

这种继承导致我使用创建并返回自定义单元格的 UICollectionView 函数破坏了 UICollectionViewDataSource 协议。这是函数:

func collectionView(collectionView: UICollectionView,
        cellForItemAtIndexPath indexPath: NSIndexPath)
        -> CustomCell {
            let cell = collectionView.dequeueReusableCellWithReuseIdentifier(
                identifier,forIndexPath:indexPath) as! CustomCell
            let dressingRoomIcons: [DressingRoomIcon] =
            dataSource.dressingRoomIcons
            let dressingRoomIcon = dressingRoomIcons[indexPath.row]
            var imageView: MMImageView =
            createIconImageView(dressingRoomIcon.name!)

            cell.setImageV(imageView)
            return cell
    }

所以在编译之前,错误会显示在 IDE 中。如何解决此错误?这是我遇到的两个错误:

类型“DressingRoomViewController”不符合协议 'UICollectionViewDataSource'

无法将“DressingRoomViewController”类型的值分配给值 类型为“UICollectionViewDataSource?”

这是整个 ViewController:

import UIKit
import Parse

class DressingRoomViewController:   UIViewController,
                                    UICollectionViewDelegateFlowLayout,
                                    UICollectionViewDataSource {

    @IBOutlet weak var MirrorImageView: UIImageView!
    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var heightConstraint: NSLayoutConstraint!
    let identifier = "cellIdentifier"
    let dataSource = DataSource()
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    let cellSpacing: CGFloat = 5
    let cellsPerRow: CGFloat = 6
    let numberOfItems = 12

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.dataSource = self
    }

    override func viewDidAppear(animated: Bool) {
        let cellSize = (collectionView.collectionViewLayout
            .collectionViewContentSize().width
            / cellsPerRow)
            - (cellSpacing)

        layout.itemSize = CGSize(width: cellSize, height: cellSize)
        layout.minimumInteritemSpacing = cellSpacing
        layout.minimumLineSpacing = cellSpacing
        layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
        collectionView.collectionViewLayout = layout
        self.heightConstraint.constant = cellSize
        self.view.layoutIfNeeded()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func prepareForSegue(  segue: UIStoryboardSegue,
                                    sender: AnyObject?) {
        if (segue.identifier == "dressingRoom2MyOutfits") {
            let myOutfitsViewController = segue.destinationViewController
                as! MyOutfitsViewController
        } else if (segue.identifier == "dressingRoom2StickerPicker") {
            let myStickerPickerController = segue.destinationViewController
                as! StickerPickerViewController
        }
    }

    func imageTapped(sender: UITapGestureRecognizer) {
        var imageView = sender.view as! MMImageView
        println(imageView.fname)
        performSegueWithIdentifier( "dressingRoom2StickerPicker",
                                    sender: imageView)
    }
}

// MARK:- UICollectionViewDataSource Delegate
extension DressingRoomViewController : UICollectionViewDataSource {

    func numberOfSectionsInCollectionView(
        collectionView: UICollectionView) -> Int {
            return 1
    }

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

    func collectionView(collectionView: UICollectionView,
        cellForItemAtIndexPath indexPath: NSIndexPath)
        -> CustomCell {
            let cell = collectionView.dequeueReusableCellWithReuseIdentifier(
                identifier,forIndexPath:indexPath) as! CustomCell
            let dressingRoomIcons: [DressingRoomIcon] =
            dataSource.dressingRoomIcons
            let dressingRoomIcon = dressingRoomIcons[indexPath.row]
            var imageView: MMImageView =
            createIconImageView(dressingRoomIcon.name!)

            cell.setImageV(imageView)
            return cell
    }

    func createIconImageView(name: String) -> MMImageView{
        var imageView :MMImageView =
            MMImageView(frame:CGRectMake(   0,
                                            0,
            (collectionView.collectionViewLayout
                .collectionViewContentSize().width / cellsPerRow)
                - (cellSpacing),
            (collectionView.collectionViewLayout
                .collectionViewContentSize().width / cellsPerRow)
                - (cellSpacing)))
        imageView.contentMode = UIViewContentMode.ScaleAspectFit
        imageView.image = UIImage(named: name)
        imageView.setName(name)
        imageView.backgroundColor = UIColor.clearColor()
        imageView.userInteractionEnabled = true
        var tapGestureRecognizer =
        UITapGestureRecognizer(target: self, action: "imageTapped:")
        tapGestureRecognizer.numberOfTapsRequired = 1
        imageView.addGestureRecognizer(tapGestureRecognizer)
        return imageView
    }
}

编辑:这是我的 CustomCell:

import Foundation
import UIKit

class CustomCell: UICollectionViewCell {
    var imageView = MMImageView()

    func setImageV(IV: MMImageView) {
        self.imageView = IV
    }
}

【问题讨论】:

  • @ChetanPrajapati 刚刚将其添加到我的问题中

标签: ios swift uicollectionview uicollectionviewcell


【解决方案1】:

替换此代码

func collectionView(collectionView: UICollectionView,
        cellForItemAtIndexPath indexPath: NSIndexPath)
        -> UICollectionViewCell {

而不是下面这个:

func collectionView(collectionView: UICollectionView,
        cellForItemAtIndexPath indexPath: NSIndexPath)
        -> CustomCell {

您可以返回自定义单元格,但不能更改任何 DataSource 或 Delegate 方法的返回类型。

【讨论】:

  • 这导致我收到此错误 2015-09-10 19:24:56.065 MirrorMirror[4317:155042] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“*** -containsValueForKey:不能发送到类 NSCoder 的抽象对象:创建一个具体实例!我将发布我的自定义 UIImageView,因为那是带有编码器的。不过,我认为您的答案可能是正确的。
  • 您分配给 collectionView 的 let dataSource = DataSource() 数据源
  • 数据源来自 plist。但是我认为问题出在我的自定义 ImageView 上,因为我之前有 dataSource 工作过。我需要创建自定义单元格的唯一原因是因为我曾经向单元格添加了一个子视图,它在滚动后在旧图像上重新绘制了一个新的单元格图像。
  • 哦,没关系。但我不明白你为什么要自定义 UIImageView 类。?
  • 我需要知道我点击了什么图像,所以我给自定义 UIImageView 一个名称属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-07
相关资源
最近更新 更多