Как установить пользовательскую ширину UIView автоматически на основе его содержимого? - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть простой пользовательский UIView (вид с белым фоном на скриншоте), использующий xib и пользовательский класс, полученный из UIView.

Custom view

Внутри у меня есть UILabel и кнопка на одной строке и все.

Размер кнопки фиксирован,Ширина ярлыка должна быть отрегулирована по его содержимому.

То, что я хотел бы, это: - подогнать размер ярлыка к его содержимому - установить положение кнопки всегда сразу после ярлыка - подогнать пользовательский

Correct Cutsom view

Как мне это сделать?

Добавить содержимое:

class Keyword: UIView {

@IBOutlet weak var label: UILabel!
@IBOutlet var contentView: UIView!

override init(frame: CGRect) {
    super .init(frame: frame)
    commonInit()
}

required init?(coder aDecoder: NSCoder) {
    super .init(coder: aDecoder)
    commonInit()
}

fileprivate func commonInit() {
    Bundle.main.loadNibNamed("Keyword", owner: self, options: nil)
    addSubview(contentView)
    contentView.frame = self.bounds
}

override var intrinsicContentSize: CGSize {
    let height = CGFloat(21)
    return CGSize(width: UIViewNoIntrinsicMetric, height: height)
}

/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
    // Drawing code
}
*/

}

Ограничения UILabel:

UILabel contraints

Ограничения Tick UIButton:

enter image description here

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Благодаря @matt я нашел решение.

В моем коде было только 2 ошибки.

  1. В моем пользовательском представлении отсутствовал следующий код строки translatesAutoresizingMaskIntoConstraints = false, поэтому intrinsicContentSize никогда не вызывался.
  2. Как подсказывает @matt, внутри intrinsicContentSize мне нужно предоставить значение на основе собственной ширины метки и кнопки для параметров ширины вместо UIViewNoIntrinsicMetric

Теперь правильный код:

class Keyword: UIView {

@IBOutlet weak var label: UILabel!
@IBOutlet weak var btn: UIButton!
@IBOutlet var contentView: UIView!

override init(frame: CGRect) {
    super .init(frame: frame)
    commonInit()
}

required init?(coder aDecoder: NSCoder) {
    super .init(coder: aDecoder)
    commonInit()
}

fileprivate func commonInit() {
    translatesAutoresizingMaskIntoConstraints = false
    Bundle.main.loadNibNamed("Keyword", owner: self, options: nil)
    addSubview(contentView)
    contentView.frame = self.bounds
}

override var intrinsicContentSize: CGSize {
    let height = btn.frame.size.height
    let width =  btn.frame.origin.x + btn.frame.size.width
    return CGSize(width: width, height: height)
}


// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
    // Drawing code
}

}
0 голосов
/ 24 сентября 2018

Следующее расширение может использоваться для вычисления высоты и ширины метки.

extension String {

//Calculate height and width for label with string
func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
    let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
    let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: font], context: nil)

    return ceil(boundingBox.height)
}

func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat {
    let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
    let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: font], context: nil)

    return ceil(boundingBox.width)
}

}

В вашем случае, поскольку размер кнопки фиксирован, вы можете рассчитать ширину метки, используя вышеуказанное расширение иможет использоваться для установки ограничения ширины всего представления.Если ваша метка имеет ведущее ограничение 8 и конечное ограничение 8 для кнопки, а кнопка имеет конечное ограничение 8 для представления контейнера, тогда вы можете рассчитать требуемую ширину для своего представления как:

viewWidthConstraint.constant = 8+<width of string from the above extension>+8+<width of button>+8

Здесь единственным изменяющимся параметром будет ширина метки.

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