PennyWise
PennyWise

Reputation: 647

Change label text when selecting UICollectionViewCell

I have a class in which I define a CollectionView which I use as a custom TabBar. It has three cells in it, each representing another tab. When I select a tab (which is thus a cell of the CollectionView), I want to update the text of a label inside my view.

In tabs.swift (where all the magic happens to set up the custom tabbar), I added the following function:

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

    let uvController = UserViewController()
    uvController.longLabel.text = "Test"

}

In UserViewController, I call it like this:

let ProfileTabs: profileTabs = {

    let tabs = profileTabs()
    return tabs

}()

It shows all the tabs I want, but when I select it, the label doesn't update. However, when I perform a print action, it does return the value of the label:

print(uvController.longLabel.text)

This returns the value I defined when I set up the label, so I can in fact access the label, but it doesn't update as I want it to do. Any insight on why this is not happening?

Upvotes: 0

Views: 1094

Answers (2)

Losiowaty
Losiowaty

Reputation: 8006

This line - let uvController = UserViewController() creates a new instance of UserViewController which is not on the screen. You need to reference the one already shown to the user. You can do something like this :

  1. The fastest way. Just pass the instance in ProfileTabs initializer. Something like this:

    class ProfileTabs {
        let parentViewController: UserViewController
    
        init(withParent parent: UserViewController) {
            self.parentViewController = parent
        }
    
        // and then change to :
       func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
            parentViewController.longLabel.text = "Test"
    
        }
    }
    
  2. The cleaner way. Use delegates.

    protocol ProfileTabsDelegate: class {
        func profileTabs(didSelectTab atIndex: Int)
    }
    
    class ProfileTabs {
        weak var delegate: ProfileTabsDelegate?
    
        init(withDelegate delegate: ProfileTabsDelegate) {
            self.delegate = delegate
        }
    
        // and then change to :
       func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            delegate?.profileTabs(didSelectTab: indexPath.item)
    
        }
    }
    

    And then in UserViewController

    extension UserViewController: ProfileTabsDelegate {
        func profileTabs(didSelectTab atIndex: Int) {
            longLabel.text = "Test"
        }
    }
    

Upvotes: 1

Edison Lo
Edison Lo

Reputation: 476

let uvController = UserViewController()

This line is the problem.

You instantiate the a new UserViewController instead of referencing to your current UserViewController, so that the label is not the same one. You can print(UserViewController) to check it out, the address should be different.

My suggestion for you can define a protocol in Tabs.swift and make your UserViewController a delegate of it, to receive the update action.

In the same time, let ProfileTabs: profileTabs is not a good naming convention as well, usually custom class should be in Capital letter instead of the variable.

Upvotes: 2

Related Questions