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

Я хочу добавить дополнение ко всем моим кнопкам, поэтому я подclassифицировал UIButton, и среди других изменений я хотел добавить фиксированное дополнение с помощью метода setFrame. Все работало, за исключением setFrame. Я проверил, и я узнал, что если я сниму «использование AutoLayout» в этом представлении, я могу использовать setFrame, и он работает. Есть ли способ обойти это? Я действительно хочу использовать autolayout, потому что это помогает сделать приложение приятным на устройствах iphone 5 и более ранних версий. Но я также хотел бы использовать setFrame в моем подclassе, чтобы облегчить мою жизнь.

Подводя итоги, я задаю вопрос: могу ли я использовать автозапуск, а также программно настроить рамку UIView?

Да, это можно сделать.

Если вы установите translatesAutoresizingMaskIntoConstraints = YES setFrame: translatesAutoresizingMaskIntoConstraints = YES , то вызовы setFrame: автоматически переводится во время выполнения в ограничения компоновки на основе текущей autoresizingMask . Это позволяет смешивать фрейм-макет с компоновкой на основе ограничений.

Например, вы можете использовать Auto Layout для определения макета всех setFrame: представления, но по-прежнему вызывайте setFrame: чтобы установить размер и положение самого представления. С вашей точки зрения, вы делаете макет с сочетанием автоматического макета и прямой обработки кадров. Но система фактически использует ограничения для обработки всего.

Однако есть одно большое предостережение об использовании translatesAutoresizingMaskIntoConstraints .

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

Например, предположим, что уже существуют ограничения, определяющие размер и положение вашего представления, а затем вы также устанавливаете translatesAutoresizingMaskIntoConstraints = YES и называете setFrame: Вызов setFrame: создаст новые ограничения для представления, которые, вероятно, будут конфликтовать с уже существующими ограничениями.

(На самом деле эта ошибка происходит NSAutoresizingMaskLayoutConstraint вы когда-либо видели сообщение журнала, NSAutoresizingMaskLayoutConstraint конфликтующие ограничения, и одним из этих ограничений является NSAutoresizingMaskLayoutConstraint , то то, что вы видите, является конфликтом с автоматическим ограничением. Это простая ошибка, потому что translatesAutoresizingMaskIntoConstraints = YES является значением по умолчанию, поэтому, если вы настраиваете ограничения в коде, вам нужно помнить о том, чтобы отключить его, если вы не хотите, чтобы эти автоматические ограничения.)

Наоборот, предположим, что уже существуют ограничения, которые определяют размер и положение вашего представления, но затем вы устанавливаете translatesAutoresizingMaskIntoConstraints = NO прежде чем вы setFrame: В этом случае ваши setFrame: не будут создавать новые ограничения, поэтому конфликт между отдельными ограничениями не будет . Однако в этом случае по-прежнему существует «конфликт» между ограничениями и установленным значением фрейма . В следующий раз, когда вызывается автоматический макет, он увидит уже существующие ограничения в представлении, вычислит требуемое значение фрейма и задает фрейм самому требуемому значению, сбрасывая значение, которое вы устанавливаете вручную.

Для получения дополнительной информации ознакомьтесь с разделом «Принятие автоматической компоновки» в Руководстве по автоматическому компоновке cocoa в Apple.

То, что оказалось самым легким для меня, заключалось в том, чтобы удалить представление, которое я хотел переместить / resize из своего супервизора, установить его frame , а затем добавить его обратно. Например, возьмите пользовательский UILabel в подclassе UITableViewCell :

 [cell.myLabel removeFromSuperview]; cell.myLabel.frame = someFrameIGenerated; [cell.contentView addSubview:cell.myLabel]; 

Что-то, что сработало для меня, просто добавило IBOutlet для моих ограничений к controllerу представления, а затем изменило свойство constant на выходе.

Например, чтобы изменить х-начало представления, установите выход из главного ограничения этого вида на ваш controller. Другими словами, создайте выход @IBOutlet var labelXOrigin: NSLayoutConstraint! , Затем, когда вы хотите настроить положение x, просто сделайте что-то вроде

 self.labelXOrigin.constant = 20.0 // Or whatever origin you want to set. 

наилучшим способом установки frameworks подзадача является метод viewWillLayoutSubviews в проектах автоопределения.

set property translationAutoresizingMaskIntoConstraints = true, это будет работать после того, как будет отображаться представление или кнопка на кнопке, чтобы установить, сразу после просмотра.

Если ваше приложение не поддерживает несколько ориентации устройств.

В viewDidLoad установлен кадр вида, который вы хотите resize

 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [aView setFrame:CGRectMake(15, 15, 100, 100)]; } 

Затем в viewDidLayoutSubviews :

 -(void)viewDidLayoutSubviews { [self.view setTranslatesAutoresizingMaskIntoConstraints:NO]; } 

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

Давайте будем гением компьютера.