This is my code for my CollectionViews. I have two CollectionViews so far, and as you can see in the Strings in the code, they each have 6 buttons. I need to call the buttons from the Strings so that when they are pressed, a new window opens. The new window will contain things like flashcards, pertaining to the subject of the button that was pressed.
For reference, is what the simulator looks like.
code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
class FirstCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var buttonOne: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
commonInit()
}
func commonInit() {
guard buttonOne != nil else { return }
buttonOne.titleLabel!.font = UIFont(name: "Marker Felt", size: 20)
buttonOne.layer.cornerRadius = 10
buttonOne.clipsToBounds = true
buttonOne.layer.borderWidth = 1.0
buttonOne.layer.borderColor = UIColor.white.cgColor
}
}
class SecondCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var buttonTwo: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
commonInit()
}
func commonInit() {
guard buttonTwo != nil else { return }
buttonTwo.titleLabel!.font = UIFont(name: "Marker Felt", size: 20)
buttonTwo.layer.cornerRadius = 10
buttonTwo.clipsToBounds = true
buttonTwo.layer.borderWidth = 1.0
buttonTwo.layer.borderColor = UIColor.white.cgColor
}
}
class TwoCollectionsViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
@IBOutlet weak var firstCV: UICollectionView!
@IBOutlet weak var secondCV: UICollectionView!
@IBAction func Buttons(_ sender: Any) {
if let btn = sender as? UIButton {
print(btn.restorationIdentifier!)
guard let button = sender as? UIButton else { return }
guard let id = Int(button.restorationIdentifier!) else {return}
if id < firstData.count {
performSegue(withIdentifier: "Good Work", sender: btn)
}
else {
performSegue(withIdentifier: "Nice Try", sender: btn)
}
print(button.restorationIdentifier!)
}
}
let firstData: [String] = [
"Good Work", "Nice Try", "Btn 3", "Btn 4", "Btn 5", "Btn 6"
]
let secondData: [String] = [
"Second 1", "Second 2", "Second 3", "Second 4", "Second 5", "Second 6"
]
override func viewDidLoad() {
super.viewDidLoad()
firstCV.dataSource = self
firstCV.delegate = self
secondCV.dataSource = self
secondCV.delegate = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// if it's the First Collection View
if collectionView == firstCV {
return firstData.count
}
// it's not the First Collection View, so it's the Second one
return secondData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// if it's the First Collection View
if collectionView == firstCV {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "firstCell", for: indexPath) as! FirstCollectionViewCell
cell.buttonOne.setTitle(firstData[indexPath.item], for: []) //allows for button title change in code above
cell.buttonOne.restorationIdentifier = "(indexPath.row + firstData.count)"
return cell
}
// it's not the First Collection View, so it's the Second one
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "secondCell", for: indexPath) as! SecondCollectionViewCell
cell.buttonTwo.setTitle(secondData[indexPath.item], for: [])
cell.buttonTwo.restorationIdentifier = "(indexPath.row)"
return cell
}
}
3
Answers
It looks like you only defined
@IBOutlet
variables for your buttons. Create@IBAction
functions and put the code that "open new windows" (i.e. performs segues) in that function.There are many resources online explaining how to do that. One of them is this one.
Just in
didSelectItemAt
write a switch case.Another solution will be add IBAction inside cell and call
handleCases(text : String)
inside cell in this IBAction.I found out it’s better to use @IBAction callback function for the two button’s instead of delegate callback function aka(didSelect)
first you can create @IBAction in (TwoCollectionsViewController) then link both (buttonOne, buttonTwo) to this func, in the mean time while user pressed a button you can know which button was pressed(depends on your use case), for that setting an id for the buttons is best option,
you can add this line to both Collection view button(buttonOne, buttonTwo) before returning the cell in(cellForRowAt):
cell.buttonOne.restorationIdentifier = "(indexPath.row)"
then add:
to the @IBAction func, after that you can use:
override:
prepare(for segue: UIStoryboardSegue, sender: Any?)
functionthen you can configure destination View Controller in the (prepare function)
hopefully this solves your issue 🙂
update:
first change the
inside second if statement (if collectionView == secondCV) to
then change @IBAction to:
after that you can override prepare(for segue: UIStoryboardSegue, sender: Any?) for extra modification , inside (class scope) not in @IBAction
.
.
.
cellForRow:
copy and replace your entire content code with this one: