I have one button in header cell that created by IB. I add on action, but I can not trigger. This code;
func collectionView( _ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let cell = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionHeader", for: indexPath) as! ProfilePhotoHeaderCell
cell.lblFavCount.text = user.favdCount
let countFoto = ((user.photos?.count)!)
cell.lblFotoCount.text = countFoto.description
cell.btnAddPhotos.isUserInteractionEnabled = true
cell.btnAddPhotos?.addTarget(self, action: #selector(ProfileController.myAction(sender:)), for: .touchUpInside) // add selector
return cell
case IOStickyHeaderParallaxHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerCell1", for: indexPath) as! ProfileParallaxHeaderCell
return headerView
default:
assert(false, "Unexpected element kind")
}
}
Related
I have two custom UICollectionViewCells(AddImageCollectionViewCell, ItemCollectionViewCell) which I am loading depending on indexpath. Here is my code for the cellForItemAtIndexpath-
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
var cell :UICollectionViewCell!
if indexPath.row == 0{
cell = collectionView.dequeueReusableCell(withReuseIdentifier: "addImageCell", for: indexPath) as! AddImageCollectionViewCell
}
else{
cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ItemCell", for: indexPath) as! ItemCollectionViewCell
cell.contentImage = self.droppedItemList[indexPath.row] //error here
}
return cell
}
I am getting the error as "Value of type 'UICollectionViewCell?' has no member 'contentImage'". Why is my cell in the else clause is not cast to "ItemCollectionViewCell" type.
I know, I must be doing something very foolish. I would be really grateful if someone can point me to the right direction.
You are declaring cell as basic type UICollectionViewCell, that's the reason. Return the cells separately
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.row == 0 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "addImageCell", for: indexPath) as! AddImageCollectionViewCell
return cell
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ItemCell", for: indexPath) as! ItemCollectionViewCell
cell.contentImage = self.droppedItemList[indexPath.row]
return cell
}
}
I have a header and a footer in my CollectionView and I want both of them to be displayed. At the current state, I get 2x the Header, because the "kind" of the Section does not automatically change and it enters the case "UICollectionElementKindSectionHeader" twice.
I could switch the indexPath instead of the kind but I want to know the other approach aswell.
func setupCollectionView() {
collectionView?.backgroundColor = .white
collectionView?.register(ProfileHeader.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: ProfileHeader.reuseIdentifier)
collectionView?.register(ProfileFooter.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: ProfileFooter.reuseIdentifier)
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: ProfileHeader.reuseIdentifier, for: indexPath) as! ProfileHeader
header.user = self.user
return header
case UICollectionElementKindSectionFooter:
let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: ProfileFooter.reuseIdentifier, for: indexPath) as! ProfileFooter
return footer
default:
assert(false, "Unexpected element kind")
}
}
The reason was that I forgot to define the reference size of the footer. Without it, the kind is not perceived by the application.
I want to add a few buttons to the header of a Collection view. Enabled 'Section Header' from the storyboard. Then dragged a 'view' to that header. And put its background color to green
But I don't why it's not displaying. In the simulator as you see, only a blank space for the header.
Use this Method
Give name in CollectionHeaderCell
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Header", for: indexPath as IndexPath)
headerView.backgroundColor = UIColor.blue;
return headerView
case UICollectionElementKindSectionFooter:
let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Footer", for: indexPath as IndexPath)
footerView.backgroundColor = UIColor.green;
return footerView
default:
assert(false, "Unexpected element kind")
}
}
// make a cell for each cell index path
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("InviteFriendCell", forIndexPath: indexPath)
let profileimage: UIImageView = (cell.viewWithTag(5) as! UIImageView)
profileimage.image = UIImage(named:arrayofdata[indexPath.row]["image"]!)
return cell
}
~New to Swift~
Below is the func I have to implement header and footer views into my UICollectionView but as of now when I run my app nothing is showing up.
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "Header", forIndexPath: indexPath)
headerView.backgroundColor = UIColor.brownColor()
return headerView
case UICollectionElementKindSectionFooter:
let footerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "Footer", forIndexPath: indexPath)
footerView.backgroundColor = UIColor.darkGrayColor()
return footerView
default:
assert(false, "Unexpected element kind")
}
}
Using the view's indexPathForItemAtPoint, I will get an index path for a cell, but never a UICollectionReusableView (header/footer) -- as it always returns nil.
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "header", for: indexPath) as! HeaderCollectionReusableView
let gestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didSelectSection(gesture:)))
headerView.addGestureRecognizer(gestureRecognizer)
return headerView
}
}
Now in didSelectSection :
func didSelectSection(gesture: UITapGestureRecognizer) {
let indexPaths = self.collectionView?.indexPathsForVisibleSupplementaryElements(ofKind: UICollectionElementKindSectionHeader)
for indexPath in indexPaths! {
if (gesture.view as! HeaderCollectionReusableView) == collectionView?.supplementaryView(forElementKind: UICollectionElementKindSectionHeader, at: indexPath){
print("found at : \(indexPath)")
break
}
}
}
You can add extension for UICollectionView where pass reference of supplementary view and kind of this view (UICollectionView.elementKindSectionHeader or UICollectionView.elementKindSectionFooter)
extension UICollectionView {
func indexPathForSupplementaryElement(_ supplementaryView: UICollectionReusableView, ofKind kind: String) -> IndexPath? {
let visibleIndexPaths = self.indexPathsForVisibleSupplementaryElements(ofKind: kind)
return visibleIndexPaths.first(where: {
self.supplementaryView(forElementKind: kind, at: $0) == supplementaryView
})
}
}
This method doesn't work if supplementary view isn't visible!