Могу ли я использовать setFrame и autolayout в одном представлении?
Я хочу добавить отступы ко всем моим кнопкам, поэтому я подклассифицировал UIButton, и среди других изменений я хотел добавить фиксированный отступ с помощью метода setFrame. Все работало, кроме setFrame. Я проверил все вокруг и обнаружил, что если я сниму флажок "использование AutoLayout" в этом представлении, то я могу использовать setFrame, и это работает. Это можно обойти? Я действительно хочу использовать autolayout, потому что это помогает сделать приложение красивым как на iphone 5, так и на более ранних устройствах. Но я также хотел бы использовать setFrame в моем подклассе, чтобы облегчить мою жизнь.
Подводя итоги, я задаюсь вопросом: могу ли я использовать автоматическую разметку, а также программно настроить рамку UIView?
5 ответов
Да, это можно сделать.
Если вы установите вид translatesAutoresizingMaskIntoConstraints = YES
затем звонит setFrame:
автоматически переводятся во время выполнения в ограничения макета на основе текущего представления autoresizingMask
, Это позволяет смешивать макет на основе фреймов с макетом на основе ограничений.
Например, вы можете использовать Auto Layout для определения макета всех подпредставлений представления, но при этом вызывать setFrame:
установить размер и положение самого представления. С вашей точки зрения, вы делаете макет со смесью Auto Layout и прямой манипуляции с кадром. Но система на самом деле использует ограничения для обработки всего.
Тем не менее, есть одна большая оговорка об использовании translatesAutoresizingMaskIntoConstraints
,
Когда вы делаете это, вам все равно нужно убедиться, что эти автоматические ограничения могут быть удовлетворены с остальными вашими ограничениями.
Так, например, предположим, что уже есть ограничения, которые определяют размер и положение вашего представления, а затем вы также установите translatesAutoresizingMaskIntoConstraints = YES
и называется setFrame:
, Призыв к setFrame:
создаст новые ограничения для представления, которые, вероятно, будут конфликтовать с уже существующими ограничениями.
(На самом деле, эта ошибка происходит часто. Если вы когда-либо видите сообщение журнала, жалующееся на конфликтующие ограничения, и одним из этих ограничений является NSAutoresizingMaskLayoutConstraint
то, что вы видите, это конфликт с автоматическим ограничением. Это легкая ошибка, потому что translatesAutoresizingMaskIntoConstraints = YES
является значением по умолчанию, поэтому, если вы настраиваете ограничения в коде, вы должны помнить, чтобы отключить его, если вы не хотите эти автоматические ограничения.)
Напротив, предположим еще раз, что уже существуют ограничения, которые определяют размер и положение вашего представления, но затем вы устанавливаете translatesAutoresizingMaskIntoConstraints = NO
прежде чем позвонить setFrame:
, В этом случае ваш setFrame:
вызовы не создают новых ограничений, поэтому между отдельными ограничениями не будет конфликта. Однако в этом случае все еще существует "конфликт" между ограничениями и установленным значением кадра. При следующем вызове Auto Layout он увидит уже существующие ограничения в представлении, вычислит требуемое им значение кадра и установит для самого кадра требуемое значение, перекрывая значение, заданное вами вручную.
Для получения более подробной информации, ознакомьтесь с разделом "Принятие автоматической разметки" в Руководстве Apple по автоматической разметке какао.
Что оказалось самым простым для меня, так это удалить представление, которое я хотел переместить / изменить размер, из его суперпредставления, установить его frame
, а затем добавить его обратно. Например, взять кастом UILabel
в UITableViewCell
подкласс:
[cell.myLabel removeFromSuperview];
cell.myLabel.frame = someFrameIGenerated;
[cell.contentView addSubview:cell.myLabel];
Что-то, что работало для меня, просто добавляло IBOutlet
для моих ограничений к контроллеру представления, затем изменяя constant
недвижимость на выходе.
Например, чтобы изменить происхождение x представления, установите выход из ведущего ограничения этого представления на свой контроллер. Другими словами, создать выход @IBOutlet var labelXOrigin: NSLayoutConstraint!
, Затем, когда вы хотите отрегулировать положение х, просто сделайте что-то вроде
self.labelXOrigin.constant = 20.0 // Or whatever origin you want to set.
Лучший способ установить фрейм подвида - это метод viewWillLayoutSubviews в проектах autolayout.
set property translationAutoresizingMaskIntoConstraints = true это будет работать после того, как представление появилось или вкладка на кнопке для установки сразу после появления представления.
Если ваше приложение не поддерживает несколько ориентаций устройств.
В viewDidLoad установите кадр вида, размер которого вы хотите изменить.
- (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];
}
Я не уверен, но я думаю, что если вы используете это решение, переключение одной ориентации на другую может вызвать проблемы