How to Call Presentviewcontroller from Within a Uicollectionviewcell

how to call presentViewController from within a UICollectionViewCell

UITableViewCell should never handle any business logic. It should be implemented in a view controller. You should use a delegate:

UICollectionViewCell subclass:

protocol CustomCellDelegate: class {
func sharePressed(cell: MyCell)
}

class CustomCell: UITableViewCell {
var delegate: CustomCellDelegate?

func didTapShare(sender: UIButton) {
delegate?.sharePressed(cell: self)
}
}

ViewController:

class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var tableView: UITableView!

//...

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! CustomCell
cell.delegate = self
return cell
}
}

extension TableViewController: CustomCellDelegate {
func sharePressed(cell: CustomCell) {
guard let index = tableView.indexPath(for: cell)?.row else { return }
//fetch the dataSource object using index
}
}

Presenting a ViewController from within a CollectionViewCell that is nested in a TableViewCell

Use protocol and delegate like this

In tableViewCell

protocol CellDelegate {
func colCategorySelected(_ indexPath : IndexPath)
}

var delegate : CellDelegate?

In didSelect

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

delegate?.colCategorySelected(indexPath)
}

In your ProfileViewController

class HomeVC: UIViewController , UITableViewDelegate, UITableViewDataSource, CellDelegate{
:
:

func colCategorySelected(_ indexPath : IndexPath){
// Push here
}
:
:
}

And dont forget

cellForRow

   let Cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! tableCell

Cell.delegate = self // dont forget this line.
return Cell

How to present view controller from UICollectiveViewCell Class - SWIFT

You have to implement custom delegate for this. When user select item from collection view, you have to call parent view method using delegate.

Here is reference for this : Access a UICollectionView's parent UIViewController

How to present a ViewController after pressing a button inside of a CollectionViewCell

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)

How to present a UIViewController on top of UICollectionView?

Create a protocol in your CollectionViewFolderCell.swift

protocol CollectionViewFolderCellDelegate {
func collectionViewFolderCellDidPressButton()
}

And inside CollectionViewFolderCell declare a delegate like:

var delegate: CollectionViewFolderCellDelegate?

Inside your button action add:

@IBAction func moreInfoBtn(_ sender: Any) {

delegate?.collectionViewFolderCellDidPressButton()

}

In your cellForItemAtIndexPath Method add cell.delegate = self

func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CollectionViewFolderCell
cell.delegate = self

return cell
}

Also in your View Controller you need to conform your CollectionViewFolderCellDelegate

extension CollectionViewFolder: CollectionViewFolderCellDelegate {
// here you can present your desired view controller
}

Swift 4 - Push a ViewController from a UICollectionView Cell

1- Inside the cell

weak var delegate:UserProfileController?

2- Inside cellForItemAt

cell.delegate = self

3- Use this inside the cell

delegate?.present(newController, animated: true, completion: nil)

BTW i think you mean

delegate?.navigationController?.pushViewController(newController, animated: true)  

How to transition a UICollectionViewCell via a button to another ViewController?

The problem is that your button's target is the cell, and so the buttonPressed action function is located in the cell. That's a pretty silly thing to do, because (as you rightly say) you cannot call present without a view controller to send it to.

What I would have done is set the button's target/selector in cellForItemAt:. That way, self is the view controller and we can set the target to self. But you didn't do that!

Thus, you need to get from the cell to the view controller that controls it.

However, there is a way. It's called walking the responder chain. Set a UIResponder variable to the button:

var responder : UIResponder = self

Now loop, calling next on responder to walk one step up the chain:

responder = responder.next

Each time, look to see if this responder is a UIViewController. When it is, stop looping and send it present! Thus:

var responder : UIResponder = self
repeat { responder = responder .next } while !(responder is UIViewController)
let vc = responder as! UIViewController
vc.present( // ...

(Still, even though the problem can be solved in this way, I think it was silly to get yourself into this mess in the first place. Making the view controller the target in the first place would have been a much better idea, in my opinion.)

presentViewController from TableViewCell

You should use protocol to pass the action back to tableViewController

1) Create a protocol in your cell class

2) Make the button action call your protocol func

3) Link your cell's protocol in tableViewController by cell.delegate = self

4) Implement the cell's protocol and add your code there

let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)

Present view controller on last item of UICollectionView

viewWillAppear will be called after viewDidLoad. If you need to call this method once your viewcontroller is launched, then you can add the code in the viewDidload method.
But if you still need to use viewWillAppear, I suggest to wrap this call on the main thread or mainqueue. You can use GCD or NSOperationQueue for this.

I think this might help in the delay issue



Related Topics



Leave a reply



Submit