Reputation: 79
Hey i'm new to programming and my problem is, i have a UICollectionViewController
with 4 cells that are horizontal scrollable. Inside of the 4th cell i have a UIButton
(optionsButton
) on top of a UIView
(ProfileContainerView
).
The UIViewController
I want to present is called ProfileEditViewController
and is set up in Main.storyboard
.
How can i present a UIViewController
after pressing this button?
ProfileCell:
class ProfileCell: UICollectionViewCell {
let profileContainerView: UIView = {
let view = UIView()
return view
}()
lazy var optionsButton: UIButton = {
let btn = UIButton(type: .custom)
btn.setImage(#imageLiteral(resourceName: "Settings"), for: UIControlState.normal)
btn.addTarget(self, action: #selector(handleOptionsButton), for: UIControlEvents.touchUpInside)
return btn
}()
@objc func handleOptionsButton() {
print("Button pressed")
}
}
HomeViewController:
class HomeViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let profileCelId = "profileCell"
override func viewDidLoad() {
super.viewDidLoad()
setupSwipeView()
}
func setupSwipeView() {
collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cell)
collectionView?.register(ProfileCell.self, forCellWithReuseIdentifier: profileCelId)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item == 3 {
return collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
}
return cell
}
}
Upvotes: 0
Views: 886
Reputation: 79
let proCell = ProfileCell()
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.cell, for: indexPath)
if indexPath.item == 3 {
let profileCell = collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
let button = proCell.optionsButton
button.addTarget(self, action: #selector(handleOptionsButton), for: UIControlEvents.touchUpInside)
return profileCell;
}
return cell
}
Upvotes: 0
Reputation: 434
You can use delegates to implement this.
Below is the code to implement this
protocol ProfileCollectionViewCellDelegate {
func buttonPressedAtIndexPath(inCell: ProfileCell)
}
class ProfileCell: UICollectionViewCell {
var delegate : ProfileCollectionViewCellDelegate?
let profileContainerView: UIView = {
let view = UIView()
return view
}()
lazy var optionsButton: UIButton = {
let btn = UIButton(type: .custom)
btn.setImage(#imageLiteral(resourceName: "Settings"), for: UIControlState.normal)
btn.addTarget(self, action: #selector(handleOptionsButton), for: UIControlEvents.touchUpInside)
return btn
}()
@objc func handleOptionsButton() {
if self.delegate != nil {
self.delegate?.buttonPressedAtIndexPath(self)
}
}
}
For your HomeViewController
class HomeViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, ProfileCollectionViewCellDelegate {
let profileCelId = "profileCell"
override func viewDidLoad() {
super.viewDidLoad()
setupSwipeView()
}
func setupSwipeView() {
collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cell)
collectionView?.register(ProfileCell.self, forCellWithReuseIdentifier: profileCelId)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
cell.delegate = self
return cell
}
fun buttonPressedAtIndexPath(inCell: ProfileCell) {
let indexOfCell = self.collectionView.indexPath(for: cell)
if indexOfCell.row == 3 {
//Do your work here
}
}
}
Upvotes: 1
Reputation: 6165
You can present your ProfileEditViewController
, which is styled in your Main.storyboard
the following way:
1) Give your ProfileEditViewController
a StoryBoard ID
. E.g. "ProfileEditViewController" - Some question regarding this is here: What is a StoryBoard ID and how can i use this?
2) Register the UIViewController
for the action on the UIButton
or offer an appropriate callback functionality.
As your HomeViewController
is also your Collection View's datasource, you can easily extend your DataSource method
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell`
Implementation could look like:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item == 3 {
let profileCell = collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
if let _cell = cell as? ProfileCell,
let button = _cell.optionsButton as? UIButton {
button.addTarget(self, action: #selector(handleOptionsButton), forControlEvents: UIControlEvents.TouchUpInside)
}
return profileCell;
}
return cell
}
Make sure that your buttons Action is now also being implemented by your HomeViewController
@objc func handleOptionsButton() {
print("Button pressed")
}
3) Now in HomeViewController.handleOptionsButton
you need to provide a functionality to support the transition to that specific Controller with the desired StoryboardID:
let storyboard = UIStoryboard(name: "Main", bundle:Bundle.main)
let controller = storyboard.instantiateViewController(withIdentifier: "ProfileEditViewController")
self.present(controller, animated: true, completion: nil)
Upvotes: 0