Swift- Custom Uitableviewcell Delegate to Uiviewcontroller Only One Protocol Works

Delegate Method to UItableViewCell Swift

If I correctly understood your question, maybe this could help:

class ViewController: UIViewController, YourCustomTableDelegate {

@IBOutlet weak var tableView: YourCustomTableView!

override func viewDidLoad() {
super.viewDidLoad()
self.tableView.customTableDelegate = self
}

// table delegate method
func shouldAnimateCell(at indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.animate(...)
}
}
}

TableViewCell delegation with Swift

Create a protocol in DetailVC.

//DetailVC

protocol SecondViewControllerDelegate: class {
func toggleFeatured (indexOfCell index: Int, isEnable: Bool)
}

When star value is change than call this delegate function.

delegate?.toggleFeatured(indexOfCell: indexOfCell, isEnable: isEnable)

In Masterviewcontroller's tableview didselected function set delegate

//MasterViewController

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let detailVC = DetailVC()/* get detalVC object */

detailVC.delgate = self
detailVC.indexOfCell = indexPath.row

//show detailvc
}

If you don't want to reload complete tableview then you can reload cell only.

extension MasterViewController: SecondViewControllerDelegate {
func toggleFeatured(indexOfCell index: Int, isEnable: Bool) {

let object = array[index]
// Logic to enable or disable star for for object

tableView.reloadRows(at: [IndexPath(item: index, section: 0)], with: .automatic)
}
}

MOST IMPORTANT

Don't forgot to make the delegate weak. weak keyword won't let the retain count increase by one hence retain cycle don't generate and memory leak problems won't come. if we don't write and any keyword then it will be strong by default which increase the retain count and create retain cycle(Deadlock).

And We need to make protocol class type because weak keyword can be use only with class type protocol. check protocol declaration, it inherited class

class DetailVC {
weak delegate: SecondViewControllerDelegate?
}

Check out this video to understand memory leak and fix it.

https://www.youtube.com/watch?v=sp8qEMY9X6Q

Swift 5: Trying to set up a delegate, but the function isn't launching

This...

let fcsViewController = FCSViewController()

...creates an instance of FCSViewController that you never do anything with except set the delegate.

Since you are using a segue to display a FCSViewController instance, you need to set the delegate on the one that's the segue destination. Implement prepareForSegue and set the delegate there.

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621490-prepareforsegue

Passing data from one custom uitableviewcell to another using Delegates in swift

It doesn't work because in AlbumCell you create another instance of AlbumsPickerTableViewCell and use it for delegation.

Generally speaking, implementing a delegate from one cell to another doesn't feel right. You can quickly find yourself in the situation when you need the value from the first cell in the controller and have no way of obtaining it. Also, a strange behaviour can occur if those cells are going to be reused by table view.

In your case, it worth making UIViewController which contains UITableView a delegate of AlbumsPickerTableViewCell, and when it gets called from the cell, pass data into AlbumCell.

Also, don't forget that references to the delegate should be weak to prevent strong reference cycle.

Swift Creates a Protocol but it does not work

I think you're implementing the delegate backwards. The UIViewController should be declaring itself the delegate of the cell, so that it responds to a call from the cell. So instead, it should look like this:

//TableViewCell
public protocol DataEnteredDelegate: class {
func userDidEnterInformation(info: NSString)
}
class UIChatBubbleTableViewCell: UITableViewCell{

internal var delegate: DataEnteredDelegate?
{

func tapLabel(tapLabel: TapLabel, didSelectLink link: String) {
print(link)
self.delegate?.userDidEnterInformation(link)

}

}

//UIViewController
class ChatViewController: UITableViewController, DataEnteredDelegate{

override internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("identifier", forIndexPath: indexPath) as!UIChatBubbleTableViewCell
cell.delegate = self

return cell
}

func userDidEnterInformation(info: NSString) {
//do thing
}

}

Delegates/Protocols between UIView & UIViewController not working

Your issue will be fixed if you set delegate while adding SideMenuHomeView as below,

func configureSideMenuHomeView() {
sideMenuHomeView = SideMenuHomeView()
view.addSubview(sideMenuHomeView)
self.menuDelegate = sideMenuHomeView
sideMenuHomeView.anchorwithConstant(top: view.topAnchor, bottom: view.bottomAnchor, leading: view.leadingAnchor, trailing: nil, paddingTop: 0, paddingBottom: 0, paddingLeading: -(view.frame.width - 20), paddingTrailing: 0, width: view.frame.width, height: 0)
}

But you are using wrong delegation here. When you have instance of SideMenuHomeView then you don't need its delegate reference explicitly as you already have all the methods on the instance. It's like two references to same object.

Protocol delegate not working within custom UIView button

Update your LoginViewController like so:

class LoginViewController: UIViewController {

static weak var shared: LoginViewController?

@IBOutlet weak var loginButton: UIButton!

weak var delegate: LoginDelegates? // Initite the delegate variable

//Login Button Action
@IBAction func loginButtonPressed(_ sender: UIButton) {
delegate?.loginButtonPressed(sender: loginButton)
}

override func viewDidLoad() {
super.viewDidLoad()
// All your viewDidLoad stuff

LoginViewController.shared = self

}
}

Update your AccessViewController like so:

class AccessViewController: UIViewController, LoginDelegates {

override func viewDidLoad() {
super.viewDidLoad()
// All your viewDidLoad stuff

LoginViewController.shared?.delegate = self

}

func loginButtonPressed(sender: AnyObject) {
performSegue(withIdentifier: "toDashboard", sender: self)
}
}

The problem you have caused because you don't have access to your active instance of LoginViewController. In both your approaches you create a new instance of LoginViewController but you need to access existing instance. To make this you have to create static variable which will keeps for you a reference to the active instance of the LoginViewController.

Also please remember that in most cases you have to mark delegate variable as weak to avoid memory leaks.

Because of you load and present view of your LoginViewController directly in AccessViewController view your LoginViewController is not the firstResponder. Because of this the action of your button is not called while pressing.

You can make some trick in your AccessViewController class

class AccessViewController: UIViewController, LoginDelegates {

override func viewDidLoad() {
super.viewDidLoad()
// All your viewDidLoad stuff

let loginVC = LoginViewController()

loginVC.loginButton.addTarget(self, action: #selector(self.loginButtonPressed), for: .touchUpInside)

//add your LoginViewController view as subview to your AccessController view.

}

@objc func loginButtonPressed() {
performSegue(withIdentifier: "toDashboard", sender: self)
}
}


Related Topics



Leave a reply



Submit