N8gray'in cevabına, bazı durumlarda, setNeedsLayout
ardı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 , edgeInsets
aşağıdaki gibi ayarlayıcıyı geçersiz kılmanız ve setNeedsLayout
ardı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.