Чи можу я відключити авторозкладку для певного підвідного режиму під час виконання?


104

У мене є погляд, який повинен маніпулювати кадром програмно - це вид документа, який перетворюється на його вміст, який потім прокручується та збільшується навколо огляду, маніпулюючи походженням кадру. Autolayout бореться з цим під час виконання.

Вимкнення автоматичного вимикання здається дещо суворим, оскільки його можна обґрунтовано використовувати для обробки макета для інших представлень. Здається, те, що я, можливо, хотів би бути якимось "нульовим обмеженням".

Відповіді:


168

У мене була така ж проблема. Але я це вирішив.
Так, ви можете вимкнути автоматичний макет під час виконання для певного UIView, замість того, щоб вимкнути його для цілого Xib або дошки, що встановлено за замовчуванням у Xcode 4.3 та пізніших версіях.

Встановіть translatesAutoresizingMaskIntoConstraintsна YES, перш ніж встановити рамку вашого підвиди:

self.exampleView.translatesAutoresizingMaskIntoConstraints = YES;
self.exampleView.frame = CGRectMake(20, 20, 50, 50);

2
Це виглядає як надмірний рівень для деяких складніших випадків з великою кількістю переглядів. Для чогось такого простого, це добре.
еш

@MuhammadAamirALi видалити підпрез, а потім додати його назад, може знизити продуктивність. Чи можемо ми архівувати краще рішення?
Nhat Dinh

2
@DinhNhat я уточнив відповідь. Видалення та повторне додавання підперегляду не потрібно.
Леандрос

5
Він показує мені попередження: "Неможливо одночасно задовольнити обмеження".
NSPratik

1
Ти врятував мій день ... перекладаєАвторезингМаскаІнтоКонсанти ... хто вигадує такі властивості, як ця тремтяча голова
Tintenklecks

50

У мене була подібна проблема, коли Autolayout переосмислив деякі мої настройки кадру під час виконання (у мене був динамічний вигляд, який у деяких випадках натискав на новий контролер перегляду ... натискання та натискання Назад скине початковий вигляд).

Я вирішив це, помістивши свій маніпуляційний код у viewDidLayoutSubviewsмій контролер перегляду. Це, здається, викликається після того, як викликається будь-яке обмеження, але перед тим, як viewDidAppear, тому користувач не мудріший.


1
Не працює для self.navigationItem.titleView. Досі не поважає зміну кадру.
Генрік Ерландссон

1
Якщо ви намагаєтеся вимкнути рамку перегляду заголовка, я б помістив його всередину перегляду контейнера і додав би перегляд контейнера як спеціальний вигляд навігаційногоItem.
jmstone617

2
Це працювало і для мене. Я витратив 2 години: 22 м, вдарившись головою об прихильну стіну, перш ніж розкрити цю проблему.
TMc

Спасибі, чоловіче. Я вже другий день боюся з цим питанням, і зараз це працює!
апостолов

28

Можливо, саме встановлення translatesAutoresizingMaskIntoConstraintsна YES(а не додавання додаткових обмежень, що впливають на цей вид), дозволить вам встановити кадр, не борочившись із системою автоматичного розміщення.


17

В iOS 8 ви можете встановити, що NSLayoutConstraint буде активним чи ні. Тож якщо я використовую конструктор інтерфейсів, я додаю всі свої обмеження до OutletCollection, а потім активую або відключаю, використовуючи:

NSLayoutConstraint.deactivateConstraints(self.landscapeConstraintsPad)
NSLayoutConstraint.activateConstraints(self.portraitConstraintsPad)

Конкретний додаток, який я тут використовую, має різні обмеження в портретному та пейзажному режимі, і я активую / вимикаю на основі обертання пристрою. Це означає, що я можу створити деякі складні зміни в компонуванні всіх в конструкторі інтерфейсів для обох орієнтацій, і все ж використовувати автоматичну компоновку без багатослівного коду автоматичного макета.

Або ви можете активувати / деактивувати за допомогою RemoveConstraints та addConstraints.


Вибачте за викрадення такого старого питання, але чи можу я запитати, як вам вдалося в першу чергу додати обмеження для макета для різних макетів? Я, здається, не знаходжу опцію всередині конструктора інтерфейсів, щоб увімкнути / вимкнути обмеження. Або ви просто додавали обмеження для обох макетів і просто ігнорували розробник інтерфейсу, скаржившись на недійсні (переосмислювальні) обмеження?
Мальте

Ну, ви могли це зробити за допомогою класів розмірів: developer.apple.com/library/ios/recipes/… , але я не міг цього зробити, тому що я підтримував iOS 7, і класи розмірів не повністю підтримують iOS 7 Я зробив це, знизивши пріоритет конфліктного обмеження. Не ідеально, але це запобігає попередженню. Я думаю, що так я і зробив це все одно ....
bandejapaisa

9

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

UIView + DisableAutolayoutTem privremeno.h

#import <UIKit/UIKit.h>

@interface UIView (DisableAutolayoutTemporarily)

// the view as a parameter is a convenience so we don't have to always
// guard against strong-reference cycles
- (void)resizeWithBlock:(void (^)(UIView *view))block;

@end

UIView + DisableAutolayoutTem privremeno.m

#import "UIView+DisableAutoResizeTemporarily.h"
@implementation UIView (DisableAutoResizeTemporarily)

