私はいくつかのケースでは、あなたが呼び出す必要がありますことをn8grayの答えに追加したいsetNeedsLayout
が続きますlayoutIfNeeded
。
たとえば、サブビューの配置が複雑で、autoresizingMaskまたはiOS6 AutoLayoutでは実行できない、UIViewを拡張するカスタムビューを作成したとします。カスタムポジショニングは、をオーバーライドすることで実行できます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);
}];
setEdgeInsetsメソッドでlayoutIfNeededへの呼び出しを追加しない場合、layoutSubviewsは次の更新サイクルで呼び出されるため、アニメーションは機能しません。これは、アニメーションブロックの外で呼び出すことと同じです。
setEdgeInsetsメソッドでlayoutIfNeededを呼び出すだけの場合、setNeedsLayoutフラグが設定されていないため、何も起こりません。