简体   繁体   English

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

[英]Storyboard Set Width / Height for Custom View in Autolayout Similar to UILabel

Labels are really convenient in iOS autolayout because they don't require a constraints to determine size, they only require an X and a Y position. 标签在iOS自动autolayout中非常方便,因为它们不需要确定大小的constraints ,它们只需要X和Y位置即可。 For static text this is great. 对于静态文本,这很棒。

I have a custom view that I would like to provide a default size to auto layout similar to UILabels . 我有一个自定义视图,我想为自动布局提供类似于UILabels的默认大小。 Is this possible? 这可能吗? I am familiar with IBInspectable and IBDesignable , but I'm not sure how to implement this. 我熟悉IBInspectableIBDesignable ,但是我不确定如何实现这一点。 I am using autolayout in storyboards , but I imagine the solution would work for storyboards + programmatic. 我正在storyboards autolayout中使用自动autolayout ,但我想该解决方案将适用于storyboards autolayout +编程。

I know I can just set the height and width , but this is view that will be used everywhere so it would be nice to have the width / height dynamic. 我知道我可以只设置heightwidth ,但这是将在所有地方使用的视图,因此可以动态调整width / height

Unfortunately, there is no smooth way to add UIView without specifying its size values, ie its width and height . 不幸的是,没有指定UIView的大小值(即widthheight平滑方法。

Speaking of auto-layout, there are 2 options you got, probably you are already aware of too. 说到自动布局,您有2个选择,也许您已经知道了。 1) you should either set UIView's size values, or 2. you set other UI Objects' sizes so that auto-layout can understand the size of UIView . 1)您应该设置UIView's大小值,或者2.设置其他UI对象的大小,以便自动布局可以了解UIView的大小。

Speaking of programmatically, upon creating UIView object, if you do not provide frame, then it is not shown. 说到编程,创建UIView对象时,如果不提供框架,则不会显示。 Although this might be a solution to put at any point with any size, it might be not ideal when you are using xibs or storyboards, since there would be a gap on those interfaces which may also confuse development. 尽管这可能是放置在任何大小的任何点上的解决方案,但在使用xib或情节提要时可能并不理想,因为这些接口上会有间隙,这也可能使开发困惑。

The way I am thinking of includes using both intrinsicContentSize and IBDesignable . 我正在考虑的方法包括同时使用intrinsicContentSizeIBDesignable I made a little demo for this purpose and you can find this code below. 为此,我进行了一些演示,您可以在下面找到此代码。 I will share 2 examples, one is inherited from UILabel and the other is inherited from UIView , so that I can show usage of intrinsicContentSize easier. 我将分享2个示例,一个示例继承自UILabel ,另一个示例继承自UIView ,以便我可以更轻松地显示intrinsicContentSize用法。

Below is the UIView one. 下面是UIView之一。

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
    }
}

And below is the UILabel one. 下面是UILabel之一。

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
    }
}

Here is the output on auto-layout 这是自动布局的输出

输出量

I intentionally showed the constraints on both object, so you can check if I understand you correctly. 我故意显示了对这两个对象的约束,因此您可以检查我是否正确理解您的需求。 They both have only 2 constraints: top and center alignment. 它们都只有两个约束:顶部和中心对齐。

UILabels have theirs own intrinsicContentSize , so when overriding them we might use their already given intrinsicContentSize as a reference, as a guidance to whatever we want to do. UILabels具有自己的intrinsicContentSize ,因此在覆盖它们时,我们可以使用它们已经给定的intrinsicContentSize作为参考,作为我们想要做的事情的指南。 UIViews intrinsicContentSize is not set, therefore we must find a way to give them specific sizes. 没有设置UIViews intrinsicContentSize ,因此我们必须找到一种方法来为其指定特定大小。 With not being sure, I am guessing for UILabel intrinsicContentSize implementation, logic is most probably related with the size of the text. 不确定的是,我猜测是UILabel intrinsicContentSize实现的,逻辑很可能与文本的大小有关。 You can simply pass constants like above code, or you can use any custom logic to provide CGFloats . 您可以像上面的代码那样简单地传递常量,也可以使用任何自定义逻辑来提供CGFloats

Just a thought of mine: Even though I came with this solution, I am not fan of IBDesignables . 只是我的想法:即使我提供了此解决方案,我也不是IBDesignables From my perspective, they slow down the development because of its buggy nature. 从我的角度来看,由于越野车的性质,它们减慢了开发速度。 Thus, to be fully honest, I'd rather 1. putting UIView objects on xibs and storyboards , 2. changing its class from UIView to custom UIView class, 3. settings its constraints, 4. setting remaining properties programmatically from its IBOutlet . 因此,说实话,我宁愿1.将UIView对象放在xibs和storyboards提要storyboards ,2.将其类从UIView更改为自定义UIView类,3.设置其约束,4.从其IBOutlet编程设置其余属性。 This is more of a traditional way, tho :) 这更像是一种传统方式,

Hope this helps you! 希望这对您有所帮助!

You can override 您可以覆盖

var intrinsicContentSize: CGSize { get }

property of UIView and calculate and return the height and width of the view based on its contents. 属性,并根据其内容计算并返回视图的高度和宽度。

Ref : intrinsicContentSize 参考: intrinsicContentSize

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM