J’ai une sous-classe UIView qui dessine un cercle dont le rayon change (avec de jolies animations rebondissantes). La vue détermine la taille du cercle.
Je souhaite que cette sous-classe UIView modifie la taille de son cadre pour correspondre aux modifications animées apscopes au rayon du cercle, et je souhaite que ces modifications modifient les contraintes NSLayoutConstraint liées à la vue (de sorte que les vues limitées au bord du cercle redimensionne le cercle).
Je comprends que l’implémentation de -(CGSize)insortingnsicContentSize
et l’appel à invalidateInsortingnsicContentSize
lorsque les changements de rayon indiquent des contraintes à mettre à jour, mais je ne vois pas comment animer les modifications sur insortingnsicContentSize
.
L’appel de invalidateInsortingnsicContentSize
depuis un bloc [UIView animateWith … met simplement à jour instantanément la mise en page.
Est-ce que c’est possible et existe-t-il une solution de rechange / meilleure?
invalidateInsortingnsicContentSize
fonctionne bien avec les animations et layoutIfNeeded
. La seule chose que vous devez prendre en compte est que la modification de la taille du contenu insortingnsèque invalide la mise en page de la superview. Donc ça devrait marcher:
[UIView animateWithDuration:0.2 animations:^{ [self invalidateInsortingnsicContentSize]; [self.superview setNeedsLayout]; [self.superview layoutIfNeeded]; }];
La contrainte largeur / hauteur n’aide pas Gardez la référence de cette contrainte et …
[NSLayoutConstraint constraintWithItem:view atsortingbute:NSLayoutAtsortingbuteWidth relatedBy:NSLayoutRelationEqual toItem:nil atsortingbute:NSLayoutAtsortingbuteNotAnAtsortingbute multiplier:1 constant:myViewInitialWidth];
… quand vous voulez animer le redimensionnement de myView, faites ceci …
self.viewWidthConstraint.constant = 100; // new width [UIView animateWithDuration:0.3 animations:^{ [view layoutIfNeeded]; }];
… faites la même chose pour la hauteur.
Dépend de vos autres contraintes, vous serez peut-être obligé de donner la priorité à ces deux contraintes.
Ou vous pouvez sous- UIView
, append - (void)invalidateInsortingnsicContentSize:(BOOL)animated
et simulé par vous-même. Obtenir une nouvelle taille à partir de - (CGSize)insortingnsicContentSize
et l’animer en animant des contraintes de largeur / hauteur. Ou append une propriété pour activer / désactiver les animations et remplacer invalidateInsortingnsicContentSize
et le faire dans cette méthode. Plusieurs façons …
Dans le code ci-dessous, la classe insortingnsèque est la classe qui vient de changer sa taille en changeant une variable. Pour animer la classe insortingnsèque, utilisez uniquement le code ci-dessous. S’il affecte d’autres objects plus haut dans la hiérarchie de vues, remplacez la classe self.insortingnsic par la vue de niveau supérieur pour setNeedsLayout et layoutIfNeeded.
[UIView animateWithDuration:.2 animations:^{ self.insortingnsicClass.numberOfWeeks=8; [self.insortingnsicClass setNeedsLayout]; [self.insortingnsicClass layoutIfNeeded]; }];
Rien de tout cela n’a fonctionné pour moi. J’ai un UILabel que je règle avec une NSAtsortingbutedSsortingng. Le texte est multiligne et enveloppe les limites des mots. La hauteur est donc variable. J’ai essayé ceci:
[UIView animateWithDuration:1.0f animations:^{ self.label = newLabelText; [self.label invalidateInsortingnsicContentSize]; [self.view setNeedsLayout]; [self.view layoutIfNeeded]; }];
Et un certain nombre de variations. Aucun ne fonctionne. L’étiquette change immédiatement sa taille et glisse ensuite dans sa nouvelle position. Ainsi, l’animation de la position des étiquettes sur l’écran fonctionne. Mais l’animation du changement de taille de l’étiquette ne l’est pas.
Version rapide de la réponse de @ stigi qui a fonctionné pour moi:
UIView.animate(withDuration: 0.2, animations: { self.invalidateInsortingnsicContentSize() self.superview?.setNeedsLayout() self.superview?.layoutIfNeeded() })
Eh bien pour Swift 4/3 cela fonctionne et je pense que c’est la meilleure pratique. Si vous avez un UIView avec un UILabel et que l’UIView adapte le cadre de l’UILabel, utilisez ceci:
self.theUILabel.text = "text update" UIView.animate(withDuration: 5.0, animations: { self.theUIView.layoutIfNeeded() })
Le self.view.layoutIfNeeded () normal fonctionnera également la plupart du temps.