How to add an extra static cell to my UICollectionView? - ios

I have an array of photos that I currently display in a UICollectionView. The only thing I still want to add is an extra static cell that should give the user the possibility to open the camera. I used an if-else statement to detect the index. Unfortunately, the console gives me an out of index error.
To be precise: I want this static cell to be in the top left corner, followed by my array of images. Do I have to add two sections, or should I register another custom cell to accomplish this? As of now I can see my extra cell, but it's not working when tapped (out of index).
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageArray.count + 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: photoId, for: indexPath) as! PhotosCollectionViewCell
if indexPath.row == imageArray.count {
cell.backgroundColor = UIColor.lightGray
cell.addGestureRecognizer(UIGestureRecognizer(target: self, action: #selector(tappedCamera)))
} else {
cell.imageView.image = imageArray[indexPath.item]
cell.imageView.addGestureRecognizer(UIGestureRecognizer(target: self, action: #selector(tappedPhoto)))
}
return cell
}
Updated code (solution)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageArray.count + 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.row == 0 {
let cameraCell = collectionView.dequeueReusableCell(withReuseIdentifier: cameraId, for: indexPath) as! CameraCollectionViewCell
return cameraCell
}
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tappedPhoto))
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: photoId, for: indexPath) as! PhotoCollectionViewCell
cell.imageView.image = imageArray[indexPath.row - 1]
cell.imageView.addGestureRecognizer(tapGesture)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.row == 0 {
print("Camera")
}
}
var startingFrame: CGRect?
var blackBackGroundView: UIView?
var selectedImageFromPicker: UIImage?
var selectedImageCompressed: UIImage?
func tappedPhoto(sender: UIGestureRecognizer) {
if let indexPath = self.collectionView?.indexPathForItem(at: sender.location(in: self.collectionView)) {
let imageView = self.collectionView?.cellForItem(at: indexPath)
startingFrame = imageView?.superview?.convert((imageView?.frame)!, to: nil)
let zoomingImageView = UIImageView(frame: startingFrame!)
zoomingImageView.image = imageArray[indexPath.row - 1]
zoomingImageView.isUserInteractionEnabled = true
zoomingImageView.contentMode = .scaleAspectFill
zoomingImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleZoomOut)))
if let keyWindow = UIApplication.shared.keyWindow {
blackBackGroundView = UIView(frame: keyWindow.frame)
blackBackGroundView?.backgroundColor = UIColor.black
blackBackGroundView?.alpha = 0
keyWindow.addSubview(blackBackGroundView!)
keyWindow.addSubview(chooseLabel)
keyWindow.addSubview(zoomingImageView)
// Set selected image and compress
selectedImageFromPicker = imageArray[indexPath.row - 1]
selectedImageCompressed = selectedImageFromPicker?.resized(withPercentage: 0.1)
chooseLabel.rightAnchor.constraint(equalTo: keyWindow.rightAnchor, constant: -25).isActive = true
chooseLabel.bottomAnchor.constraint(equalTo: keyWindow.bottomAnchor, constant: -25).isActive = true
UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.blackBackGroundView?.alpha = 1
self.chooseLabel.alpha = 1
let height = self.startingFrame!.height / self.startingFrame!.width * keyWindow.frame.width
zoomingImageView.frame = CGRect(x: 0, y: 0, width: keyWindow.frame.width, height: height)
zoomingImageView.center = keyWindow.center
}, completion: {(completed) in
// Do nothing
})
}
}
}

