选择和取消选择可重复使用的视图

时间:2019-06-20 12:48:21

标签: ios swift uiview

我在xib文件中创建一个自定义视图。我在viewController中添加了3个视图(继承自自定义)。最初它们具有白色,但是当我单击第一个视图时,应该将其更改为其他颜色,如果我单击第二个视图,则第一个视图应恢复为白色。

选择第二个视图时,我需要帮助将第一个视图的颜色改回白色。

我的自定义代码在此处查看

class SubscriptionView: UIView {

    @IBOutlet weak var title: UILabel!
    @IBOutlet weak var subTitle: UILabel!
    @IBOutlet weak var checkMark: UIImageView!
    var isSelect: Bool = false

    let nibName = "SubscriptionView"
    var contentView: UIView?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapAction)))
    }

    func commonInit() {
        guard let view = loadViewFromNib() else {
            return
        }
        view.frame = self.bounds
        view.layer.masksToBounds = true
        view.layer.cornerRadius = 14
        view.layerBorderColor = AppColor.amaranth
        view.layerBorderWidth = 0.5
        self.addSubview(view)
        contentView = view
    }

    func loadViewFromNib() -> UIView? {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: nibName, bundle: bundle)
        return nib.instantiate(withOwner: self, options: nil).first as? UIView
    }

    public func selectedView(_ isSelect: Bool) {
        self.isSelect = isSelect
        title.textColor = isSelect ? UIColor.white : AppColor.amaranth
        subTitle.textColor = isSelect ? UIColor.white : AppColor.amaranth
        checkMark.alpha = isSelect ? 1.0 : 0.0
        contentView!.backgroundColor = isSelect ? AppColor.amaranth : UIColor.white
    }

    @objc private func tapAction() {
        ///????? selectedView

    }
}

1 个答案:

答案 0 :(得分:0)

这是一个使用“委托/协议”模式的非常简单的示例。

定义协议:

// Protocol / Delegate pattern
protocol SubscriptionViewDelegate {
    func gotTap(from sender: SubscriptionView)
}

让您的视图控制器符合该协议。在您自定义的SubscriptionView类中,当用户点击时,您会告诉代表收到了点击,控制器将循环遍历SubscriptionView对象,将其设置为“选定”根据点击的视图将状态设置为true或false。

class SubscriptionsViewController: UIViewController, SubscriptionViewDelegate {

    let theStackView: UIStackView = {
        let v = UIStackView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.axis = .vertical
        v.alignment = .fill
        v.distribution = .fill
        v.spacing = 20
        return v
    }()

    // array to track the "subscription" views
    var arrayOfSubscriptionViews: [SubscriptionView] = [SubscriptionView]()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .yellow

        // add a stack view to hold the "subscription" views
        view.addSubview(theStackView)

        NSLayoutConstraint.activate([
            theStackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
            theStackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20.0),
            theStackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20.0),
            ])

        // instantiate 3 "subscription" views
        for _ in 1...3 {

            // instantiate view
            let v = SubscriptionView()

            // set self as its delegate
            v.delegate = self

            // add it to our stack view
            theStackView.addArrangedSubview(v)

            // append it to our tracking array
            arrayOfSubscriptionViews.append(v)

        }

    }

    func gotTap(from sender: SubscriptionView) {

        // just for dev / debugging
        print("got tap from", sender)

        // loop through the subscription views,
        // setting the sender selected to TRUE
        // the others to FALSE

        arrayOfSubscriptionViews.forEach {
            $0.selectedView($0 == sender)
        }

    }

}

// Protocol / Delegate pattern
protocol SubscriptionViewDelegate {
    func gotTap(from sender: SubscriptionView)
}

class SubscriptionView: UIView {

    @IBOutlet weak var title: UILabel!
    @IBOutlet weak var subTitle: UILabel!
    @IBOutlet weak var checkMark: UIImageView!
    var isSelect: Bool = false

    var delegate: SubscriptionViewDelegate?

    let nibName = "SubscriptionView"
    var contentView: UIView?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    func commonInit() {
        guard let view = loadViewFromNib() else {
            return
        }
        view.frame = self.bounds
        view.layer.masksToBounds = true
        view.layer.cornerRadius = 14
        view.layer.borderColor = UIColor.red.cgColor // AppColor.amaranth
        view.layer.borderWidth = 0.5
        self.addSubview(view)
        contentView = view

        selectedView(false)

        addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapAction)))
    }

    func loadViewFromNib() -> UIView? {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: nibName, bundle: bundle)
        return nib.instantiate(withOwner: self, options: nil).first as? UIView
    }

    public func selectedView(_ isSelect: Bool) {
        self.isSelect = isSelect
        title.textColor = isSelect ? UIColor.white : .red // AppColor.amaranth
        subTitle.textColor = isSelect ? UIColor.white : .red // AppColor.amaranth
        checkMark.alpha = isSelect ? 1.0 : 0.0
//      contentView!.backgroundColor = isSelect ? AppColor.amaranth : UIColor.white
        contentView!.backgroundColor = isSelect ? UIColor.red : UIColor.white
    }

    @objc private func tapAction() {

        // for dev / debugging
        print("sending tap from", self)

        // tell the delegate self got tapped
        delegate?.gotTap(from: self)

    }
}

我只对您的SubscriptionView类进行了微小的更改,因此您应该可以将其与现有的.xib一起使用