Ширина / высота набора раскадровок для пользовательского вида в Autolayout, аналогичном UILabel - PullRequest
0 голосов
/ 27 января 2019

Ярлыки действительно удобны в iOS autolayout, потому что они не требуют constraints для определения размера, они только требуют X и Y позиции.Для статического текста это отлично.

У меня есть пользовательское представление, в котором я хотел бы указать размер по умолчанию для автоматического макета, аналогичный UILabels.Это возможно?Я знаком с IBInspectable и IBDesignable, но я не уверен, как это реализовать.Я использую autolayout в storyboards, но я думаю, что решение будет работать для storyboards + программно.

Я знаю, что могу просто установить height и width, но это представление, которое будет использоваться везде, поэтому было бы неплохо иметь динамический width / height.

Ответы [ 2 ]

0 голосов
/ 28 января 2019

К сожалению, не существует плавного способа добавления UIView без указания значений его размера, то есть его width и height.

Говоря об автоматической компоновке, у вас есть 2 варианта,вероятно, вы уже знаете об этом.1) вам следует либо установить UIView's значения размера, либо 2. вы установите размеры других объектов пользовательского интерфейса, чтобы автоматическое расположение могло понимать размер UIView.

Говоря о программном обеспечении, при создании UIView объект, если вы не предоставите кадр, то он не отображается.Хотя это может быть решением для размещения в любой точке любого размера, оно может быть не идеальным, когда вы используете XIB или раскадровки, поскольку в этих интерфейсах будет пробел, который также может запутать разработку.

То, как я думаю, включает в себя использование intrinsicContentSize и IBDesignable.Я сделал небольшое демо для этой цели, и вы можете найти этот код ниже.Я поделюсь двумя примерами, один унаследован от UILabel, а другой унаследован от UIView, так что я могу показать использование intrinsicContentSize проще.

Ниже приведен 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
    }
}

А ниже 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
    }
}

Вот вывод на автоматическом макете

Output

Я намеренно показал ограничения на оба объекта, чтобы вы могли проверить, правильно ли я вас понимаю.Они оба имеют только 2 ограничения: выравнивание по верху и по центру.

UILabels имеют свои собственные intrinsicContentSize, поэтому при их переопределении мы можем использовать их уже заданные intrinsicContentSize в качестве ориентира, в качестве руководства для любыхмы хотим сделать.UIViews intrinsicContentSize не задано, поэтому мы должны найти способ задать им конкретные размеры.Не будучи уверенным, я предполагаю, что для реализации UILabel intrinsicContentSize логика, скорее всего, связана с размером текста.Вы можете просто передать константы, как в приведенном выше коде, или использовать любую собственную логику для предоставления CGFloats.

Просто моя мысль: хотя я и пришел с этим решением, я не фанат IBDesignables.С моей точки зрения, они замедляют развитие из-за его ошибочного характера.Таким образом, если быть полностью честным, я бы предпочел: 1. поместить UIView объекты в xibs и storyboards, 2. изменить его класс с UIView на пользовательский UIView класс, 3. установить его ограничения, 4. установитьостальные свойства программно из его IBOutlet.Это более традиционный способ, хотя:)

Надеюсь, это поможет вам!

0 голосов
/ 27 января 2019

Вы можете переопределить

var intrinsicContentSize: CGSize { get }

свойство UIView и рассчитать и вернуть высоту и ширину представления на основе его содержимого.

Ref: intrinsicContentSize

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...