Do I have to add two sections, or should I register another custom
cell to accomplish this?
In your case, just adding one cell at the beginning of the collection should be fair enough, there is no need to multi-section it.
Your methods should be implemented as follows:
1- numberOfItemsInSection method: should be as is:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageArray.count + 1
}
2- cellForItemAt method: depends on the first cell, if it should be a different cell:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// first row
if indexPath.row == 0 {
let cameraCell = collectionView.dequeueReusableCell(withReuseIdentifier: "cameraCell-ID", for: indexPath)
// setup the cell...
return cameraCell
}
let defaultCell = collectionView.dequeueReusableCell(withReuseIdentifier: "defaultCell-ID", for: indexPath)
// setup default cell...
return defaultCell
}
Or, if you want it to be the same cell, but with some editions:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell-ID", for: indexPath)
// first row
if indexPath.row == 0 {
// setup the cell as cemera cell...
} else {
// setup the cell as default cell...
}
return cell
}
Actually, there is no need to add UITapGestureRecognizer for each cell, all you have to do is to implement collection​View(_:​did​Select​Item​At:​) delegate method:
Tells the delegate that the item at the specified index path was
selected.
3- didSelectItemAt method:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.row == 0 { // camera cell
// handle tapping the camera cell
} else { // default cells
// handle tapping the default cell
// don't forget that:
// getting the first element in 'imageArray' should be imageArray[indexPath.row - 1]
}
}
Hope this helped.

Related

multiple cells selected on scrolling [reuse cells problem]

I have a collectionViewCell which contains an image and a label. When I select a cell and scroll ahead I find other cell being selected. Also when I scroll back I find the other cell and not the cell I selected is selected.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return followedUsers.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = attachProfilesCollectionView.dequeueReusableCell(withReuseIdentifier: "attachCells", for: indexPath) as? attachUsersCell
cell!.subscribedUserId = self.followedUsers[indexPath.row].userId
cell?.profileNameToAttah.text = self.followedUsers[indexPath.row].fullName
cell?.profileImageToAttch.loadImagesWithUrl(from: self.followedUsers[indexPath.row].ImagePath)
if mLastSelectedIndex == indexPath.row {
cell?.isSelected = true}
else{cell?.isSelected = false}
return cell!
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 80, height: 110)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = attachProfilesCollectionView.cellForItem(at: indexPath) as! attachUsersCell
cell.subscribedUserId = following[indexPath.item]
usersToAttach.append(cell.subscribedUserId)
attachedCounter += 1
attachCounterFun()
print(usersToAttach)
cell.checkMarkImage.isHidden = false
attachCounterFun()
guard mLastSelectedIndex != indexPath.row else{return}
mLastSelectedIndex = indexPath.row
print("this is addition \(usersToAttach)")
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell_ = attachProfilesCollectionView.cellForItem(at: indexPath) as! attachUsersCell
let toRemove = usersToAttach.index(of: following[indexPath.row])
usersToAttach.remove(at: toRemove!)
attachedCounter -= 1
attachCounterFun()
print(usersToAttach)
cell_.checkMarkImage.isHidden = true
print("this is removal \(usersToAttach)")
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if isSelected {
cell.isSelected = true}
else { isSelected = false }
}
At present I have enabled paging and almost there but occasionally the selected cells change selection upon scroll
Maintain global variable in your controller
var mLastSelectedIndex = -1
Whenever cellForRowAtIndexPath method called check if current cell is selected or not .If this is selected One update its UI. I suggest you to change selected cell UI on cell class only. This way you can easily manage cell tapping and helps you writing clean code.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = attachProfilesCollectionView.dequeueReusableCell(withReuseIdentifier: "attachCells", for: indexPath) as? attachUsersCell
cell!.subscribedUserId = self.followedUsers[indexPath.row].userId
cell?.profileNameToAttah.text = self.followedUsers[indexPath.row].fullName
cell?.profileImageToAttch.loadImagesWithUrl(from: self.followedUsers[indexPath.row].ImagePath)
// here update selected index path
if mLastSelectedIndex == indexPath.row {
cell?.isSelected = true
}
else{
cell?.isSelected = false
}
return cell!
}
Update last selected index on cell tapped.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard mLastSelectedIndex != IndexPath.row else{return}
let indexpath = IndexPath(row:mLastSelectedIndex, section: 0)
mColllectionView.cellForItem(at: indexpath)?.isSelected = !mColllectionView.cellForItem(at: indexpath)!.isSelected
mLastSelectedIndex = IndexPath.row
}
In your attachUsersCell.swift declare isSelected property of cell . The default value of this property is false, which indicates that the cell is not selected.
override var isSelected: Bool{
didSet{
if isSelected {
setSelectedUI()
}
else{
setUnSelectedUI()
}
}
}
func setSelectedUI(){
borderColor = UIColor.systemOrange
borderWidth = 2
cornerRadius = 8
clipsToBounds = true
}
func setUnSelectedUI(){
// reset to default ui
}
Hope this helps!

