Используйте AutoLayout для позиционирования процентных подпредставлений внутри UIView - PullRequest
0 голосов
/ 10 апреля 2020

Я работаю с некоторыми JSON, которые дают мне серию представлений и подпредставлений для размещения внутри UIView, и я хочу использовать AutoLayout для достижения этой цели. Вот пример JSON:

"component": {
    "width": 150,
    "height": 100,
    "elements": [
        {
            "x": 0.1,
            "y": 0.1,
            "w": 0.8,
            "h": 0.8
        }   
    ]
}

. В этом примере внешний вид (вид component) запросил размер 150 на 100. соотношение сторон на основе ширины экрана, например, так:

private func fittedSize(for dimensions: Dimensions) -> CGSize {
    var width: CGFloat
    var height: CGFloat

    if dimensions.width.value > dimensions.height.value {
        let aspectRatio = dimensions.height.value / dimensions.width.value
        width = dimensions.width.value
        height = dimensions.width.value * aspectRatio
    } else {
        let aspectRatio = dimensions.width.value / dimensions.height.value
        height = dimensions.height.value
        width = dimensions.height.value * aspectRatio


    let apertureSize = CGSize(width: width, height: height)

    if apertureSize.width > apertureSize.height {
        let scale = bounds.width / apertureSize.width
        return CGSize(width: apertureSize.width * scale, height: apertureSize.height * scale)
    } else {
        let scale = bounds.height / apertureSize.height
        return CGSize(width: apertureSize.width * scale, height: apertureSize.height * scale)
    }
}

Вышеприведенная функция вычисляет максимальный размер, который может иметь вид, при сохранении соотношения сторон, заданного его размерами, например, при ширине экрана 320, это представление 100x150 будет 320x480.

Теперь мне нужно расположить подпредставления этого представления, содержащие элементы в этом компоненте. Эти значения указаны в процентах, поэтому в приведенном выше примере элемент должен располагаться на 10% ширины слева и сверху и на 80% ширины и высоты суперпредставления.

Я могу легко получить правильную ширину и высоту, используя ограничения с множителями, например:

let w = elementView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: element.position.width)
let h = elementView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: element.position.height)

Это займет 0,8 и сделает подпредставление 80% его родительской ширины и высоты. Беда в том, что я также хочу использовать множители для своей позиции (х и у). AutoLayout не поддерживает это, и это ответ, который я ищу.

Как я могу расположить и изменить размер одного UIView внутри другого, используя процентные значения, используя AutoLayout, а не прибегая к ручному позиционированию кадров ?

Примечания:

Вот пример того, как все устроено в данный момент. Красная область - это подпредставление, а бледно-голубая - это суперпредставление. Обратите внимание, что размер подпредставления правильный, 80% ширины и высоты, но он не отображает 10% пути сверху и слева, вот чего мне не хватает.

enter image description here

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

Вы можете использовать UILayoutGuide или фиктивные представления с ограничением по переднему краю суперпредставления и переднему краю вашего представления, и ограничить ширину этого вида «распорки» шириной его суперпредставления с множителем.

let l = view .leadingAnchor.constraint (equalTo: view.leadingSpacer.leadingAnchor) )

И активируйте эти ограничения

И сделайте то же самое для верхней проставки. Я использовал фиктивные представления для этой проблемы, но UILayoutGuide предлагается как более эффективное решение, поскольку оно взаимодействует только с движком AutoLayout и не участвует в рендеринге. Надеюсь, это поможет.

0 голосов
/ 10 апреля 2020

Вам нужно будет также указать ограничения сверху и слева. Что-то вроде ниже

elementView.topAnchor.constraint(equalTo: view.topAnchor, constant: height / 10),
elementView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: width / 10),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...