首页 > 解决方案 > IBDesignable ButtonView 右边框在方向更改时重叠(横向)

问题描述

我在管理我UITableViewIBDesignable ButtonView方向和方向时遇到了问题。基本上,当我切换到横向时,就会出现问题,里面的 customView 的右边框UITableViewCell是重叠的。仅当我将方向更改为横向时才会发生这种情况。它应该能够在单元格内正确显示右边框。

有人对这个问题有任何想法吗?我附上了一张关于我的布局如何组织和行为的图片:

Portrait,按预期工作

Landscape, 右边界重叠

为了添加更多细节,每个按钮ButtonView都有定义为User Defined Runtime Attributesin 的布尔值Storyboard,这对于前 2 个按钮是正确的。

这是IBDesignable ButtonView实现

import UIKit

@IBDesignable
class ButtonView: UIView {

    // MARK: - Properties
    @IBInspectable var image: UIImage? {
        didSet {
            imageView.image = image
        }
    }

    @IBInspectable var title: String? {
        didSet {
            titleLabel.text = title
        }
    }

    @IBInspectable var hasRightBorder: Bool = false

    @IBInspectable var disabledColor: UIColor = Colors.lightGray
    @IBInspectable var enabledColor: UIColor = Colors.primary
    @IBInspectable var iconSize: CGFloat = 16.0 {
        didSet {
            imageView.addConstraints(width: iconSize, height: iconSize)
        }
    }
    var imageView = UIImageView()
    var titleLabel = UILabel()
    var button = UIButton(type: .custom)

    var isEnabled = true {
        didSet {
            if isEnabled {
                imageView.tintColor = enabledColor
                titleLabel.textColor = enabledColor
            } else {
                imageView.tintColor = disabledColor
                titleLabel.textColor = disabledColor
            }

            button.isEnabled = isEnabled
        }
    }

    var buttonClosure: (() ->Void)?

    // MARK: - Initializers
    override init(frame: CGRect) {
        super.init(frame: frame)

        setupView()
    }

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

        setupView()
    }

    // MARK: - View lifecycle
    override func layoutSubviews() {
        super.layoutSubviews()

        if hasRightBorder {
            layer.addBorder(edge: .right, color: Colors.lightGray, thickness: 1.0)
        } else {
            layer.addBorder(edge: .right, color: UIColor.clear, thickness: 0.0)
        }
    }

    // MARK: - Actions
    @objc fileprivate func buttonTapped() {
        buttonClosure?()
    }

    // MARK: - Private API
    fileprivate func setupView() {
        imageView.tintColor = enabledColor
        imageView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(imageView)
        imageView.topAnchor.constraint(equalTo: topAnchor, constant: 5.0).isActive = true
        imageView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true

        titleLabel.textColor = Colors.primary
        titleLabel.font = FontBook.regular.of(size: .extraSmall)
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        addSubview(titleLabel)
        titleLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -5.0).isActive = true
        titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true

        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        button.translatesAutoresizingMaskIntoConstraints = false
        addSubview(button)
        button.fillSuperview(with: -10.0)
    }

}

addBorder 实现

extension CALayer {

    func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) {
        let border = CALayer();

        switch edge {
        case UIRectEdge.top:
            border.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: thickness)
            break
        case UIRectEdge.bottom:
            border.frame = CGRect(x:0, y:self.frame.height - thickness, width:self.frame.width, height:thickness)
            break
        case UIRectEdge.left:
            border.frame = CGRect(x:0, y:0, width: thickness, height: self.frame.height)
            break
        case UIRectEdge.right:
            border.frame = CGRect(x:self.frame.width - thickness, y: 0, width: thickness, height:self.frame.height)
            break
        default:
            break
        }

        border.backgroundColor = color.cgColor;

        addSublayer(border)
    }

}

这是它的外观Storyboard

标签: iosswiftoverlappingorientation-changesibdesignable

解决方案


我使用不同的方法解决了这个问题。通过查看这个答案,我了解到很多事情,包括旋转设备调用layoutSubview。这就是为什么边界重复。我正在发布我的解决方案,以防有人面临同样的问题。

首先,我没有定义一个 boolean hasRightBorder,而是在里面创建了一个border宽度为 1 的Storyboard

然后,我定义了一个UIView内部ButtonView类,设置宽度和框架高度将其添加到视图中。像魅力一样工作:)

@IBDesignable
class ButtonView: UIView {

    // MARK: - Properties
    @IBInspectable var image: UIImage? {
        didSet {
            imageView.image = image
        }
    }

    //Add the rightBorder support
    @IBInspectable var border: CGFloat = 1.0 {
        didSet {
            view.addConstraints(width: border, height: frame.size.height)
        }
    }

    // MARK: - Initializers
    override init(frame: CGRect) {
        super.init(frame: frame)

        setupView()
    }

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

        setupView()
    }

    //view to add right border
    var view = UIView()

    // MARK: - Private API
    fileprivate func setupView() {

        //Set the color & add it to view
        view.backgroundColor = Colors.lightGray
        view.translatesAutoresizingMaskIntoConstraints = false
        addSubview(view)

        view.rightAnchor.constraint(equalTo: rightAnchor, constant: 0).isActive = true

    }

}

推荐阅读