【问题标题】:Add UIView rounding logic inside UIView class在 UIView 类中添加 UIView 舍入逻辑
【发布时间】:2017-07-04 04:20:38
【问题描述】:

我有一个自定义 UIView 并将其添加到我的 ViewController 中,如下所示:

let myCustomView = Bundle.main.loadNibNamed("MyCustomView", owner: nil, options: nil) as! MyCustomView
myCustomView.layer.cornerRadius = 10
myCustomView.layer.masksToBounds = true

我绕过视图的角落。但我想知道,有没有办法在 MyCustomView 类中移动这种圆角逻辑?

【问题讨论】:

  • 你在哪里叫这个..
  • 嘿@BlueBoy,欢迎来到 StackOverflow。如果您有时间将其中一个答案标记为已接受,那就太好了。

标签: ios swift


【解决方案1】:

在使用 IB 时,您可能会发现扩展 UIView 会更方便

extension UIView {
    @IBInspectable var borderColor: UIColor? {
        set {
            layer.borderColor = newValue?.cgColor
        }
        get {
            if let color = layer.borderColor {
                return UIColor(cgColor:color)
            } else {
                return nil
            }
        }
    }

    @IBInspectable var borderWidth: CGFloat {
        set {
            layer.borderWidth = newValue
        }
        get {
            return layer.borderWidth
        }
    }

    @IBInspectable var cornerRadius: CGFloat {
        set {
            layer.cornerRadius = newValue
            clipsToBounds = newValue > 0
        }
        get {
            return layer.cornerRadius
        }
    }
}

然后您可以从属性检查器中设置这些值。

【讨论】:

  • 很棒的解决方案:)
  • 我真的不明白为什么这被认为是一个好的解决方案。您将这些属性公开给每个 UIView 类,而问题是询问一个特定的子类。我想这也会大大减慢故事板的加载速度。
  • @Leon “相当”听起来有点沉重。我已经说过“如果你使用 IB”和“为了方便”。我也同意指出的开销。
  • 也许吧,虽然看起来 UIView 无论如何都不会在情节提要中呈现,所以没有真正的影响。然而,这不是提出的主要问题。
【解决方案2】:

是的 - 如果您使用自定义视图加载 nib,则该 nib 很可能是指另一个类。如果是这种情况,您可以在类本身内部移动逻辑。

也就是说,我真的很喜欢 Lawliet's suggestion 使用 IBInspectable 属性制作 UIView 扩展。这种方法的缺点是现在每个视图都具有这些属性,这会产生一定的开销和潜在的冲突。

【讨论】:

    【解决方案3】:

    你可以在你的 UIView 子类中做这样的事情:

    class RoundedView: UIView {
    
        /*
        // Only override draw() if you perform custom drawing.
        // An empty implementation adversely affects performance during animation.
        override func draw(_ rect: CGRect) {
            // Drawing code
        }
        */
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.layer.cornerRadius = 10
            self.layer.masksToBounds = true
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            self.layer.cornerRadius = 10
            self.layer.masksToBounds = true
        }
    
    }
    

    此外,如果您想在cornerRadius 属性中传递自定义值而不是“10”,您可以尝试通过查看此处来实现便利的初始化:

    Override Init method of UIView in Swift

    【讨论】:

    • 这是我正在寻找的,但是当我运行它时得到fatal error: init(coder:) has not been implemented
    • 尝试在init coder函数super.init(coder:aDecoder)中添加这个
    • 停止崩溃,但没有效果。
    • 哦……我的错。您正在从 nib 文件加载视图。这将导致调用 init(coder:) 而不是 init(frame:)。因此,您还需要这两行来在 init(coder:) 函数中设置 layer 属性。我已经更新了我的答案。
    猜你喜欢
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    相关资源
    最近更新 更多