UIButton in HeaderView not clickable

Hi everyone, ran into this problem: there is a table view; it has a header view. header view has 2 buttons one button (expandButton) is clickable and the other (closeButton) is not please help me figure it out

    private(set) lazy var expandButton: UIButton = {

        let button = UIButton()

        button.setTitleStyled(buttonLabelText, fontName: Constants.robotoMediumFont, fontSize: appearance.expandButtonLabelSize, fontColor: appearance.textColor)

        button.addTarget(self, action: #selector(expandLabel), for: .touchUpInside)

        return button

    }()

    private(set) lazy var closeButton: UIButton = {

       let button = UIButton()

        button.translatesAutoresizingMaskIntoConstraints = false

        button.setImage(UIImage(named: "24_x_24_close"), for: .normal)

        button.addTarget(self, action: #selector(closeButtonTapped), for: UIControl.Event.touchUpInside)

        return button

    }()

   
    @objc func expandLabel() {

        print("Done")

        let params: [AnyHashable : Any] = ["installationId": Constants.deviceUniqueId as Any, "product": product?.code as Any]

        appMetricaFactory = factory.makeAppMetricaFactory()

        appMetricaFactory?.sendRequest(name: "productShowMoreDescription", parametrs: params)

        if CardConst.expandedState == .collapsed {

            CardConst.expandedState = .expanded

        } else {

            CardConst.expandedState = .collapsed

        }

        ProductCardViewController.shared?.updateView()

    }

    

    @objc func closeButtonTapped(_ sender: UIButton) {

        print("Tapped")

        ProductCardViewController.shared?.customizeView()
        onClose?()
    }

Replies

Do you see the close button ? Where is it in the debug view : could you circle the 2 buttons in the screenshot ?

Could you show the code where you add buttons to headerView ?

private func addSubviews() {

addSubview (предварительный просмотр TextLabel)

addSubview (detailTextView)

addSubview (expandButtonView)

detailTextView.addSubview(detailTextLabel)

expandButtonView.addSubview(expandButton)

expandButtonView.addSubview(underlineView)

}

expandButton.snp.makeConstraints { (make) в

make.leading.equalToSuperview()

make.top.equalToSuperview()

make.bottom.equalToSuperview()

}

если bannerCode == product.code {

addSubview(bannerImageView)
bannerImageView.addSubview (близко кнопка)

bannerImageView.snp.makeConstraints { сделать в

make.top.equalTo(underlineView.snp.bottom).offset(16)

make.leading.equalToSuperview()

make.trailing.equalToSuperview()

make.height.equalTo(88)

}
closeButton.snp.makeConstraints { сделать в

make.trailing.equalTo(bannerImageView.snp.trailing).inset(16)

make.bottom.equalTo(bannerImageView.snp.bottom).inset(56)

make.height.width.equalTo(24)

}

screen

Thanks for the information, but I still don't see where you add closeButton.

In the screenshot, closeButton seems to be in a different view than expandButton.

In addition, your code is not formatted, it is very hard to read. And it seems there are closing brackets that are wrongly placed…

private func addSubviews() {
    
    addSubview (предварительный просмотр TextLabel)
    addSubview (detailTextView)
    addSubview (expandButtonView)
    detailTextView.addSubview(detailTextLabel)
    expandButtonView.addSubview(expandButton)
    expandButtonView.addSubview(underlineView)
}      // <<-- Are you sure there should be a closing bracket here ? The following code is "free floating"

expandButton.snp.makeConstraints { (make) в
    make.leading.equalToSuperview()
    make.top.equalToSuperview()
    make.bottom.equalToSuperview()
}

если bannerCode == product.code {  // <<-- No closing bracket 

addSubview(bannerImageView)
bannerImageView.addSubview (близко кнопка)

    bannerImageView.snp.makeConstraints { сделать в
        make.top.equalTo(underlineView.snp.bottom).offset(16)
        make.leading.equalToSuperview()
        make.trailing.equalToSuperview()
        make.height.equalTo(88)
    }

    closeButton.snp.makeConstraints { сделать в
        make.trailing.equalTo(bannerImageView.snp.trailing).inset(16)
        make.bottom.equalTo(bannerImageView.snp.bottom).inset(56)
        make.height.width.equalTo(24)
    }
import UIKit
import SnapKit
class HeaderDetailView: UIView {
    
    var onClose: (() -> Void)?

    private(set) lazy var expandButtonView: UIView = {
        let view = UIView()
        return view
    }()

    private(set) lazy var expandButton: UIButton = {
        let button = UIButton()
        button.setTitleStyled(buttonLabelText, fontName: Constants.robotoMediumFont, fontSize: appearance.expandButtonLabelSize, fontColor: appearance.textColor)
        button.addTarget(self, action: #selector(expandLabel), for: .touchUpInside)
        return button
    }()

    private(set) lazy var underlineView: UIView = {
        let view = UIView()
        view.backgroundColor = appearance.underlineColor
        return view
    }()
    
    private(set) lazy var bannerImageView: UIImageView = {
        let banner = UIImageView()
         banner.translatesAutoresizingMaskIntoConstraints = false
         banner.backgroundColor = .grey.withAlphaComponent(0.5)
         banner.contentMode = .scaleAspectFill
         return banner
    }()

    private(set) lazy var closeButton: UIButton = {
       let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(named: "24_x_24_close"), for: .normal)
        button.addTarget(self, action: #selector(closeButtonTapped), for: UIControl.Event.touchUpInside)
        return button
    }()

    init() {
        super.init(frame: UIScreen.main.bounds)
        addSubviews()
        makeConstraints()
    }

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

    private func addSubviews() {
        addSubview(previewTextLabel)
        addSubview(detailTextView)
        addSubview(expandButtonView)
        detailTextView.addSubview(detailTextLabel)
        expandButtonView.addSubview(expandButton)
        expandButtonView.addSubview(underlineView)
    }

    func updateView(with product: ProductCard, code: Int, banner: ActionBannerModel?) {
        self.bannerCode = code
        self.banner = banner
        notificationView.product = product
        previewTextLabel.text = product.name
        detailTextLabel.text = product.detailText.htmlToString
        if product.isAvailable == 0 {
            addSubview(notificationView)
            notificationView.code = product.code
            notificationView.snp.makeConstraints { make in
                make.top.equalTo(underlineView.snp.bottom).offset(24)
                make.leading.equalToSuperview().offset(appearance.defaultOffset)
                make.trailing.equalToSuperview().offset(-appearance.defaultOffset)
                make.height.equalTo(139)
            }
            notificationView.onMessageView = { [weak self] status in
                guard let self = self else { return }
                self.delegate?.createNotificatiom(status)
            }
        }
        if bannerCode == product.code {
            addSubview(bannerImageView)
            bannerImageView.addSubview(closeButton)
            bannerImageView.snp.makeConstraints { make in
                make.top.equalTo(underlineView.snp.bottom).offset(16)
                make.leading.equalToSuperview()
                make.trailing.equalToSuperview()
                make.height.equalTo(88)
            }
            closeButton.snp.makeConstraints { make in
                make.trailing.equalTo(bannerImageView.snp.trailing).inset(16)
                make.bottom.equalTo(bannerImageView.snp.bottom).inset(56)
                make.height.width.equalTo(24)
            }
            guard let banner = banner else { return }
            setBannerView(urlString: banner.img, title: banner.text, date: banner.dateFull)
        }
    }

    private func makeConstraints() {
        previewTextLabel.snp.makeConstraints { (make) in
            make.leading.equalToSuperview().offset(appearance.defaultOffset)
            make.trailing.equalToSuperview().inset(appearance.defaultOffset)
            make.top.equalToSuperview().offset(appearance.defaultOffset)
        }
        detailTextView.snp.makeConstraints { (make) in
            make.leading.equalToSuperview().offset(appearance.defaultOffset)
            make.trailing.equalToSuperview().inset(appearance.defaultOffset)
            make.top.equalTo(previewTextLabel.snp.bottom).offset(appearance.defaultOffset / 2)
        }
        detailTextLabel.snp.makeConstraints { (make) in
            make.leading.equalToSuperview()
            make.trailing.equalToSuperview()
            make.top.equalToSuperview()
            make.bottom.equalToSuperview()
        }
        expandButtonView.snp.makeConstraints { (make) in
            make.leading.equalToSuperview().offset(appearance.defaultOffset)
            make.trailing.equalToSuperview().inset(appearance.defaultOffset)
            make.top.equalTo(detailTextView.snp.bottom)
        }
        expandButton.snp.makeConstraints { (make) in
            make.leading.equalToSuperview()
            make.top.equalToSuperview()
            make.bottom.equalToSuperview()
        }
        underlineView.snp.makeConstraints { (make) in
            make.top.equalTo(expandButton.snp.bottom).offset(appearance.underlineViewTopOffset)
            make.leading.equalToSuperview()
            make.width.equalTo(expandButton.snp.width)
            make.height.equalTo(appearance.underlineViewHeight)
        }
    }

    @objc func expandLabel() {
        print("Done")
        let params: [AnyHashable : Any] = ["installationId": Constants.deviceUniqueId as Any, "product": product?.code as Any]
        appMetricaFactory = factory.makeAppMetricaFactory()
        appMetricaFactory?.sendRequest(name: "productShowMoreDescription", parametrs: params)
        if CardConst.expandedState == .collapsed {
            CardConst.expandedState = .expanded
        } else {
            CardConst.expandedState = .collapsed
        }
        ProductCardViewController.shared?.updateView()
    }

    @objc func closeButtonTapped(_ sender: UIButton) {
        print("Tapped")
        ProductCardViewController.shared?.customizeView()
        onClose?()
    }
}

It is a bit difficult to understand all the code, as some class definitions are not accessible.

However, I would change here:

        if bannerCode == product.code {
            addSubview(bannerImageView)
            bannerImageView.addSubview(closeButton)
            bannerImageView.snp.makeConstraints { make in
                make.top.equalTo(underlineView.snp.bottom).offset(16)
                make.leading.equalToSuperview()
                make.trailing.equalToSuperview()
                make.height.equalTo(88)
            }

When you use, bannerImageView has no frame defined.

So, could you try:

        if bannerCode == product.code {
            addSubview(bannerImageView)
            bannerImageView.snp.makeConstraints { make in
                make.top.equalTo(underlineView.snp.bottom).offset(16)
                make.leading.equalToSuperview()
                make.trailing.equalToSuperview()
                make.height.equalTo(88)
            }
            bannerImageView.addSubview(closeButton)

Thanks for your help, but I solved this problem by adding the following line

bannerImageView.isUserInteractionEnabled = true