it-roy-ru.com

В autolayout, как я могу иметь вид, занимающий половину экрана, независимо от ориентации?

В портретном режиме у меня есть табличное представление с левой стороны и веб-представление с правой стороны. Они оба занимают половину экрана. У меня включена функция автоматического размещения.

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

Почему это происходит? Как сделать так, чтобы изображения занимали только половину экрана относительно их ширины, независимо от ориентации экрана?

22
NYC Tech Engineer

Первая половина ответа касается случая, в котором мы хотим равномерно разделить представление между представлением A (синим) и представлением B (красным). Вторая половина будет посвящена случаю, когда мы хотим, чтобы представление A занимало половину экрана, но представление B не существует.

Шаг 1:

enter image description here

Установите ограничения авторазметки синего цвета, как показано на рисунке. Сверху, слева, снизу от 0 до суперпредставления. Справа от 0 до красного взгляда.

Шаг 2:

enter image description here

Установите те же, но зеркальные ограничения для красного представления.

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

enter image description here

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

Шаг 3:

enter image description here

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

Чтобы добавить эти ограничения в код с использованием VFL, нам понадобятся следующие ограничения:

@"H:|[blueView(==redView)][redView]|"
@"V:|[blueView]|"
@"V:|[redView]|"

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

Шаг 1:

enter image description here

Это похоже на шаг 1, описанный выше, за исключением того, что мы не добавляем ограничение правой стороны (это, очевидно, изменится, если мы хотим, чтобы наше представление занимало другую половину).

Шаг 2:

enter image description here

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

enter image description here

На данный момент у нас есть предупреждение автоматического макета. Авто макет хочет, чтобы наш кадр соответствовал ширине его родителя. Нажав на предупреждение и выбрав «Обновить ограничения», вы получите жестко запрограммированное значение. Мы не хотим этого.

Шаг 3:

enter image description here

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

Нажмите «Изменить» рядом с ограничением «Равная ширина в:». Нам нужно изменить значение множителя.

enter image description here

Нам нужно изменить значение множителя на 2.

Теперь ограничение изменяется на «Пропорциональная ширина:», и все наши предупреждения и ошибки автоматического размещения исчезают. Теперь наш взгляд всегда будет занимать ровно половину супер просмотра.

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

@"H:|[blueView]"
@"V:|[blueView]|"

Но пропорциональное ограничение ширины не может быть добавлено с VFL. Мы должны добавить это как так:

NSLayoutConstraint *constraint =
    [NSLayoutConstraint constraintWithItem:blueView
                                 attribute:NSLayoutAttributeWidth 
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superView
                                 attribute:NSLayoutAttributeWidth
                                multiplier:2.0
                                  constant:0.0]; 
71
nhgrif

Создайте UIView в XIB или Storyboard

  1. Установить верхнее и левое ограничения
  2. Установить ограничение по высоте
  3. Установите ограничение ширины равным ширине суперпредставления * Важно
  4. Отредактируйте ширину ограничения, преобразовав его в десятичную 

 enter image description here

  1. Установите десятичную ширину, которую вы хотите (в моем случае 0,5 или половина)

 Result

5
Michael

Свяжите их оба с краями суперпредставления (табличное представление к переднему краю, веб-представление к заднему краю) и установите для них ограничение одинаковой ширины.

4
sha

Система ограничений не может читать ваши мысли. Вы должны сказать, что вы хотите. Половина - это половина. Если хочешь наполовину, скажи наполовину. Чтобы сделать представление вдвое меньше ширины его суперпредставления, присвойте ему ограничение ширины, которое имеет множитель .5 по отношению к ширине его суперпредставления.

1
matt

Программно в Swift 4:

import UIKit

class ViewController: UIViewController {

    let halfScreenViewLeft: UIView = {
        let view = UIView()
        view.backgroundColor = .blue
        return view
    }()

    let halfScreenViewRight: UIView = {
        let view = UIView()
        view.backgroundColor = .red
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(halfScreenViewLeft)
        view.addSubview(halfScreenViewRight)

        //Enable Autolayout
        halfScreenViewLeft.translatesAutoresizingMaskIntoConstraints = false

        //Place the top side of the view to the top of the screen
        halfScreenViewLeft.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true

        //Place the left side of the view to the left of the screen.
        halfScreenViewLeft.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true

        //Set the width of the view. The multiplier indicates that it should be half of the screen.
        halfScreenViewLeft.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5).isActive = true

        //Set the same height as the view´s height
        halfScreenViewLeft.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true

        //We do the same for the right view

        //Enable Autolayout
        halfScreenViewRight.translatesAutoresizingMaskIntoConstraints = false

        //Place the top side of the view to the top of the screen
        halfScreenViewRight.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true

        //The left position of the right view depends on the position of the right side of the left view

        halfScreenViewRight.leadingAnchor.constraint(equalTo: halfScreenViewLeft.trailingAnchor).isActive = true

        //Place the right side of the view to the right of the screen.
        halfScreenViewRight.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true

        //Set the same height as the view´s height
        halfScreenViewRight.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true


    }

}
0
Fernando Cardenas