К сожалению, не существует плавного способа добавления 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
}
}
Вот вывод на автоматическом макете
Я намеренно показал ограничения на оба объекта, чтобы вы могли проверить, правильно ли я вас понимаю.Они оба имеют только 2 ограничения: выравнивание по верху и по центру.
UILabels
имеют свои собственные intrinsicContentSize
, поэтому при их переопределении мы можем использовать их уже заданные intrinsicContentSize
в качестве ориентира, в качестве руководства для любыхмы хотим сделать.UIViews
intrinsicContentSize
не задано, поэтому мы должны найти способ задать им конкретные размеры.Не будучи уверенным, я предполагаю, что для реализации UILabel
intrinsicContentSize
логика, скорее всего, связана с размером текста.Вы можете просто передать константы, как в приведенном выше коде, или использовать любую собственную логику для предоставления CGFloats
.
Просто моя мысль: хотя я и пришел с этим решением, я не фанат IBDesignables
.С моей точки зрения, они замедляют развитие из-за его ошибочного характера.Таким образом, если быть полностью честным, я бы предпочел: 1. поместить UIView
объекты в xibs и storyboards
, 2. изменить его класс с UIView
на пользовательский UIView
класс, 3. установить его ограничения, 4. установитьостальные свойства программно из его IBOutlet
.Это более традиционный способ, хотя:)
Надеюсь, это поможет вам!