- (void)resizeWithBlock:(void (^)(UIView * view))block
{
    UIView *superview = self.superview;
    [self removeFromSuperview];
    [self setTranslatesAutoresizingMaskIntoConstraints:YES];
    __weak UIView *weakSelf = self;
    block(weakSelf);
    [superview addSubview:self];
}

@end

Я використовую це так:

[cell.argumentLabel resizeWithBlock:^(UIView *view) {
    [view setFrame:frame];
}];

Сподіваюся, це допомагає.


Блискуче! Я використав модифіковану версію вашого коду, щоб написати просту функцію "hidControl" для будь-якого UIView. Він в основному встановлює висоту UIView до 0, але, головне, він використовує ваш код, щоб змусити AutoLayout обробляти його належним чином (на відміну від використання "someView.hidden = TRUE"). Таким чином, елементи керування, які опинилися нижче прихованого елемента керування, і з ним пов'язані вертикальні відстані, тепер зміщуватимуться вгору на екрані, щоб заповнити проміжок, де раніше з'являвся прихований вигляд.
Майк Гледхілл

6

Ви можете встановити translatesAutoresizingMaskIntoConstraintsтип Boolean, значення «Так» у визначених користувачем атрибутах виконання UIView, який ви хочете, на xib / раскадровці.


2
  • Відкритий проект у 4.5
  • Виберіть раскадровку
  • Відкрийте інспектор файлів
  • У розділі Документ для розробника інтерфейсу зніміть прапорець "Використовувати автоматичний вигляд"

Ви можете розділити на кілька дощок, якщо ви хочете використовувати авторозкладку для деяких представлень.


10
Це вимикає авторозкладку для всієї рекламної панелі / підказки. Що я шукав - це спосіб (в ідеалі програмно) мати певні підзагляди в межах раскадровки / ручки, не використовувати авторозкладку, залишаючи решту робити все, що вказано в дошці / ручці.
страшна

Ви можете використовувати декілька дощок із розгортанням та просто викликати ті, з / без автоматичного розкладу за необхідності: // Ініціалізуйте контролер перегляду дощок та деталей для відображення UIStoryboard * sb = [Роздільна панель UIStoryboardWithName: @ Пакет "Storyboard": [NSBundle mainBundle]]; DetailViewController * dvController = [sb instantiateViewControllerWithIdentifier: entry.viewName];
Майк Боббітт

1

Для мене це працювало над створенням програмного перегляду програмного забезпечення, в моєму випадку автоматичний макет змішувався з тим, що мені потрібно обертатися навколо його центру, але як тільки я створив цей вид програмно, він працював.


1

На мій погляд, у мене були етикетка та текст. Етикетка мала жест пан. Під час перетягування мітка добре переміщується. Але коли я використовую клавіатуру текстового поля, мітка скидає своє положення до початкового місця, визначеного в автоматичному макеті. Проблема була вирішена, коли я швидко додав наступне для ярлика. Я додав це в viewWillAppear, але його можна додати майже в будь-якому місці, де ви маєте доступ до цільового поля.

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true

0

Це сталося зі мною в проекті без раскадров або файлів xib. Всі 100% код. Я мав рекламний банер внизу і хотів, щоб межі перегляду зупинялися на рекламному банері. Перегляд автоматично змінить розмір зображення після завантаження. Я намагався кожну резолюцію на цій сторінці, але жодна з них не спрацювала.

Я в кінцевому підсумку просто створив подання з укороченою висотою і помістив його в основний вигляд контролера. Потім весь мій вміст зайшов у підпогляд. Це вирішило проблему дуже легко, не роблячи нічого, що здавалося, що це йде проти зерна.

Я думаю, якщо ви хочете переглянути, який не є нормальним розміром, який заповнює вікно, то для цього слід використовувати підгляд.


0

Я зіткнувся з подібним сценарієм, коли я приєднався до проекту, який був ініційований з автоматичним компонуванням, але мені потрібно було внести динамічні корективи в декілька переглядів. Ось що для мене спрацювало:

  1. НЕ мати перегляди або компоненти, викладені в конструкторі інтерфейсів.

  2. Додайте свої погляди суто програмно, починаючи з alloc / init і відповідним чином встановлюючи їх кадри.

  3. Зроблено.


0

Замість того, щоб вимкнути автоматичний розклад, я б просто обчислив нове обмеження за допомогою кадру, який ви замінюєте. Мені здається, це відповідний спосіб. Якщо ви коригуєте компоненти, що спираються на обмеження, відрегулюйте їх відповідно.

Наприклад, якщо у вас є вертикальне обмеження 0 між двома видами перегляду (myView та otherView), і у вас є жест панорамування або щось, що регулює висоту myView, ви можете перерахувати обмеження на коригувані значення.

self.verticalConstraint.constant = newMyViewYOriginValue - (self.otherView.frame.origin.y + self.otherView.frame.size.height);
[self.myView needsUpdateConstraints];

0

Для тих, хто використовує автоматичний макет, будь ласка, ознайомтеся з моїм рішенням тут . Ви повинні створювати @IBOutletобмеження, які хочете скорегувати, а потім змінити їх константи.


-16

якщо це файл Xib:

  1. виберіть файл .xib
  2. виберіть "Власник файлу"
  3. показати утиліти
  4. натисніть на "Інспектор файлів"
  5. У розділі "Документ для побудови інтерфейсу" відключити: "Використовувати автоматичний розклад"

1
Ні, це вимикає авторозкладку на весь xib. Що я шукав - це спосіб вийняти лише один конкретний підвід із системи автоматичного вимикання.
жахливий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.