为按钮添加目标不适用于另一个 UIView

问题描述 投票:0回答:1

我为视图控制器实现了标头(UIView),但我无法为 UIView 内部的按钮添加目标。我相信这对每个人来说都很容易理解,但如果您愿意,我可以添加更多细节

loadView() 内的我的视图控制器代码

let headerViewModel = HeaderViewModel(title: "Farmers", helpAction:  {self.navigationController?.popViewController(animated: true) // when debugging this        //line doesn't work when adding })
let headerView = HeaderView(viewModel: headerViewModel)

我的标题 UIView 代码

import UIKit

protocol HeaderViewModelProtocol {
    var title: String { get }
    var color: UIColor { get }
    var imageName: String? { get }
    var backAction: (()->Void)? { get set}
    var helpAction: (()->Void)? { get set}
}

struct HeaderViewModel: HeaderViewModelProtocol {
    let title: String
    var color: UIColor = UIColor.white
    var imageName: String?
    var backAction: (() -> Void)?
    var helpAction: (() -> Void)?
}

class HeaderView: UIView {
    
    let viewModel: HeaderViewModelProtocol
    private var layer0: CAGradientLayer!
    
    var backButton: UIButton = {
        let button = UIButton()
            button.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
            button.addTarget(HeaderView.self, action: #selector(tapBack), for: .touchUpInside)
            button.backgroundColor = UIColor.red
            button.tag=5
            button.translatesAutoresizingMaskIntoConstraints = false
            button.backgroundColor = .clear
            button.tintColor = .white
            button.setImage(UIImage(named: "back"), for: .normal)
            return button
    }()
    
    
    var helpButton: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.backgroundColor = .clear
        button.setImage(UIImage(named: "plus"), for: .normal)
        button.tintColor = .white
        return button
    }()
    init(viewModel: HeaderViewModelProtocol) {
        self.viewModel = viewModel
        super.init(frame: .zero)
        loadView()
    }
    func loadView() {
        if viewModel.backAction != nil {
            backButton.addTarget(self, action: #selector(tapBack), for: .touchUpInside)
            
            addSubview(backButton)
            
            backButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 30).isActive = true
            backButton.topAnchor.constraint(equalTo: topAnchor, constant: 36).isActive = true
            backButton.widthAnchor.constraint(equalToConstant: 22).isActive = true
            backButton.heightAnchor.constraint(equalToConstant: 36).isActive = true
        }
        
        if viewModel.helpAction != nil {
            helpButton.addTarget(self, action: #selector(tapHelp), for: .touchUpInside)
            addSubview(helpButton)
            
            helpButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -30).isActive = true
            helpButton.topAnchor.constraint(equalTo: topAnchor, constant: 36).isActive = true
            helpButton.widthAnchor.constraint(equalToConstant: 22).isActive = true
            helpButton.heightAnchor.constraint(equalToConstant: 36).isActive = true
        }
    }

    @objc func tapBack() {
        viewModel.backAction?()
    }
    
    @objc func tapHelp() {
        viewModel.helpAction?()
    }
}

先谢谢大家了!可以联系我哦!

swift button uiview addtarget
1个回答
0
投票

你的评论说你“给headerview高度140”...但是你没有显示如何你正在这样做,所以我仍然认为你的按钮最终超出了视图边界。

这是您的代码,稍作修改:

protocol HeaderViewModelProtocol {
    var title: String { get }
    var color: UIColor { get }
    var imageName: String? { get }
    var backAction: (()->Void)? { get set}
    var helpAction: (()->Void)? { get set}
}

struct HeaderViewModel: HeaderViewModelProtocol {
    let title: String
    var color: UIColor = UIColor.white
    var imageName: String?
    var backAction: (() -> Void)?
    var helpAction: (() -> Void)?
}

class HeaderView: UIView {
    
    let viewModel: HeaderViewModelProtocol
    private var layer0: CAGradientLayer!
    
    var backButton: UIButton = {
        let button = UIButton()
        button.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
        button.addTarget(HeaderView.self, action: #selector(tapBack), for: .touchUpInside)
        button.backgroundColor = UIColor.red
        button.tag=5
        button.translatesAutoresizingMaskIntoConstraints = false
        button.backgroundColor = .clear
        button.tintColor = .white
        button.setImage(UIImage(named: "back"), for: .normal)

        // during development, use a background color so we can easily see the frame
        button.backgroundColor = .red

        return button
    }()
    
    
    var helpButton: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.backgroundColor = .clear
        button.setImage(UIImage(named: "plus"), for: .normal)
        button.tintColor = .white

        // during development, use a background color so we can easily see the frame
        button.backgroundColor = .blue

        return button
    }()
    init(viewModel: HeaderViewModelProtocol) {
        self.viewModel = viewModel
        super.init(frame: .zero)
        loadView()
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    func loadView() {
        if viewModel.backAction != nil {
            backButton.addTarget(self, action: #selector(tapBack), for: .touchUpInside)
            
            addSubview(backButton)
            
            backButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 30).isActive = true
            backButton.topAnchor.constraint(equalTo: topAnchor, constant: 36).isActive = true
            backButton.widthAnchor.constraint(equalToConstant: 22).isActive = true
            backButton.heightAnchor.constraint(equalToConstant: 36).isActive = true

            // if you want these UI elements to determine the height
            //backButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -36).isActive = true
        }
        
        if viewModel.helpAction != nil {
            helpButton.addTarget(self, action: #selector(tapHelp), for: .touchUpInside)
            addSubview(helpButton)
            
            helpButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -30).isActive = true
            helpButton.topAnchor.constraint(equalTo: topAnchor, constant: 36).isActive = true
            helpButton.widthAnchor.constraint(equalToConstant: 22).isActive = true
            helpButton.heightAnchor.constraint(equalToConstant: 36).isActive = true

            // if you want these UI elements to determine the height
            //helpButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -36).isActive = true
        }
        
    }
    
    @objc func tapBack() {
        print("back tapped")
        viewModel.backAction?()
    }
    
    @objc func tapHelp() {
        print("help tapped")
        viewModel.helpAction?()
    }
}

和一个示例视图控制器来展示它的工作原理:

class HeaderViewVC: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()

        let headerViewModel = HeaderViewModel(title: "Farmers", helpAction:  {
            print("Farmers Help Action")
            self.navigationController?.popViewController(animated: true) // when debugging this        //line doesn't work when adding })
        })
        let headerView = HeaderView(viewModel: headerViewModel)
        
        headerView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(headerView)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            headerView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
            headerView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
            headerView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
            headerView.heightAnchor.constraint(equalToConstant: 140.0),
        ])
    
        // during development... makes it easy to see the view framing
        headerView.backgroundColor = .cyan
        
    }
    
}

运行它,你会看到:

help tapped
Farmers Help Action

点击按钮时输出到调试控制台。

将此代码与您的实际代码进行比较,看看有什么不同。

© www.soinside.com 2019 - 2024. All rights reserved.