0
votes

Lets say I have 3 cells inside a collectionview. Inside the cell is a follow button, where the isSelected = true state has the title following and the isSelected = false state has the text follow.

The first and third button has a isSelected state of false, and the second button has an isSelected state of true. That makes it false, true, false.

The trouble is, I want to maintain these states when the collection view is reloaded. Whenever I call pull to refresh inside my collectionView, it will read json and load data into the collectionView. Because of how cells are reused, it ends up reloading the previous cell.

So originally, the order would be false, true, false of isSelected state. This would then change to false, false true because of how the cells are reused.

Then, once I make another request to check of what the state of the button should be, it changes back to false, true, false. But, I want to maintain the state rather than having to check the state. Otherwise, it looks buggy. For a split second the isSelected state of the button is incorrect.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {


    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: UserCell.reuseIdentifier, for: indexPath) as! UserCell

    cell.user = user?[indexPath.row]
//            cell.followButton.isSelected = false

    return cell

}

.

class UserCell: UICollectionViewCell {

var user: User? {
    didSet {
        followButton.user = user
    }

    lazy var followButton: FollowButton = {
        let button = FollowButton()
        return button
    }()
}

.

class FollowButton: UIButton {

var user: User? {
    didSet {
        checkIfUserIsFollowed()
    }
}

override var isSelected: Bool {
    didSet {
        self.layer.backgroundColor = isSelected ? UIColor.rgb(50, green: 205, blue: 50).cgColor
                                                : UIColor.white.cgColor
    }
}

override init(frame: CGRect) {
    super.init(frame: frame)
    layer.cornerRadius = 4
    layer.backgroundColor = UIColor.white.cgColor
    translatesAutoresizingMaskIntoConstraints = false

    setTitle("Follow", for: .normal)
    setTitle("Following", for: .selected)

    contentEdgeInsets = UIEdgeInsetsMake(5,5,5,5)
    titleLabel?.font = UIFont(name: "HelveticaNeue", size: 13.0)
    contentHorizontalAlignment = .right

    setTitleColor(UIColor.rgb(50, green: 205, blue: 50), for: .normal)
    setTitleColor(UIColor.white, for: .selected)

    layer.borderWidth = 0.5
    layer.borderColor = UIColor.rgb(50, green: 205, blue: 50).cgColor
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


func checkIfUserIsFollowed() {
    // This is a request that checks where the logged in user is following the user inside the cell.  It either returns true or false and sets the state accordingly
}

}
2
Could you provide realization of your func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCellmethod?Taras Chernyshenko
@TarasChernyshenko doneluke

2 Answers

0
votes

To efficiently achieve this you need to save user data for following list. Then compare these with the data getting from api at the time of polulating data in tableview. Or you have to update data on server in real time and update table with only server data.

0
votes

Not necessarily server side is needed. You can maintain an array of Bool. Length of array = Number of items. On selecting a button update array with the opposite value.

For example: Initially your array looks like [false, false, false]

On selecting button in first cell. Update array with [false, true, false] and simultaneously keep a check in cellForItemAt if value at the index of array is true show following else show follow.