How to get CollectionViewCell indexPath on Out-sided UIButton Click

How to get indexPath of collectionViewCell on Button click and Button is in Out sided from collectionviewCell. I am trying with sender and Superview. But it is not working.
#IBAction func btnCancel(_ sender: Any) {
if let cell = (sender as AnyObject).superview??.superview?.superview?.superview?.superview?.superview as? ImageShowinPopUpCell {
let indexPath = collectionview.indexPath(for: cell)
deleteDublicateImage(id: isNilValue(assignValue: dbImageDataModel![(indexPath?.row)!].id))
collectionview.reloadData()
if dbImageDataModel.count == 0
{
dismiss(animated: true, completion: nil)
}
}
}
import UIKit
class ViewController: UIViewController ,UICollectionViewDelegate&UICollectionViewDataSource&UICollectionViewDelegateFlowLayout{
#IBOutlet weak var collectionView: UICollectionView!
var currentIndexPath:IndexPath!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
collectionView.delegate = self
collectionView.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = indexPath.row % 2 == 1 ? .blue : .red
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
currentIndexPath = indexPath
}
#IBAction func indexPathAction(_ sender: UIButton) {
print("Current IndexPath",currentIndexPath)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return collectionView.bounds.size
}
}
Create custom cell with button, give button action programatically, give tag values for button & superView like the below.
Implement button action, you can able to get index like below.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.button.superview.tag = indexPath.section
cell.button.tag = indexPath.row
cell.button.addTarget(self, action: #selector(self.buttonAction), for: .touchUpInside)
return cell
}
func buttonAction(_ sender:UIButton) {
let indexPath = IndexPath(row: sender.tag, section: sender.superview!.tag)
}
Try This
you set your cell button in cellForItemAt indexPath like this
cell.btnCancel.tag = indexPath.row
cell.btnCancel.addTarget(self, action:#selector(btnCancel), for:.touchUpInside)
//And catch your value like this
#objc func btnCancel(sender: UIButton)
{
let index = [sender.tag] as IndexPath
let dict = self.yourarray[sender.tag] as! NSDictionary
}
You can assign a tag to button and retrieve indexpath from the tag in action of the button.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.button.tag = indexPath.row
cell.button.addTarget(self, action: #selector(buttonTapped(sender:)), for: UIControl.Event.touchUpInside)
return cell
}
#objc func buttonTapped(sender:UIButton){
let indexPath = Indexpath(row:sender.tag , section: 0)
let cell = collectionView.cellForItem(at:indexPath)
}
Hope this helps!

Detect tap on UIViewCollectionCell inside UITableViewCell

