N8gray'in cevabına, bazı durumlarda, setNeedsLayoutardından aramanız gerekeceği cevabını eklemek istiyorum layoutIfNeeded.
Diyelim ki, alt görünümlerin konumlandırmasının karmaşık olduğu ve otomatik yeniden boyutlandırmaMask veya iOS6 Otomatik Yerleşim ile yapılamayacağı, UIView'ı genişleten özel bir görünüm yazdığınızı varsayalım. Özel konumlandırma, geçersiz kılarak yapılabilirlayoutSubviews .
Örnek olarak, contentView etrafındaki marjları ayarlamaya izin veren bir contentViewözelliği ve edgeInsetsözelliği olan özel bir görünüme sahip olduğunuzu varsayalım. layoutSubviewsşöyle görünürdü:
- (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Özelliği her değiştirdiğinizde çerçeve değişikliğini canlandırabilmek istiyorsanız , edgeInsetsaşağıdaki gibi ayarlayıcıyı geçersiz kılmanız ve setNeedsLayoutardından şunu çağırmanız gerekir 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
}
Bu şekilde, aşağıdakini yaparsanız, bir animasyon bloğunun içindeki edgeInsets özelliğini değiştirirseniz, contentView'in çerçeve değişikliğine animasyon uygulanacaktır.
[UIView animateWithDuration:2 animations:^{
customView.edgeInsets = UIEdgeInsetsMake(45, 17, 18, 34);
}];
SetEdgeInsets yönteminde layoutIfNeeded çağrısını eklemezseniz, layoutSubviews sonraki güncelleme döngüsünde çağrılacağı için animasyon çalışmayacaktır, bu da onu animasyon bloğunun dışına çağırmaya eşittir.
SetEdgeInsets yönteminde yalnızca layoutIfNeeded öğesini çağırırsanız, setNeedsLayout bayrağı ayarlanmadığından hiçbir şey olmaz.