Saya ingin menambahkan jawaban n8gray bahwa dalam beberapa kasus Anda perlu menelepon setNeedsLayoutdiikuti oleh layoutIfNeeded.
Misalnya, Anda menulis tampilan kustom yang memperluas UIView, di mana pemosisian subview rumit dan tidak dapat dilakukan dengan AutoresizingMask atau iOS6 AutoLayout. Penentuan posisi kustom dapat dilakukan dengan mengganti layoutSubviews.
Sebagai contoh, katakanlah Anda memiliki tampilan kustom yang memiliki contentViewproperti dan edgeInsetsproperti yang memungkinkan untuk menyetel margin di sekitar contentView. layoutSubviewsakan terlihat seperti ini:
- (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);
}
Jika Anda ingin dapat menganimasikan perubahan bingkai setiap kali Anda mengubah edgeInsetsproperti, Anda perlu mengganti edgeInsetspenyetel sebagai berikut dan memanggil setNeedsLayoutdiikuti oleh 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
}
Dengan demikian, jika Anda melakukan hal berikut, jika Anda mengubah properti edgeInsets di dalam blok animasi, perubahan bingkai dari contentView akan dianimasikan.
[UIView animateWithDuration:2 animations:^{
customView.edgeInsets = UIEdgeInsetsMake(45, 17, 18, 34);
}];
Jika Anda tidak menambahkan panggilan ke layoutIfNeeded dalam metode setEdgeInsets, animasi tidak akan berfungsi karena layoutSubviews akan dipanggil pada siklus pembaruan berikutnya, yang sama dengan memanggilnya di luar blok animasi.
Jika Anda hanya memanggil layoutIfNeeded dalam metode setEdgeInsets, tidak akan ada yang terjadi karena tanda setNeedsLayout tidak disetel.