可重用的.xib + 可可类组件,如何在情节提要中自动调整大小和样式?

Posted

技术标签:

【中文标题】可重用的.xib + 可可类组件,如何在情节提要中自动调整大小和样式?【英文标题】:Reusable .xib + cocoa class components, how to auto size and style superview in storyboard? 【发布时间】:2018-09-02 17:05:58 【问题描述】:

我在this guide之后使用.xib和cocoa类的组合实现了可重用的按钮组件

它有效,但有一个问题。为了在我的一个主视图故事板中使用它,我必须先拖入一个普通视图(在问题标题中引用为超级视图),然后应用我的 Button 类,使其成为一个按钮。

这可行,但初始视图的高度和宽度及其白色背景仍然存在,因此我必须在使用组件时手动重写它们,这本身会导致可重用性差。

理想情况下,我想拖入一个视图,将其设置为Button 类,仅此而已,该视图应立即采用按钮的高度和宽度并具有透明背景。这样的事情可以实现吗?

为了在这个问题上阐明更多的上下文,这里是我的实现的一些有用的部分

1.作为 .xib 视图和自己的 cocoa 类制作的可重用组件

2。 Button.swift的内容

import UIKit

@IBDesignable class Button: UIView 

    @IBOutlet var contentView: UIView!
    @IBOutlet weak var label: UILabel!

  @IBInspectable var buttonLabel: String? 
    get 
      return label.text
    
    set(buttonLabel) 
      label.text = buttonLabel
    
  

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

  required init?(coder: NSCoder) 
    super.init(coder: coder)
    componentInit()
  

  private func componentInit() 
    let bundle = Bundle(for: Button.self)
    bundle.loadNibNamed("Button", owner: self, options: nil)
    addSubview(contentView)
    contentView.frame = self.bounds
    contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
  


3.示例用法(在我的一个主视图故事板中)演示如何将普通视图变成按钮,但在高度、宽度和背景颜色方面存在问题

P.S ^ 如果在上面的 gif 中很难分辨出发生了什么,我基本上将 UIView 拖到故事板中,并为其赋予 Button 的自定义类属性,这会将视图变成一个按钮。

编辑:为了更清楚,我的问题是:我可以将宽度、高度和透明颜色应用于我的 XIB 的父/超级视图吗?这里的最终目标是将视图拖到故事板上,给它一个Button的自定义类,就是这样,它应该适当调整大小并具有透明背景,而不是现在的样子(视图没有获得按钮的大小并具有白色背景)

【问题讨论】:

只是猜测:您是否尝试过实现视图的intrinsicContentSize @JamesBucanek 实际上,我没有。在阅读了有关它的文档后,这似乎是一个可行的解决方案,但是您能扩展一下吗?即这是否以某种方式进入主故事板中的父视图?我无法在尺寸工具中找到此选项。 这只是一个猜测。 intrinsicContentSizeUIView 的属性,自动布局用于调整视图大小。自动布局首先查询视图的固有大小,并且在没有冲突约束的情况下,将调整视图大小以匹配。大多数控件(按钮、标签……)和许多内容视图(图像视图……)都具有固有大小,允许它们自动调整大小以匹配其内容的大小。我没有玩过它,但我希望新的和改进的 IB 可以使用内在大小来自动调整情节提要中的视图大小;自动布局一定会。 intrinsicContentSize 确实是您的自定义视图缺少的内容,以便提供自派生尺寸,因此您可以覆盖并返回一个大小,该大小可能取决于您标签自己的 intrinsicContentSize 例如(所以它会自动增长更大的字符串 - 你明白了)。现在可以在您的自定义视图上轻松地将背景设置为.clear。话虽如此,如果您打算大量使用可设计对象,请记住 IB(至少在这个 v9.x 阶段)可能会变得非常不稳定,并且是一场噩梦...... @Alladinian 那么,我是在我的contentView 组件中设置intrinsicContentSize,还是需要将它设置在我拖到gif 中的情节提要中的视图上?那就是我需要调整大小和清除背景的那个,因此我需要以某种方式在我的设计中完成所有这些,所以我只需将它的类应用于任何视图,它就可以开箱即用。感谢您对IB 的警告,这是我刚开始时首选的做事方式 【参考方案1】:

您必须将您的子视图正确固定在 Button 以及 Main.storyboard 中。然后您的自定义视图将自动调整大小。清晰的颜色正在起作用。

import UIKit

@IBDesignable
class Button: UIView 

    @IBOutlet var contentView: UIView!
    @IBOutlet weak var label: UILabel!

    @IBInspectable
    var backColor: UIColor = .clear 
        didSet 
            backgroundColor = backColor
            contentView.backgroundColor = backColor
        
    

    override var backgroundColor: UIColor? 
        get 
            return backgroundColor
         set 

        
    

    @IBInspectable
    var buttonLabel: String? 
        get 
            return label.text
        
        set(buttonLabel) 
            label.text = buttonLabel
        
    

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

    required init?(coder: NSCoder) 
        super.init(coder: coder)
        componentInit()
    

    private func componentInit() 
        let bundle = Bundle(for: Button.self)
        bundle.loadNibNamed("Button", owner: self, options: nil)
        addSubview(contentView)
        contentView.frame = bounds
        backgroundColor = backColor
        contentView.backgroundColor = backColor
        contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        // for static height
        contentView.heightAnchor.constraint(equalToConstant: 70).isActive = true
    


为确保您的 CustomView 能够正确调整自身大小,您可以使用底部约束 >= 0。测试后重置为等于。

【讨论】:

以上是关于可重用的.xib + 可可类组件,如何在情节提要中自动调整大小和样式?的主要内容,如果未能解决你的问题,请参考以下文章

如何在情节提要场景中嵌入自定义视图 xib?

在情节提要中使用 iOS 静态库公共视图控制器?

OSX / macOS - 如何将 xib 迁移到情节提要

如何在编码中用“.xib”文件替换情节提要

如何在不使用尺寸等级和情节提要的情况下创建适用于 iPhone 4 到 iPhone 6 Plus 的 XIB?

用 XIB 替换情节提要