Ich möchte einer Ansicht eine Animation hinzufügen, während sie ihren verborgenen Modus ändert
my_view.hidden=YES;
Ich habe eine Schaltfläche in der Navigationsleiste hinzugefügt. Wenn wir darauf klicken, wird die neue Ansicht wieder eingeblendet. Es zeichnet am oberen Rand der Navigationstabelle.
Hidden ist leider keine Eigenschaft, die durch UIView-Animationen animiert werden kann. Ich denke, Ihre beste Wette könnte darin bestehen, eine der von @Erik B vorgeschlagenen Animationen zu verwenden, oder sich mit Core-Animationen zu beschäftigen, die viel mächtiger sind. Werfen Sie einen Blick auf die Dokumentation für UIView-Animationen und Core-Animationen.
Ich habe etwas erreicht, was Sie vorschlagen, indem Sie UIView-Animationen verwenden, um die neue Ansicht unter eine andere Ansicht zu verschieben. Dadurch sah es aus wie eine Schublade, die herausrutschte. Wenn Sie so etwas tun möchten, müssen Sie die Nachbesserung im Ereignis abfangen und den Animationscode dort platzieren.
- (IBAction)buttonClicked:(id)sender {
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationCurveEaseOut
animations:^(void) {
self.myView.frame = /* set the frame here */
}
completion:NULL];
}
Animieren Sie die Deckkraft der Ansicht von 100% bis 0%. Haben Sie den Rückruf für die Animation abgeschlossen, um die Ansicht auszublenden. Möglicherweise möchten Sie die Deckkraft während des Rückrufs wieder auf 100% zurücksetzen, sodass die Ansicht beim Ausblenden vollständig undurchsichtig angezeigt wird.
yourView.alpha = 0.0 //for zero opacity
yourView.alpha = 1.0 //for 100% opacity
Es gibt jedoch keine Animation zum Verstecken. Sie erhalten dasselbe Ergebnis mit dem folgenden Swift-Code:
UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: {
self.yourView.alpha = 0 // Here you will get the animation you want
}, completion: { _ in
self.yourView.hidden = true // Here you hide it when animation done
})
Aktualisiert zu Swift 3 :
UIView.animate(withDuration: 0.2, delay: 0.2, options: .curveEaseOut,
animations: {firstView.alpha = 0},
completion: { _ in firstView.isHidden = true
//Do anything else that depends on this animation ending
})
Und wenn Sie etwas zurück animieren möchten, nachdem die erste Ansicht weg ist, können Sie den Code innerhalb des Vervollständigungsblocks mit alpha = 1
und hidden = false
replizieren.
Hier ist eine Kategorie, die ich geschrieben habe, um eine neue "versteckte" Eigenschaft in UIView einzuführen, die die Animation korrekt unterstützt:
@implementation UIView (AnimateHidden)
-(void)setHiddenAnimated:(BOOL)hide
{
[UIView animateWithDuration:0.5
delay:0.0
options: UIViewAnimationCurveEaseOut
animations:^
{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
if (hide)
self.alpha=0;
else
{
self.hidden= NO;
self.alpha=1;
}
}
completion:^(BOOL b)
{
if (hide)
self.hidden= YES;
}
];
}
@end
Ich denke, ein besserer Weg, dies zu tun, ist:
[UIView transitionWithView:aView
duration:0.3
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^(void){
aView.hidden = NO;
}
completion:nil];
Dies ist korrigierte N.J.-Version:
@implementation UIView (AnimateHidden)
-(void)setHiddenAnimated:(BOOL)hide duration:(NSTimeInterval)duration {
if(self.hidden == hide)
return;
if(hide)
self.alpha = 1;
else {
self.alpha = 0;
self.hidden = NO;
}
[UIView animateWithDuration:duration animations:^{
if (hide)
self.alpha = 0;
else
self.alpha = 1;
} completion:^(BOOL finished) {
if(finished)
self.hidden = hide;
}];
}
@end
Hier ist die Swift-Version dafür:
UIView.animateWithDuration(0.5, delay: 0.2, options:
UIViewAnimationOptions.CurveEaseOut, animations: {
objView.alpha = 0
}, completion: { finished in
objView.hidden = true
})
Dadurch werden Animationen mit einer Dauer von 5 Sekunden und einer Verzögerung von 2 Sekunden ausgeführt.
Verfügbare Animationsoptionen sind:
CurveEaseInOut, CurveEaseIn, CurveEaseOut, CurveLinear
Die Antworten von NJ und Stanislav hier halfen mir dabei, eine neue Kategorie zu erstellen, die meiner Meinung nach ihre Antworten verbessert. Ich dachte, ich würde das posten, was ich mir vorgestellt habe, falls es anderen helfen würde.
Beachten Sie, dass es nur in iOS4 oder höher funktioniert, da es Blöcke verwendet.
UIView + AnimateHidden.m
#import "UIView+AnimateHidden.h"
@implementation UIView (AnimateHidden)
- (void)setHidden:(BOOL)hidden animated:(BOOL)animated
{
// If the hidden value is already set, do nothing
if (hidden == self.hidden) {
return;
}
// If no animation requested, do the normal setHidden method
else if (animated == NO) {
[self setHidden:hidden];
return;
}
else {
// Store the view's current alpha value
CGFloat origAlpha = self.alpha;
// If we're unhiding the view, make it invisible initially
if (hidden == NO) {
self.alpha = 0;
}
// Unhide the view so we can see the animation
self.hidden = NO;
// Do the animation
[UIView animateWithDuration:0.5
delay:0.0
options: UIViewAnimationOptionCurveEaseOut
animations:^{
// Start animation block
if (hidden == YES) {
self.alpha = 0;
}
else {
self.alpha = origAlpha;
}
// End animation block
}
completion:^(BOOL b){
// Start completion block
// Finish up by hiding the view if necessary...
self.hidden = hidden;
// ... and putting back the correct alpha value
self.alpha = origAlpha;
// End completion block
}];
}
}
@end
Da einige dieser Antworten etwas unübersichtlich sind, dachte ich, ich könnte mein minimalistisches Design dieser API veröffentlichen. Ich habe auch die Verzögerung und Dauer hinzugefügt - warum nicht.
In der Implementierung haben wir.
#import "UIView+AnimateHidden.h"
@implementation UIView (AnimateHidden)
- (void)setHiddenAnimated:(BOOL)hide
delay:(NSTimeInterval)delay
duration:(NSTimeInterval)duration {
[UIView animateWithDuration:duration
delay:delay
options:UIViewAnimationOptionAllowAnimatedContent
animations:^{
if (hide) {
self.alpha = 0;
} else {
self.alpha = 0;
self.hidden = NO; // We need this to see the animation 0 -> 1
self.alpha = 1;
}
} completion:^(BOOL finished) {
self.hidden = hide;
}];
}
@end
In der Header Datei haben wir.
#import <UIKit/UIKit.h>
@interface UIView (AnimateHidden)
- (void)setHiddenAnimated:(BOOL)hide
delay:(NSTimeInterval)delay
duration:(NSTimeInterval)duration;
@end
Eine andere Version, wenn Sie komplexere Animationstypen oder Animationen verwenden möchten, die nicht von UIView unterstützt werden
- (void)setHidden:(BOOL)hidden withAnimationDuration:(NSTimeInterval)duration
{
CATransition* transition = ({
CATransition* its = [CATransition animation];
its.duration = duration;
its.timingFunction =
[CAMediaTimingFunction
functionWithName: kCAMediaTimingFunctionEaseInEaseOut];
its.type = kCATransitionPush;
its.subtype = (hidden ? @"fromBottom" : @"fromTop");
its
});
UIView* containerView = self.superview;
[containerView.layer removeAllAnimations];
[containerView.layer addAnimation: transition forKey: kCATransition];
self.hidden = hidden;
if (!hidden) {
[self.superview bringSubviewToFront: self];
}
}
Hier ist der Code, den ich zum Modellieren einer Ansicht verwendet habe: "Vergrößern" und "Verkleinern". Modellierung der Antwort von Palyancodr
Dieser Ansatz ermöglicht es mir, beide Ansichten im Storyboard zu erstellen, sodass die Einschränkungen auf den verschiedenen iOS-Geräten wie erwartet funktionieren und ich nicht alle Einschränkungen individuell anpassen muss.
@IBAction func showMoreOrLessAction(_ sender: Any) {
// if small view showing
if showMoreLargeView.isHidden {
showMoreSmallView.isHidden = true
//showMoreLargeView.isHidden = false
UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: {
self.showMoreLargeView.alpha = 1 // Here you will get the animation you want
}, completion: { _ in
self.showMoreLargeView.isHidden = false // Here you hide it when animation done
})
}
else { // large view showing
//showMoreSmallView.isHidden = false
UIView.animate(withDuration: 0.2, delay: 0, options: [], animations: {
self.showMoreSmallView.alpha = 1 // Here you will get the animation you want
}, completion: { _ in
self.showMoreSmallView.isHidden = false // Here you hide it when animation done
})
showMoreLargeView.isHidden = true
}
}