@IBDesignable UIView 不在情节提要中调用 init

Posted

技术标签:

【中文标题】@IBDesignable UIView 不在情节提要中调用 init【英文标题】:@IBDesignable UIView not calling init within storyboard 【发布时间】:2018-07-24 11:27:22 【问题描述】:

我有一个UIView,即@IBDesignable

@IBDesignable
class MyView: UIView 

    override init(frame: CGRect) 
        super.init(frame: frame)
        sharedInit()
    

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

    private func sharedInit()
        translatesAutoresizingMaskIntoConstraints = false
        backgroundColor = .blue
    


当我将 UIView 放在情节提要中,并在 身份检查器 中将其类分配给 MyView 时,UIView 仍然具有默认背景颜色。为什么它的背景颜色不是故事板中的UIColor.blue?还有,请问我怎样才能做到这一点?

感谢您的帮助。

【问题讨论】:

init 用于 runtime - 而 Interface Builder 是 design-time。虽然这可能不起作用,但请考虑使用 prepareForInterfaceBuilder() 来查看 sharedInit 【参考方案1】:

从情节提要初始化此视图的初始化程序将在运行时调用,为了在编译时更新情节提要中的视图,您应该尝试包含prepareForInterfaceBuilder,它会在编译时更新情节提要 xib 文件。

我建议你在创建@IBDesignable 类时做多件事:

    @IBDesignable标签标记班级 用@IBInspectable 标记UIView 属性,然后您将能够使用StoryBoard 更改此属性的值 在该属性的willSet 中设置配置代码,该配置代码在属性获取值之前观察更改,或者在属性接收到值之后设置didSet。 在prepareForInterfaceBuilder() 中进行额外设置,它覆盖了它的超类UIView

简单易行!

您的代码应如下所示:

斯威夫特 5:

import UIKit

@IBDesignable
class myView: UIView 

  @IBInspectable var storyBoardColor : UIColor = .red          
    willSet(myVariableNameToCatch) 
      self.backgroundColor = myVariableNameToCatch
    
   

  fileprivate func sharedInit()
    translatesAutoresizingMaskIntoConstraints = false
    backgroundColor = storyBoardColor
  

  override func prepareForInterfaceBuilder() 
    super.prepareForInterfaceBuilder()
    sharedInit()
  

myView 的 storyBoardColor 初始值为 red,您可以从 storyBoard 更改它;)

【讨论】:

@thibautnoah 嗨,我在第 (3) 节中提醒了他,并告诉他如何实现 structre base。答案可以在第 (3) 节中找到,对于我想让每个人都知道它是如何工作的功能......但谢谢,也许我应该少解释一下。 @mohamadrezakoohkan 视图首先不是初始化的。因此我说你没有回答这个问题。我同意可检查部分,但您更改了类本身的结构。【参考方案2】:

一旦您使用标签@IBDesignable 制作您的视图。接下来是使用@IBInspectable 设置您的属性。

@IBDesignable
class MyView: UIView 

    @IBInspectable var myBackgroundColour: UIColor? = nil 
        willSet(v) 
            self.backgroundColor = v
        
    
   // YOUR EXISTING CODE HERE

现在,当您在 Identity Inspector 中将 MyView 设置为类名时。您将能够在 Attributes Inspector 中看到您的可检查属性。在那里您可以设置颜色,它会立即反映到您的自定义视图中。

我认为使用自定义属性设置背景颜色没有任何用处,因为 UIView 具有设置背景颜色的默认属性。

希望对你有帮助。

【讨论】:

【参考方案3】:

Swift 4.2 经过测试并且可以正常工作。这是最干净的解决方案。

在 Xcode 中确保选中 Editor -> Automatically refresh views

import UIKit

@IBDesignable
class BoxView: UIView 

    override func prepareForInterfaceBuilder() 
        super.prepareForInterfaceBuilder()
        layer.borderColor = borderColor?.cgColor
        layer.borderWidth = borderWidth
        layer.cornerRadius = cornerRadius
    

    @IBInspectable var borderColor: UIColor? 
        didSet 
            layer.borderColor = borderColor?.cgColor
            setNeedsLayout()
        
    

    @IBInspectable var borderWidth: CGFloat = 0.0 
        didSet 
            layer.borderWidth = borderWidth
            setNeedsLayout()
        
    

    @IBInspectable var cornerRadius: CGFloat = 0.0 
        didSet 
            layer.cornerRadius = cornerRadius
            setNeedsLayout()
        
    

    在上面创建 BoxView.swift 文件。 在 InterfaceBuilder 中选择一个 UIView。 在Identity Inspector 中选择Custom Class -> Class to "BoxView"。 在Attributes Inspector 中设置borderColorborderWidthborderRadius

【讨论】:

以上是关于@IBDesignable UIView 不在情节提要中调用 init的主要内容,如果未能解决你的问题,请参考以下文章

无法将自定义 IBDesignable 类链接到情节提要上的 UIButton

iOS - 无法让 @IBDesignable .xib 文件显示在情节提要或模拟器上

层的 UIView 的子层在 Storyboard 中显示为 @IBDesignable,但在模拟器中却没有

如何使用创建的自定义 IBDesignable 类从情节提要中更改按钮的角半径

Swift @IBDesignable/@IBInspectable UIView 样式

UIView 初始化覆盖导致 IBDesignable 崩溃