Могу ли я отключить автозапуск для определенного подвью во время выполнения?

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

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

Ответ 1

У меня была та же проблема. Но я решил это.

Да, вы можете отключить автоматическую компоновку во время выполнения для определенного UIView, вместо того чтобы отключить ее для всей xib или раскадровки, которая установлена ​​по умолчанию в Xcode 4.3 и более поздних версиях.

Установите translatesAutoresizingMaskIntoConstraints в YES, прежде чем устанавливать кадр вашего подвью:

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

Ответ 2

У меня была аналогичная проблема, когда Autolayout переопределял некоторые параметры моего фрейма во время выполнения (у меня был динамический вид, который в некоторых случаях подтолкнул новый контроллер представления... нажав, а затем нажав Back, reset начальный вид).

Я обошел это, поставив свой код манипуляции в viewDidLayoutSubviews моего View Controller. Кажется, это вызвано после того, как вызвано любое ограничение mojo, но перед viewDidAppear, поэтому пользователь не является более мудрым.

Ответ 3

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

Ответ 4

В iOS 8 вы можете установить NSLayoutConstraint как активный или нет. Поэтому, если я использую конструктор интерфейса, я добавляю все мои ограничения в OutletCollection, а затем активирую или деактивирую, используя:

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

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

Или вы можете активировать/деактивировать с помощью removeConstraints и addConstraints.

Ответ 5

Я не знаю, поможет ли это кому-либо еще, но я написал категорию, чтобы сделать это удобным, потому что я очень много делаю.

UIView + DisableAutolayoutTemporarily.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 + DisableAutolayoutTemporarily.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];
}];

Надеюсь, что это поможет.

Ответ 6

Вы можете установить тип translatesAutoresizingMaskIntoConstraints Boolean, значение Да в пользовательских атрибутах времени выполнения UIView, которые вы хотите в xib/раскадровке.

Ответ 7

  • Открыть проект в 4.5
  • Выберите раскадровку
  • Откройте инспектор файлов
  • В документе Interface Builder снимите флажок "Использовать автоспуск"

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

Ответ 8

Для меня это работало, чтобы создать subview программно, в моем случае автоматический макет возился с представлением, которое мне нужно было вращать вокруг его центра, но как только я создал это представление программно, он сработал.

Ответ 9

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

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

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

Ответ 10

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

  • НЕ имеют представления или компоненты, размещенные в построителе интерфейса.

  • Добавьте свои представления чисто программно, начиная с alloc/init и соответствующим образом настроив их фреймы.

  • Готово.

Ответ 11

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

Например, если у вас есть вертикальное ограничение 0 между двумя представлениями (myView и otherView), и у вас есть жест панорамы или что-то, что регулирует высоту myView, тогда вы можете пересчитать ограничение с установленными значениями.

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

Ответ 12

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

Ответ 13

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

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true

Ответ 14

если это xib файл:

  • выберите файл .xib
  • выберите "Владелец файла"
  • показать утилиты
  • нажмите "Инспектор файлов"
  • В разделе "Document Builder Document" отключить: "Использовать автозапуск"