iOS" UITemporaryLayoutHeight " ограничение

Я использую systemLayoutSizeFittingSize чтобы получить наименьший размер для подкласса пользовательского представления, который удовлетворяет его внутренним ограничениям.

let someView = SomeView()        
someView.setNeedsUpdateConstraints()
someView.setNeedsLayout()
someView.layoutIfNeeded()

let viewSize = someView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

println(viewSize) // PRINTS (0.0, 96.0) WHICH IS RIGHT!

Я получаю правильное значение, но я также получить Unable to simultaneously satisfy constraints предупреждение:

"<NSLayoutConstraint:0x7ff16b753190 '_UITemporaryLayoutHeight' V:[ProjectName.SomeView:0x7ff16b772210(0)]>",
"<NSLayoutConstraint:0x7ff16b75de50 UIImageView:0x7ff16b76eff0.top == ProjectName.SomeView:0x7ff16b772210.topMargin>",
"<NSLayoutConstraint:0x7ff16b7653f0 UIImageView:0x7ff16b76eff0.bottom <= ProjectName.SomeView:0x7ff16b772210.bottomMargin>"

ниже SomeView подкласс UIView.

он просто содержит 80x80 imageView, прикрепленный к верхнему, левому и нижнему полям. (Я использую PureLayout для записи ограничений).

теперь, очевидно, этот вид будет иметь фиксированный высота 96 (80 + 8x2 для полей), но теоретически она может растянуться, если ее подвиды изменят размер.

какие идеи? Поиск google для UITemporaryLayoutHeight (или ширина) дает 0 результатов...

class SomeView: UIView {

    let imageView = UIImageView()

    var constraintsSet = false

    override init(frame: CGRect) {

        super.init(frame: frame)

        backgroundColor = UIColor.lightGrayColor()

        imageView.backgroundColor = UIColor.darkGrayColor()
        addSubview(imageView)
    }

    override func updateConstraints() {

        if(!constraintsSet) {

            imageView.autoPinEdgeToSuperviewMargin(.Top)
            imageView.autoPinEdgeToSuperviewMargin(.Left)
            imageView.autoPinEdgeToSuperviewMargin(.Bottom, relation: NSLayoutRelation.GreaterThanOrEqual)
            imageView.autoSetDimension(.Width, toSize: 80.0)
            imageView.autoSetDimension(.Height, toSize: 80.0)

            constraintsSet = true
        }
        super.updateConstraints()
    }
}

4 ответов


Это:

Он просто содержит 80x80 imageView, прикрепленный к верхнему, левому и нижнему полям

и

NSLayoutConstraint: 0x7ff16b753190 '_UITemporaryLayoutHeight' V: [Имяпроекта.SomeView:0x7ff16b772210(0)]

является источником проблемы. UIKit находится в какой-то момент в процессе загрузки/компоновки/отображения, используя высоту 0. Поскольку у вас есть ограничения как сверху, так и снизу и imageview имеет свой внутренний размер контента, вы говорите ему, чтобы поместить изображение в нулевое вертикальное пространство.

обычный способ решить эту проблему-установить приоритет верхнего или нижнего ограничения на что-либо меньше 1000.


я заметил, что это происходит со мной, если я буду называть layoutIfNeeded на вид, прежде чем его родитель был выложен. Я бы поспорил, если бы вы удалили someView.layoutIfNeeded() вы больше не увидите эту ошибку. Вы, вероятно, также можете избавиться от someView.setNeedsLayout() и заменить someView.updateConstraintsIfNeeded(). systemLayoutSizeFittingSize не должно требовать, чтобы представления были фактически выложены, ему просто нужны ограничения для правильной настройки.


у меня это предупреждение, когда вид не имеет superview и layoutIfNeeded называется. Моим решением было позвонить layoutIfNeeded после добавления представления на superview. Надеюсь, это поможет:

- (void)didMoveToSuperview {
    [super didMoveToSuperview];
    [self layoutIfNeeded];
}

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

кроме того, вам нужно установить setTranslatesAutoresizingMaskIntoConstraints(false) до imageView

попробуйте добавить ограничения при добавлении изображения в качестве подпанели.

что-то вроде этого должно работать:

class SomeView: UIView {

    let imageView = UIImageView()

    var constraintsSet = false

    override init(frame: CGRect) {

        super.init(frame: frame)

        backgroundColor = UIColor.lightGrayColor()

        imageView.backgroundColor = UIColor.darkGrayColor()
        addSubview(imageView)

        // Don't forget this
        imageView.setTranslatesAutoresizingMaskIntoConstraints(false)

        imageView.autoPinEdgeToSuperviewMargin(.Top)
        imageView.autoPinEdgeToSuperviewMargin(.Left)
        imageView.autoPinEdgeToSuperviewMargin(.Bottom, relation: NSLayoutRelation.GreaterThanOrEqual)
        imageView.autoSetDimension(.Width, toSize: 80.0)
        imageView.autoSetDimension(.Height, toSize: 80.0)
    }
}

надеюсь, это сработает. Дайте мне знать, если вам нужна помощь!