集合视图单元格没有出现在集合视图中?
Posted
技术标签:
【中文标题】集合视图单元格没有出现在集合视图中?【英文标题】:Collection views cells are not appearing in collection view? 【发布时间】:2015-11-01 01:36:49 【问题描述】:这是我第一次使用集合视图,我很挣扎。我在“setupView”函数中设置了一个集合视图布局,然后实现了典型的视图方法,比如 numberOfSections 和 cellForRowAtIndexPath。现在,我只是想让集合视图正常工作,所以我只是使用工作区中已有的图像,而不是从 API 获取图片(稍后会出现)。
这是我正在使用的代码。为什么除了黑屏什么都不显示?
import UIKit
import Alamofire
import AlamofireImage
class PhotoBrowserCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout
let goldenWordsYellow = UIColor(red: 247.00/255.0, green: 192.00/255.0, blue: 51.00/255.0, alpha: 0.5)
@IBOutlet weak var menuButton:UIBarButtonItem!
@IBOutlet var picturesCollectionView: UICollectionView!
var pictureObjects = NSMutableOrderedSet(capacity: 1000)
var customRefreshControl = UIRefreshControl()
let PhotoBrowserCellIdentifier = "PhotoBrowserCell"
var dateFormatter = NSDateFormatter()
var nodeIDArray = NSMutableArray()
var timeStampDateString : String!
override func viewDidLoad()
super.viewDidLoad()
self.collectionView!.registerClass(PhotoBrowserCollectionViewCell.self, forCellWithReuseIdentifier: PhotoBrowserCellIdentifier)
self.revealViewController().rearViewRevealWidth = 280
collectionView!.delegate = self
collectionView!.dataSource = self
customRefreshControl = UIRefreshControl()
customRefreshControl.backgroundColor = goldenWordsYellow
customRefreshControl.tintColor = UIColor.whiteColor()
self.picturesCollectionView!.addSubview(customRefreshControl)
navigationController?.setNavigationBarHidden(false, animated: true)
navigationItem.title = "Pictures"
setupView()
populatePhotos()
self.dateFormatter.dateFormat = "dd/MM/yy"
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int
return 1
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 5 // setting an arbitrary value in case pictureObjects is not getting correctly populated
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(PhotoBrowserCellIdentifier, forIndexPath: indexPath) as! PhotoBrowserCollectionViewCell
cell.imageView.image = UIImage(named: "mail")
return cell
这是我的 setupView 函数。
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
performSegueWithIdentifier("ShowPhoto", sender: (self.pictureObjects.objectAtIndex(indexPath.item) as! PictureElement).imageURL)
func setupView()
navigationController?.setNavigationBarHidden(false, animated: true)
let layout = UICollectionViewFlowLayout()
let itemWidth = (view.bounds.size.width - 2) / 3
layout.itemSize = CGSize(width: itemWidth, height: itemWidth)
layout.minimumInteritemSpacing = 1.0
layout.minimumLineSpacing = 1.0
collectionView!.collectionViewLayout = layout
navigationItem.title = "Pictures"
customRefreshControl.tintColor = UIColor.whiteColor()
customRefreshControl.addTarget(self, action: "handleRefresh", forControlEvents: .ValueChanged)
self.collectionView!.addSubview(customRefreshControl)
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
return CGSizeMake(120, 120)
情节提要中的一切看起来都一团糟。我正在使用 UICollectionViewController swift 类(不是 UIViewController + collectionView 组合),我真的不知道应该使用哪些插座。这是我在整个视图控制器上的连接列表:
最后,这是我非常简单的视图层次结构。
我真的不知道为什么集合视图不能正常工作。有什么想法吗?
编辑 1:我更改了很多代码并最终让我的 collectionView 工作。对于那些在类似问题上苦苦挣扎的人,这里是我用于 collectionView 的全部代码。也许它会帮助你解决你自己的collectionView代码中的问题
import UIKit
import Alamofire
import AlamofireImage
class PhotoBrowserCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout
let goldenWordsYellow = UIColor(red: 247.00/255.0, green: 192.00/255.0, blue: 51.00/255.0, alpha: 0.5)
@IBOutlet weak var menuButton:UIBarButtonItem!
@IBOutlet var picturesCollectionView: UICollectionView!
var temporaryPictureObjects = NSMutableOrderedSet(capacity: 1000)
var pictureObjects = NSMutableOrderedSet(capacity: 1000)
var goldenWordsRefreshControl = UIRefreshControl()
var revealViewControllerIndicator : Int = 0
let imageCache = NSCache()
var customView: UIView!
var labelsArray: [UILabel] = []
var isAnimating = false
var currentColorIndex = 0
var currentLabelIndex = 0
var timer : NSTimer!
var populatingPhotos = false
var currentPage = 0
let PhotoBrowserCellIdentifier = "PhotoBrowserCell"
var dateFormatter = NSDateFormatter()
var nodeIDArray = NSMutableArray()
var timeStampDateString : String!
var cellLoadingIndicator = UIActivityIndicatorView()
var scrollViewDidScrollLoadingIndicator = UIActivityIndicatorView()
override func viewDidLoad()
super.viewDidLoad()
self.collectionView!.registerClass(PhotoBrowserCollectionViewCell.self, forCellWithReuseIdentifier: PhotoBrowserCellIdentifier)
self.cellLoadingIndicator.backgroundColor = goldenWordsYellow
self.cellLoadingIndicator.hidesWhenStopped = true
if self.revealViewController() != nil
revealViewControllerIndicator = 1
menuButton.target = self.revealViewController()
menuButton.action = "revealToggle:"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
self.revealViewController().rearViewRevealWidth = 280
collectionView!.delegate = self
collectionView!.dataSource = self
goldenWordsRefreshControl = UIRefreshControl()
goldenWordsRefreshControl.backgroundColor = goldenWordsYellow
goldenWordsRefreshControl.tintColor = UIColor.whiteColor()
self.collectionView!.addSubview(goldenWordsRefreshControl)
navigationController?.setNavigationBarHidden(false, animated: true)
navigationItem.title = "Pictures"
setupView()
populatePhotos()
self.dateFormatter.dateFormat = "dd/MM/yy"
self.cellLoadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
self.cellLoadingIndicator.color = goldenWordsYellow
self.cellLoadingIndicator.center = (self.collectionView?.center)!
self.collectionView!.addSubview(cellLoadingIndicator)
self.collectionView!.bringSubviewToFront(cellLoadingIndicator)
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
override func scrollViewDidEndDecelerating(scrollView: UIScrollView)
if goldenWordsRefreshControl.refreshing
if !isAnimating
holdRefreshControl()
func holdRefreshControl()
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "handleRefresh", userInfo: nil, repeats: true)
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int
return 1
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return (pictureObjects.count) // setting an arbitrary value in case pictureObjects is not getting correctly populated
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(PhotoBrowserCellIdentifier, forIndexPath: indexPath) as! PhotoBrowserCollectionViewCell
if let pictureObject = pictureObjects.objectAtIndex(indexPath.row) as? PictureElement
let title = pictureObject.title ?? "" // if pictureObject.title == nil, then we return an empty string
let timeStampDateObject = NSDate(timeIntervalSince1970: NSTimeInterval(pictureObject.timeStamp))
let timeStampDateString = dateFormatter.stringFromDate(timeStampDateObject)
let author = pictureObject.author ?? ""
let issueNumber = pictureObject.issueNumber ?? ""
let volumeNumber = pictureObject.volumeNumber ?? ""
let nodeID = pictureObject.nodeID ?? 0
let imageURL = pictureObject.imageURL ?? "http://goldenwords.ca/sites/all/themes/custom/gw/logo.png"
cell.request?.cancel()
if let image = self.imageCache.objectForKey(imageURL) as? UIImage
cell.imageView.image = image
else
cell.imageView.image = nil
cell.request = Alamofire.request(.GET, imageURL).responseImage() response in
if let image = response.result.value
self.imageCache.setObject(response.result.value!, forKey: imageURL)
if cell.imageView.image == nil
cell.imageView.image = image
return cell
self.performSegueWithIdentifier("ShowPhoto", sender: self)
func setupView()
navigationController?.setNavigationBarHidden(false, animated: true)
let layout = UICollectionViewFlowLayout()
let itemWidth = (view.bounds.size.width) / 3
layout.itemSize = CGSize(width: itemWidth, height: itemWidth)
layout.minimumInteritemSpacing = 1.0
layout.minimumLineSpacing = 1.0
collectionView!.collectionViewLayout = layout
navigationItem.title = "Pictures"
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
return CGSizeMake(((self.collectionView?.frame.width)!*0.5)-2, self.collectionView!.frame.height/3)
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
if segue.identifier == "ShowPhoto"
let detailViewController = segue.destinationViewController as! PhotoViewerViewController
let indexPaths = self.collectionView!.indexPathsForSelectedItems()
let indexPath = indexPaths![0] as! NSIndexPath
let item = indexPath.item
override func scrollViewDidScroll(scrollView: UIScrollView)
if (scrollView.contentOffset.y + view.frame.size.height > scrollView.contentSize.height * 0.75)
populatePhotos()
func populatePhotos()
if populatingPhotos
return
populatingPhotos = true
self.cellLoadingIndicator.startAnimating()
self.temporaryPictureObjects.removeAllObjects()
Alamofire.request(GWNetworking.Router.Pictures(self.currentPage)).responseJSON() response in
if let JSON = response.result.value
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0))
var nodeIDArray : [Int]
if (JSON .isKindOfClass(NSDictionary))
for node in JSON as! Dictionary<String, AnyObject>
let nodeIDValue = node.0
var lastItem : Int = 0
self.nodeIDArray.addObject(nodeIDValue)
if let pictureElement : PictureElement = PictureElement(title: "Picture", nodeID: 0, timeStamp: 0, imageURL: "http://goldenwords.ca/sites/all/themes/custom/gw/logo.png", author: "Staff", issueNumber: "Issue # error", volumeNumber: "Volume # error")
pictureElement.title = node.1["title"] as! String
pictureElement.nodeID = Int(nodeIDValue)!
let timeStampString = node.1["revision_timestamp"] as! String
pictureElement.timeStamp = Int(timeStampString)!
if let imageURL = node.1["image_url"] as? String
pictureElement.imageURL = imageURL
if let author = node.1["author"] as? String
pictureElement.author = author
if let issueNumber = node.1["issue_int"] as? String
pictureElement.issueNumber = issueNumber
if let volumeNumber = node.1["volume_int"] as? String
pictureElement.volumeNumber = volumeNumber
if self.pictureObjects.containsObject(pictureElement)
// do not add the pictureElement to the set of pictures
else
lastItem = self.temporaryPictureObjects.count // Using a temporary set to not handle the dataSource set directly (safer).
self.temporaryPictureObjects.addObject(pictureElement)
let indexPaths = (lastItem..<self.temporaryPictureObjects.count).map NSIndexPath(forItem: $0, inSection: 0)
let timeStampSortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: false)
self.temporaryPictureObjects.sortUsingDescriptors([timeStampSortDescriptor])
dispatch_async(dispatch_get_main_queue())
for object in self.temporaryPictureObjects
self.pictureObjects.addObject(object)
self.temporaryPictureObjects.removeAllObjects()
self.collectionView!.reloadData()
self.cellLoadingIndicator.stopAnimating()
self.goldenWordsRefreshControl.endRefreshing()
self.currentPage++
self.populatingPhotos = false
func handleRefresh()
goldenWordsRefreshControl.beginRefreshing()
self.pictureObjects.removeAllObjects()
self.temporaryPictureObjects.removeAllObjects()
self.collectionView!.reloadData()
self.currentPage = 0
self.picturesCollectionView.bringSubviewToFront(cellLoadingIndicator)
self.populatingPhotos = false
populatePhotos()
【问题讨论】:
在设置后再次尝试在 UIcollectionview 上调用 reloadData。 【参考方案1】:数据格式化后,只需重新加载您的 collectionView。 picturesCollectionView.reloadData()
override func viewDidLoad()
super.viewDidLoad()
self.collectionView!.registerClass(PhotoBrowserCollectionViewCell.self, forCellWithReuseIdentifier: PhotoBrowserCellIdentifier)
self.revealViewController().rearViewRevealWidth = 280
collectionView!.delegate = self
collectionView!.dataSource = self
customRefreshControl = UIRefreshControl()
customRefreshControl.backgroundColor = goldenWordsYellow
customRefreshControl.tintColor = UIColor.whiteColor()
self.picturesCollectionView!.addSubview(customRefreshControl)
navigationController?.setNavigationBarHidden(false, animated: true)
navigationItem.title = "Pictures"
setupView()
populatePhotos()
self.dateFormatter.dateFormat = "dd/MM/yy"
picturesCollectionView.reloadData()
【讨论】:
我非常非常困惑的一件事是我应该使用picturesCollectionView 还是collectionView。我的理解是,当您创建我拥有的集合视图控制器时,Xcode 会自动“设置”collectionView,因此我可以直接访问该collectionView 变量。但是由于我已经为我的 collectionView 创建了一个到 collection view 控制器的出口,称为“picturesCollectionView”,我应该使用 picturesCollectionView 还是直接使用提供的 collectionView 变量? picturesCollectionView.reloadData() 或 collectionView.reloadData() 都有效。 collectionView 是你的 UICollectionViewController 的一个实例,而 picturesColectionView 也是你的 UICollectionViewController 控制器的一个实例。唯一的区别是picturesCollectionView 是你的UICollectionViewController 的一个IBOutlet。 好吧,很高兴知道它们之间没有任何真正的区别。 我想我不小心删除了你最后的评论凯。我在代码中更改了很多东西并将解决方案代码发布为编辑。以上是关于集合视图单元格没有出现在集合视图中?的主要内容,如果未能解决你的问题,请参考以下文章