I want to detect a tap on imageview in uicollectionviewcell inside uitableviewcell
I'm using an api response to build a data in my tableview
I have this API response:
{"status":1,"data":{"blocks":[{"name":"CustomBlock","description":"CustomDescription","itemsType":"game","items":[510234,78188,15719,37630]}], "items":[{"id:"1", name: "testgame"}]}
BlocksViewController.swift
class BlocksViewController: UIViewController, UITableViewDataSource, UICollectionViewDataSource, UICollectionViewDelegate, UITableViewDelegate {
var blocks = [Block]() // I'm getting blocks in this controller
var items : BlockItem! // and items
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return blocks[collectionView.tag].items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "GameCollectionCell", for: indexPath) as? GameCollectionCell else { return
UICollectionViewCell() }
if let found = items.game.first(where: {$0.id == String(blocks[collectionView.tag].items[indexPath.row])}) {
cell.gameName.text = found.name
cell.gameImage.kf.indicatorType = .activity
let processor = DownsamplingImageProcessor(size: CGSize(width: 225, height: 300))
cell.gameImage.kf.setImage(
with: URL(string: found.background_image ?? ""),
options: [
.processor(processor),
.scaleFactor(UIScreen.main.scale),
.transition(.fade(0.2)),
.cacheOriginalImage
])
}
else {
cell.gameName.text = ""
cell.gameImage.image = nil
}
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return blocks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "BlockCell") as? BlockCell else { return UITableViewCell() }
cell.blockName.text = blocks[indexPath.row].name
cell.blockDescription.text = blocks[indexPath.row].description
cell.setScrollPosition(x: offsets[indexPath] ?? 0)
cell.gameCollectionCell.delegate = self
cell.gameCollectionCell.dataSource = self
cell.gameCollectionCell.tag = indexPath.row
cell.gameCollectionCell.reloadData()
return cell
}
I'm getting blocks and items in this controller. Now i want to detect a tap using LongTapGestureRecognizer on image in gamecollectionCell(UIcollectionViewCell inside BlockCell(TableviewCell). How can i do this? Or maybe any advice how to improve logic here?
Okay, i've added gesture recognizer like this in cellForItemAt :
cell.addGestureRecognizer(UILongPressGestureRecognizer.init(target: self, action: #selector(addGamePopUp)))
Then i need to animate uiimageview on long tap.
var selectedGameCell : GameCollectionCell?
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.selectedGameCell = collectionView.dequeueReusableCell(withReuseIdentifier: "GameCollectionCell", for: indexPath) as? GameCollectionCell
}
And
#IBAction func addGamePopUp(_ sender: UILongPressGestureRecognizer) {
if (sender.state == UIGestureRecognizer.State.began){
UIView.animate(withDuration: 0.3, animations: {
self.selectedGameCell?.gameImage.transform = CGAffineTransform(scaleX: 0.95,y: 0.95);
}) { (Bool) in
UIView.animate(withDuration: 0.3, animations: {
self.selectedGameCell?.gameImage.transform = CGAffineTransform(scaleX: 1,y: 1);
});
}
}
}
But it still doesn't work. Did i miss something?
If you want to use longTapGestureRecognizer, just add one to the cell in your cellForItemAtIndexPath method of your collectionView, like this:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SubjectCellId", for: indexPath) as? SubjectCell {
cell.addGestureRecognizer(UILongPressGestureRecognizer.init(target: self, action: #selector(someMethod)))
return cell
}
return UICollectionViewCell()
}
You can use following delegate method of uicollectionview to detect tap on collection view cell.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){
print("cell tapped")
}
For Adding Long Press Gesture Add Following Code in Cell For item at indexpath method:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell : GameCollectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! GameCollectionCell
cell.backgroundColor = model[collectionView.tag][indexPath.item]
let lpgr = UILongPressGestureRecognizer(target: self, action: #selector(addGamePopUp(_:)))
cell.addGestureRecognizer(lpgr)
return cell
}
#IBAction func addGamePopUp(_ sender: UILongPressGestureRecognizer){
print("add game popup")
if (sender.state == UIGestureRecognizer.State.began){
UIView.animate(withDuration: 0.3, animations: {
self.selectedGameCell?.gameImage?.transform = CGAffineTransform(scaleX: 0.95,y: 0.95);
}) { (Bool) in
UIView.animate(withDuration: 0.3, animations: {
self.selectedGameCell?.gameImage?.transform = CGAffineTransform(scaleX: 1,y: 1);
});
}
}
}
You can use touchesBegan method inside tableview cell and from the touch location get the collection view cell object inside it.
NOTE: When you implement this method the didSelectRow method would not be called for the TableViewCell.
extension TableViewCell {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let point = touch.location(in: self)
if let path = collectionView.indexPathForItem(at: point) {
//Get cell of collection view from this index path
}
}
}
}
In order to get things working, I'd recommend changing your function from
#IBAction func addGamePopUp(_ sender: UILongPressGestureRecognizer) {
to
#objc func addGamePopUp() {
And when you're adding the longTapGestureRecognizer to your collectionViewCell, you'll have it trigger that method by changing the line to:
cell.addGestureRecognizer(UILongPressGestureRecognizer.init(target: self, action: #selector(addGamePopUp)))
Let me know if that works!
(psst: also take out this if check in your addGamePopupMethod if you're going this route)
if (sender.state == UIGestureRecognizer.State.began){

Adding new Item to CollectionView programmatically, via the last Item

I'm facing an issue with CollectionView, I want to see a collection of images and have an add button as the last item so first of all I've made an array of NSData as I'm gonna save those images to Core Data
var photoArray = [NSData]()
then I implement UICollectionViewDataSource
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.item == photoArray.count + 1 {
present(imagePicker, animated: true, completion: nil)
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return photoArray.count + 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoItem", for: indexPath) as? PhotoCell else {return UICollectionViewCell()}
cell.btn.tag = indexPath.item
if indexPath.item == photoArray.count + 1 {
cell.thumImage.image = UIImage(named: "add_button")
cell.btn.isHidden = true
print("first")
return cell
} else {
let img = photoArray[indexPath.item]
cell.configureAddingImage(img: img)
print("second")
return cell
}
}
Actually I'm facing with the problem in "cellForItemAt indexPath" like "fatal error: index is out of range" I tried to make array look like var photoArray: [NSData]! but it caused other problems, please give me any advice or help, thank you!
Index is out of range because items or rows are indexed from 0
Should be like this:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoItem", for: indexPath) as? PhotoCell else {return UICollectionViewCell()}
cell.btn.tag = indexPath.row
if indexPath.row == photoArray.count {
cell.thumImage.image = UIImage(named: "add_button")
cell.btn.isHidden = true
print("first")
return cell
} else {
let img = photoArray[indexPath.row]
cell.configureAddingImage(img: img)
print("second")
return cell
}
}

Strange behavior with UICollectionView cell selection

I currently have this (pseudo)code:
var selectedCell: UICollectionViewCell?
override func viewDidLoad() {
super.viewDidLoad()
...
#initialize all objects and pull data from the server to fill the cells
UIView.animate(withDuration: 0, animations: {
self.dataCollectionView.reloadData()
}, completion: {(finished) in
let indexPath = IndexPath(row: 0, section: 0)
self.dataCollectionView.selectItem(at: indexPath, animated: true, scrollPosition: .top)
self.collectionView(self.dataCollectionView, didSelectItemAt: indexPath)
})
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! DataCollectionViewCell
if !selectedCell {
cell.layer.borderWidth = 1
}
else {
cell.layer.borderWidth = 2
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAtindexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
selectedCell = cell
cell.image = SomeImageFromServer
cell.layer.borderWidth = 2
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell.layer.borderWidth = 1
}
My thinking is that this code will select the first cell right after the collection view has been loaded, and it does. The problem is it selects the last cell as well, but didSelectItemAtindexPath is never called for the last cell, and only the first cell.
I've tried selecting the second cell by using let indexPath = IndexPath(row: 1, section: 0) and it does select the second cell once the collectionview has been loaded, and the last cell is not selected as you would think.
And once any cell is selected, the last cell is unselected.
So my hypothesis is that this isn't the code thinking the cell is "selected" but that it's for some reason giving the selected cell a "selected cell border" but only when the first selected cell is the first one. Any thoughts?
Try moving the border setting into cell, UICollectionView will automatically manage the border width:
//Swift3
class TestCollectionViewCell: UICollectionViewCell {
override func awakeFromNib() {
super.awakeFromNib()
self.layer.borderWidth = 1 //Default border width
}
override var isSelected: Bool {
didSet{
if self.isSelected {
self.layer.borderWidth = 2
}
else{
self.layer.borderWidth = 1
}
}
}
}

Resources