Я хотел бы добавить к ответу n8gray, что в некоторых случаях вам нужно будет позвонить setNeedsLayout
, а затем layoutIfNeeded
.
Допустим, например, что вы написали собственный вид, расширяющий UIView, в котором позиционирование подвидов является сложным и не может быть выполнено с помощью autoresizingMask или iOS6 AutoLayout. Пользовательское позиционирование может быть сделано путем переопределения layoutSubviews
.
В качестве примера предположим, что у вас есть пользовательское представление, которое имеет свойство contentView
и свойство edgeInsets
, которое позволяет устанавливать поля вокруг contentView. layoutSubviews
будет выглядеть так:
- (void) layoutSubviews {
self.contentView.frame = CGRectMake(
self.bounds.origin.x + self.edgeInsets.left,
self.bounds.origin.y + self.edgeInsets.top,
self.bounds.size.width - self.edgeInsets.left - self.edgeInsets.right,
self.bounds.size.height - self.edgeInsets.top - self.edgeInsets.bottom);
}
Если вы хотите иметь возможность анимировать смену кадра при каждом изменении свойства edgeInsets
, вам необходимо переопределить установщик edgeInsets
следующим образом и вызвать setNeedsLayout
, а затем layoutIfNeeded
:
- (void) setEdgeInsets:(UIEdgeInsets)edgeInsets {
_edgeInsets = edgeInsets;
[self setNeedsLayout]; //Indicates that the view needs to be laid out
//at next update or at next call of layoutIfNeeded,
//whichever comes first
[self layoutIfNeeded]; //Calls layoutSubviews if flag is set
}
Таким образом, если вы сделаете следующее, если вы измените свойство edgeInsets внутри блока анимации, то изменение кадра в ContentView будет анимированным.
[UIView animateWithDuration:2 animations:^{
customView.edgeInsets = UIEdgeInsetsMake(45, 17, 18, 34);
}];
Если вы не добавите вызов layoutIfNeeded в методе setEdgeInsets, анимация не будет работать, поскольку layoutSubviews будет вызываться при следующем цикле обновления, что эквивалентно вызову его вне блока анимации.
Если вы вызываете layoutIfNeeded только в методе setEdgeInsets, ничего не произойдет, поскольку флаг setNeedsLayout не установлен.