类似于UILabel的自动布局中的自定义视图的故事板设置宽度/高度

时间:2019-01-27 18:14:37

标签: ios swift xcode autolayout storyboard

标签在iOS autolayout中非常方便,因为它们不需要constraints即可确定大小,它们只需要X和Y位置即可。对于静态文本,这很棒。

我有一个自定义视图,我想为自动布局提供类似于UILabels的默认大小。这可能吗?我熟悉IBInspectableIBDesignable,但不确定如何实现。我正在autolayout中使用storyboards,但我想该解决方案将适用于storyboards +编程方式。

我知道我可以只设置heightwidth,但是这种视图将在所有地方使用,因此最好使用width / height动态的。

2 个答案:

答案 0 :(得分:2)

不幸的是,没有不指定其大小值即UIViewwidth的{​​{1}}的平滑方法。

说到自动布局,您有2个选择,也许您已经知道了。 1)您应该设置height的大小值,或者2.设置其他UI对象的大小,以便自动布局可以了解UIView's的大小。

从程序上讲,创建UIView对象时,如果不提供框架,则不会显示该框架。尽管这可能是一个解决方案,可以随时随地放置任何大小,但在使用xibs或情节提要时可能并不理想,因为这些界面上会有间隙,这也可能使开发混乱。

我考虑的方式包括同时使用UIViewintrinsicContentSize。为此,我进行了一些演示,您可以在下面找到此代码。我将分享两个示例,一个示例继承自IBDesignable,另一个示例继承自UILabel,这样我可以更轻松地展示UIView的用法。

下面是intrinsicContentSize个。

UIView

下面是UILabel之一。

import UIKit

@IBDesignable class UIDemoView: UIView {

    func setup() {
        layer.cornerRadius = frame.height / 5
        clipsToBounds = true
    }    

    override func awakeFromNib() {
        super.awakeFromNib()
        self.setup()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        self.setup()
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        self.setup()
    }

    override var intrinsicContentSize: CGSize {
        let newWidth = 100
        let newHeight = 100
        let newSize = CGSize(width: newWidth, height: newHeight)
        return newSize
    }
}

这是自动版式上的输出

Output

我故意显示了对两个对象的约束,因此您可以检查我是否正确理解了您的需求。它们都只有两个约束:顶部和中心对齐。

import UIKit @IBDesignable class UIDemoLabel: UILabel { func setup() { layer.cornerRadius = frame.height / 2 clipsToBounds = true textAlignment = .center } override func awakeFromNib() { super.awakeFromNib() self.setup() } override func layoutSubviews() { super.layoutSubviews() self.setup() } override func prepareForInterfaceBuilder() { super.prepareForInterfaceBuilder() self.setup() } override var intrinsicContentSize: CGSize { let superSize = super.intrinsicContentSize let newWidth = superSize.width + superSize.height let newHeight = superSize.height let newSize = CGSize(width: newWidth, height: newHeight) return newSize } } 拥有自己的UILabels,因此在覆盖它们时,我们可以使用它们已经给定的intrinsicContentSize作为参考,以作为我们想要做的事情的指南。 intrinsicContentSize UIViews未设置,因此我们必须找到一种方法来为其指定特定大小。不确定,我猜测是intrinsicContentSize UILabel的实现,逻辑很可能与文本的大小有关。您可以像上面的代码那样简单地传递常量,也可以使用任何自定义逻辑来提供intrinsicContentSize

仅是我的想法:即使我提出了这个解决方案,我也不喜欢CGFloats。从我的角度来看,由于越野车的性质,它们减慢了开发速度。因此,老实说,我宁愿1.将IBDesignables对象放在xibs和UIView上,2.将其类从storyboards更改为自定义UIView类,3 。设置其约束,4.从其UIView以编程方式设置其余属性。 tho:)

希望这对您有帮助!

答案 1 :(得分:0)

您可以覆盖

foreach(var button in this.Controls.OfType<Button>())
{
    button.Visible = false;
}

UIView的属性,并根据其内容计算并返回视图的高度和宽度。

Ref:intrinsicContentSize