0

A button in my custom collection view cell is not highlighting when tapped(optionsButton)...any action that I add works. However, the system highlight is not showing when touching the button.

Code below...

class HomeFeedCell: UICollectionViewCell {
    
    public lazy var userProfilePhotoimageView: UIImageView = {
        let iv = UIImageView()
        iv.translatesAutoresizingMaskIntoConstraints = false
        iv.clipsToBounds = true
        iv.backgroundColor = .systemBlue
        iv.contentMode = .scaleAspectFill
        iv.layer.cornerRadius = 40 / 2
        return iv
    }()
    
    public lazy var profileNameLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.clipsToBounds = true
        label.text = "UserName"
        return label
    }()
    
    public lazy var imageView: UIImageView = {
        let iv = UIImageView()
        iv.translatesAutoresizingMaskIntoConstraints = false
        iv.clipsToBounds = true
        iv.image = UIImage(systemName: "photo")
        iv.contentMode = .scaleAspectFill
        return iv
    }()
    
     public lazy var optionsButton: UIButton = {
        let button = UIButton(type: .system)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.titleLabel?.font = UIFont.preferredFont(forTextStyle: .body)
        button.setTitle("Done", for: .normal)
        return button
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
}
    
    private func commonInit() {
        setupProfilePhotoConstraints()
        setupImageViewConstraints()
        setupOptionsButtonConstraints()
        setupProfileNameLabelConstraints()
    }
    
    private func setupProfilePhotoConstraints() {
        addSubview(userProfilePhotoimageView)
        NSLayoutConstraint.activate([
            userProfilePhotoimageView.topAnchor.constraint(equalTo: topAnchor, constant: 8),
            userProfilePhotoimageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8),
            userProfilePhotoimageView.widthAnchor.constraint(equalToConstant: 40),
            userProfilePhotoimageView.heightAnchor.constraint(equalTo: userProfilePhotoimageView.widthAnchor)
        ])
    }
    
    private func setupProfileNameLabelConstraints() {
        addSubview(profileNameLabel)
        NSLayoutConstraint.activate([
            profileNameLabel.topAnchor.constraint(equalTo: topAnchor),
            profileNameLabel.leadingAnchor.constraint(equalTo: userProfilePhotoimageView.trailingAnchor, constant: 8),
            profileNameLabel.bottomAnchor.constraint(equalTo: imageView.topAnchor),
            profileNameLabel.trailingAnchor.constraint(equalTo: optionsButton.leadingAnchor)
        ])
    }
    
    private func setupImageViewConstraints() {
        addSubview(imageView)
        NSLayoutConstraint.activate([
            imageView.topAnchor.constraint(equalTo: userProfilePhotoimageView.bottomAnchor, constant: 8),
            imageView.leadingAnchor.constraint(equalTo: leadingAnchor),
            imageView.bottomAnchor.constraint(equalTo: bottomAnchor),
            imageView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])
    }
    
    private func setupOptionsButtonConstraints() {
        addSubview(optionsButton)
        NSLayoutConstraint.activate([
            optionsButton.topAnchor.constraint(equalTo: topAnchor),
            optionsButton.bottomAnchor.constraint(equalTo: imageView.topAnchor),
            optionsButton.trailingAnchor.constraint(equalTo: trailingAnchor),
            optionsButton.widthAnchor.constraint(equalToConstant: 44),
        ])
    }
    
    public func configureCellPhoto(_ imageURL: String) {
        guard let url = URL(string: imageURL) else { return }
        imageView.kf.setImage(with: url)
    }
    
    @objc private func handleOptions() {
        print("tapped")
    }
}

I have tried everything that I can think of...even used chat gpt, which was useless lol Any help would be greatly appreciated!

3 Answers3

2

Every time you say addSubview, that's wrong. Change it to contentView.addSubview and your button will start working.

matt
  • 515,959
  • 87
  • 875
  • 1,141
0

UPDATE: So the highlight does indeed work. When I tap on the button both in the simulator or on my phone, there is not an immediate highlight response as in other cases...that is why I wasn't seeing anything. However, when I press the button firmly, kind of like a forceful press (longer than a tap), then let go, I see a highlight...? So I don't know exactly what is going on, but there is a response. My theory is that there could be something about the constraints that are making the area of touch too small. However, the button size is bigger than Apple's recommendation of 44x44. IDK. I did try changing .addSubview to contentView.addSubview, but I do believe that both approaches work (tested both and same result) when adding content to the CV cell's superview. Nonetheless, the .system feature does work when the button is firmly pressed!

  • The delay is because it takes a little while for the scroll view to decide if you are starting a drag or not. The button’s tap gesture is delayed until the scroll view’s drag gesture fails to be recognised. Subclassing the scroll view (or collection view in your case), setting a property and overriding a method should allow the button tap to be recognised immediately. See https://stackoverflow.com/questions/3642547/uibutton-touch-is-delayed-when-in-uiscrollview/19656611#19656611 – Geoff Hackworth Apr 26 '23 at 08:30
  • Thank you so much Geoff!! The solution that solved it was this: collectionView.delaysContentTouches = false – Brendon Crowe Apr 26 '23 at 18:39
  • I think you might need to override `touchesShouldCancelInContentView` otherwise you won’t be able to start dragging the scroll view while the button is highlighted. – Geoff Hackworth Apr 26 '23 at 19:05
-1

Try this option:

    private func setupOptionsButtonConstraints() {
    addSubview(optionsButton)
    optionsButton.addTarget(self, action: #selector(handleOptions), for: .touchUpInside)
    NSLayoutConstraint.activate([
        optionsButton.topAnchor.constraint(equalTo: topAnchor),
        optionsButton.bottomAnchor.constraint(equalTo: imageView.topAnchor),
        optionsButton.trailingAnchor.constraint(equalTo: trailingAnchor),
        optionsButton.widthAnchor.constraint(equalToConstant: 44),
    ])
}
@objc private func handleOptions() {
    print("tapped")
    optionsButton.isHighlighted = true
}
NexusUA
  • 217
  • 1
  • 3
  • 13