Ich möchte die Antwort von n8gray ergänzen, die Sie in einigen Fällen anrufen müssen, setNeedsLayout
gefolgt von layoutIfNeeded
.
Angenommen, Sie haben eine benutzerdefinierte Ansicht geschrieben, die UIView erweitert. Die Positionierung von Unteransichten ist komplex und kann nicht mit autoresizingMask oder iOS6 AutoLayout durchgeführt werden. Die benutzerdefinierte Positionierung kann durch Überschreiben erfolgen layoutSubviews
.
Angenommen , Sie haben eine benutzerdefinierte Ansicht mit einer contentView
Eigenschaft und einer edgeInsets
Eigenschaft, mit der die Ränder um die contentView festgelegt werden können. layoutSubviews
würde so aussehen:
- (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);
}
Wenn Sie in der Lage sein möchten, die Rahmenänderung zu animieren, wenn Sie die edgeInsets
Eigenschaft ändern , müssen Sie den edgeInsets
Setter wie folgt überschreiben und aufrufen, setNeedsLayout
gefolgt von 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
}
Wenn Sie auf diese Weise Folgendes tun und die Eigenschaft edgeInsets in einem Animationsblock ändern, wird die Rahmenänderung der contentView animiert.
[UIView animateWithDuration:2 animations:^{
customView.edgeInsets = UIEdgeInsetsMake(45, 17, 18, 34);
}];
Wenn Sie den Aufruf von layoutIfNeeded nicht in der setEdgeInsets-Methode hinzufügen, funktioniert die Animation nicht, da die layoutSubviews beim nächsten Aktualisierungszyklus aufgerufen werden, was einem Aufruf außerhalb des Animationsblocks entspricht.
Wenn Sie layoutIfNeeded nur in der Methode setEdgeInsets aufrufen, geschieht nichts, da das Flag setNeedsLayout nicht gesetzt ist.