Swift 2.3 IndexPath error in CollectionView - ios

Hi I am somewhat new to iOS and swift. I recently switched to swift 2.3 and now I am getting this error
Use of undeclared type 'IndexPath'
for this method
override func collectionView(collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
Any Ideas??

The function parameter should be NSIndexPath not IndexPath. Xcode 8+ uses the documentation and code completion for Swift 3.0.
Swift 2.3 syntax:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
Swift 3.0 syntax:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)

Yup! It's wrong in the Apple documentation. Not sure why they don't just fix it

Related

Header in collection view won't show up? Used to work?

I migrated this project (an iMessage app with a collection view to hold stickers) from Swift 3 to Swift 5, and everything works but the header view function simply will not fire, nor will header show up.
I register the header cell in storyboard:
then in collection view functions:
private func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
let headerView: HeaderCollectionReusableView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerCell", for: indexPath as IndexPath) as! HeaderCollectionReusableView
print("CALLED")
//header1 = headerView as! UICollectionReusableView
return headerView
}
Ive even tried turning the header a different color in storyboard, however this function doesn't even print to console. What is wrong here? This used to work and the other cells work.
I migrated this project (an iMessage app with a collection view to hold stickers) from Swift 3 to Swift 5
Well you didn't migrate this line:
private func collectionView(_ collectionView: UICollectionView,
viewForSupplementaryElementOfKind kind: String,
atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
Change it to:
func collectionView(_ collectionView: UICollectionView,
viewForSupplementaryElementOfKind kind: String,
at indexPath: IndexPath) -> UICollectionReusableView {
Not private. Not atIndexPath. Not NSIndexPath. Talk Swift, not Objective-C, and don't hide this method from Objective-C or it can't be called by Cocoa.
Plus make absolutely sure you are in a place where adoption of UICollectionViewDataSource is declared (you probably are, since you say other methods are being called okay).

numberOfItemsInSection is called but cellForItemAt is not called UICollectionViewController

This maybe a duplicate post. But I haven't found any solution in the answers given in previous questions.
Basic checks from my side that I have done.
No errors on the constraint that I have put on CollectionView and CollectionViewCell.
When numberofitemsinsection is called, it always returns more than 0.
Reusable identifier is tagged for both CollectionView and CollectionViewCell
All links for ui objects are at place.
CollectionViewCell size is set as default.
Some more information on my code.
class StickerGridCollectionViewController: UICollectionViewController{
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return stickerPackList.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
/*some code*/
return cell
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
/*some code*/
}
}
I checked all the answers here, but didn't find my answer yet.
Any clue why I might be getting this issue?
Update
When I open debug view hierarchy, I find out that collectionview is taking correct area, but views which were supposed to be inside collectionview are flowing outside and acting abnormally.
Moreover I see UICollectionView inside UiCollectionView.
Any reason, why this abnormal behaviour might occur?

Swift 3 warning func collectionView instance method nearly matches optional requirement

I am converting my project to Swift 3 in Xcode 8.1 and one of my collection view functions is returning a warning message indicating that the footprint has changed. The code is
func collectionView(_ collectionView: UICollectionView, cellForItemAtIndexPath indexPath: IndexPath) -> UICollectionViewCell {
and the warning is
Instance method CollectionView(:CellForItemAtIndexPath:) nearly matches optional requirement collectionView(:canFocusItemAt:) of protocol UICollectionViewDelegate
I believe the warning is a red herring here. I looked up the API reference https://developer.apple.com/reference/uikit/uicollectionview/1618088-cellforitem and I see
func cellForItem(at indexPath: IndexPath) -> UICollectionViewCell?
However, I am unable to find a declaration along these lines which won't result in a compiler error with a red dot.
edit:
After the answer below I added the datasource to my ViewController class as follows:
class MyController: UIViewController,
UICollectionViewDelegateFlowLayout,
UICollectionViewDataSource,
then in ViewDidLoad() I added this myCollectionView.dataSource = self.
I now have this
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
This View Controller is entirely constructed in code and had not implemented datasource although there was code for numberOfSectionsInCollectionView which produced a compiler red dot after the datasource was added. This was updated to
func numberOfSections(in collectionView: UICollectionView) -> Int {
I believe the warning is a red herring here
Well, it isn't. Typically the way to treat the compiler is with respect; it usually knows considerably more than you do. Your https://developer.apple.com/reference/uikit/uicollectionview/1618088-cellforitem is the red herring.
This is the function you want:
https://developer.apple.com/reference/uikit/uicollectionviewdatasource/1618029-collectionview
As you can see, the signature is:
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
... which is subtly different from what you wrote originally.
Another thing to watch out for is that you must make this declaration inside a class declaration that explicitly adopts UICollectionViewDataSource. The only exception is if this is a UICollectionViewController, in which case it already adopts UICollectionViewDataSource — and in that case, the compiler will tell you to add override to your declaration (and you should obey).

CollectionViewDelegate method doesn't get called after Swift 3 migration

I have a simple collection view in my app, and I use the delegate to get notified when a cell was tapped, so I implement didSelectItemAtIndexPath: method. In Swift 2 this method's signature looked like this:
#objc func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
After running thru migration process this signature changed to this:
#objc func collectionView(collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
The compiler was happy and I moved on, but now this method doesn't get triggered when I tap any cell. I found a way to fix it:
#objc(collectionView:didSelectItemAtIndexPath:) func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
Obviously, the problem was in the first parameter name, but I still don't understand why it doesn't work without specifying obj-c selector explicitly.
no need to write #objc,
Here is a working code,
extension YourViewController:UICollectionViewDelegate{
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("didSelect")
}
}
add delegate in viewdidload also add uicollectionviewdelegae,uicollectionviewdatasource also in storyboard,
this helps me.

How to listen to user touches for UICollectionViewCell in iOS?

I have implemented a UICollectionView that holds list of UIImageView objects.
I want the user to be taken to YouTube with specific URL when he touched an image.
But I don't know how to add touch listener for each UICollectionViewCell:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell: PhotoCell = collectionView.dequeueReusableCellWithReuseIdentifier("PhotoCell", forIndexPath: indexPath) as PhotoCell
cell.loadImage(thumbnailFileURLs[indexPath.row], originalImagePath: originalFileURLs[indexPath.row])
return cell
}
My PhotoCell class has a member variable that holds the URL to youtube.
For each PhotoCell object, when pressed, I want my app to send the user to youtube.com website or APP (if installed)
You should implement UICollectionViewDelegate protocol method collectionView(_:didSelectItemAtIndexPath:). When you press one of your collection view cells this method get called. Here is sample implementation
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let url = thumbnailFileURLS[indexPath.item]
if UIApplication.sharedApplication().canOpenURL(url) {
UIApplication.sharedApplication().openURL(url)
}
}
By the way I don't know where you get url. So I improvised a bit :)
Swift 5
didSelectItemAtIndexPath has been renamed to didSelectItemAt in Swift 5
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//Do your logic here
}

Resources