可重用的.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 实际上,我没有。在阅读了有关它的文档后,这似乎是一个可行的解决方案,但是您能扩展一下吗?即这是否以某种方式进入主故事板中的父视图?我无法在尺寸工具中找到此选项。
这只是一个猜测。 intrinsicContentSize
是 UIView
的属性,自动布局用于调整视图大小。自动布局首先查询视图的固有大小,并且在没有冲突约束的情况下,将调整视图大小以匹配。大多数控件(按钮、标签……)和许多内容视图(图像视图……)都具有固有大小,允许它们自动调整大小以匹配其内容的大小。我没有玩过它,但我希望新的和改进的 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 + 可可类组件,如何在情节提要中自动调整大小和样式?的主要内容,如果未能解决你的问题,请参考以下文章