Mon objectif simple est de faire disparaître les fonctions de masquage et d'affichage.
Button.hidden = YES;
Assez simple. Cependant, est-il possible de le faire disparaître plutôt que de disparaître? Cela semble plutôt peu professionnel de cette façon.
Dans iOS 4 et versions ultérieures, il existe un moyen de le faire en utilisant simplement la méthode de transition UIView sans avoir besoin d'importer QuartzCore. Vous pouvez juste dire:
[UIView transitionWithView:button
duration:0.4
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
button.hidden = YES;
}
completion:NULL];
La solution de Michail fonctionnera, mais ce n'est pas vraiment la meilleure approche.
Le problème de la décoloration alpha est que parfois, les différentes couches de vue qui se chevauchent paraissent étranges lorsqu'elles disparaissent. Il existe d'autres alternatives utilisant Core Animation. Commencez par inclure le cadre QuartzCore dans votre application et ajoutez #import <QuartzCore/QuartzCore.h>
à votre en-tête. Vous pouvez maintenant effectuer l’une des opérations suivantes:
1) définissez button.layer.shouldRasterize = YES;
, puis utilisez le code d'animation alpha fourni par Michail dans sa réponse. Cela empêchera les calques de se mélanger bizarrement, mais entraînera une légère dégradation des performances et rendra le bouton flou s'il n'est pas aligné exactement sur une limite de pixels.
Alternativement:
2) Utilisez le code suivant pour animer le fondu à la place:
CATransition *animation = [CATransition animation];
animation.type = kCATransitionFade;
animation.duration = 0.4;
[button.layer addAnimation:animation forKey:nil];
button.hidden = YES;
La bonne chose à propos de cette approche est que vous pouvez appliquer un fondu enchaîné à n’importe quelle propriété du bouton, même si elle n’est pas animable (par exemple, le texte ou l’image du bouton), il suffit de configurer la transition, puis de définir immédiatement vos propriétés.
Les propriétés animées UIView sont:
- frame
- bounds
- center
- transform
- alpha
- backgroundColor
- contentStretch
Décrivez dans: Animations
isHidden
n’est pas l’un d’entre eux, donc, à mon avis, le meilleur moyen est de:
Swift 4:
func setView(view: UIView, hidden: Bool) {
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.isHidden = hidden
})
}
Objectif c:
- (void)setView:(UIView*)view hidden:(BOOL)hidden {
[UIView transitionWithView:view duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^(void){
[view setHidden:hidden];
} completion:nil];
}
Pour disparaître progressivement:
[UIView animateWithDuration:0.3 animations:^{
button.alpha = 0;
} completion: ^(BOOL finished) {//creates a variable (BOOL) called "finished" that is set to *YES* when animation IS completed.
button.hidden = finished;//if animation is finished ("finished" == *YES*), then hidden = "finished" ... (aka hidden = *YES*)
}];
// Swift:
UIView.animateWithDuration(0.3, animations: {
button.alpha = 0
}) { (finished) in
button.hidden = finished
}
Fondu en:
button.alpha = 0;
button.hidden = NO;
[UIView animateWithDuration:0.3 animations:^{
button.alpha = 1;
}];
// Swift:
button.alpha = 0
button.hidden = false
UIView.animateWithDuration(0.3) {
button.alpha = 1
}
J'utilise ce petit Swift 3 extension:
extension UIView {
func fadeIn(duration: TimeInterval = 0.5,
delay: TimeInterval = 0.0,
completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
UIView.animate(withDuration: duration,
delay: delay,
options: UIViewAnimationOptions.curveEaseIn,
animations: {
self.alpha = 1.0
}, completion: completion)
}
func fadeOut(duration: TimeInterval = 0.5,
delay: TimeInterval = 0.0,
completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
UIView.animate(withDuration: duration,
delay: delay,
options: UIViewAnimationOptions.curveEaseIn,
animations: {
self.alpha = 0.0
}, completion: completion)
}
}
Swift 3
func appearView() {
self.myView.alpha = 0
self.myView.isHidden = false
UIView.animate(withDuration: 0.9, animations: {
self.myView.alpha = 1
}, completion: {
finished in
self.myView.isHidden = false
})
}
J'ai créé la catégorie pour UIView
à cette fin et mis en œuvre un concept spécial un peu différent: visibility
. La principale différence de ma solution est que vous pouvez appeler [view setVisible:NO animated:YES]
et juste après que vérifier de manière synchrone [view visible]
et obtenir un résultat correct. C'est assez simple mais extrêmement utile.
En outre, il est permis d'éviter d'utiliser la "logique booléenne négative" (voir Code terminé, page 277, Utiliser des noms de variables booléennes positives pour plus d'informations).
UIView+Visibility.Swift
import UIKit
private let UIViewVisibilityShowAnimationKey = "UIViewVisibilityShowAnimationKey"
private let UIViewVisibilityHideAnimationKey = "UIViewVisibilityHideAnimationKey"
private class UIViewAnimationDelegate: NSObject {
weak var view: UIView?
dynamic override func animationDidStop(animation: CAAnimation, finished: Bool) {
guard let view = self.view where finished else {
return
}
view.hidden = !view.visible
view.removeVisibilityAnimations()
}
}
extension UIView {
private func removeVisibilityAnimations() {
self.layer.removeAnimationForKey(UIViewVisibilityShowAnimationKey)
self.layer.removeAnimationForKey(UIViewVisibilityHideAnimationKey)
}
var visible: Bool {
get {
return !self.hidden && self.layer.animationForKey(UIViewVisibilityHideAnimationKey) == nil
}
set {
let visible = newValue
guard self.visible != visible else {
return
}
let animated = UIView.areAnimationsEnabled()
self.removeVisibilityAnimations()
guard animated else {
self.hidden = !visible
return
}
self.hidden = false
let delegate = UIViewAnimationDelegate()
delegate.view = self
let animation = CABasicAnimation(keyPath: "opacity")
animation.fromValue = visible ? 0.0 : 1.0
animation.toValue = visible ? 1.0 : 0.0
animation.fillMode = kCAFillModeForwards
animation.removedOnCompletion = false
animation.delegate = delegate
self.layer.addAnimation(animation, forKey: visible ? UIViewVisibilityShowAnimationKey : UIViewVisibilityHideAnimationKey)
}
}
func setVisible(visible: Bool, animated: Bool) {
let wereAnimationsEnabled = UIView.areAnimationsEnabled()
if wereAnimationsEnabled != animated {
UIView.setAnimationsEnabled(animated)
defer { UIView.setAnimationsEnabled(!animated) }
}
self.visible = visible
}
}
UIView+Visibility.h
#import <UIKit/UIKit.h>
@interface UIView (Visibility)
- (BOOL)visible;
- (void)setVisible:(BOOL)visible;
- (void)setVisible:(BOOL)visible animated:(BOOL)animated;
@end
UIView+Visibility.m
#import "UIView+Visibility.h"
NSString *const UIViewVisibilityAnimationKeyShow = @"UIViewVisibilityAnimationKeyShow";
NSString *const UIViewVisibilityAnimationKeyHide = @"UIViewVisibilityAnimationKeyHide";
@implementation UIView (Visibility)
- (BOOL)visible
{
if (self.hidden || [self.layer animationForKey:UIViewVisibilityAnimationKeyHide]) {
return NO;
}
return YES;
}
- (void)setVisible:(BOOL)visible
{
[self setVisible:visible animated:NO];
}
- (void)setVisible:(BOOL)visible animated:(BOOL)animated
{
if (self.visible == visible) {
return;
}
[self.layer removeAnimationForKey:UIViewVisibilityAnimationKeyShow];
[self.layer removeAnimationForKey:UIViewVisibilityAnimationKeyHide];
if (!animated) {
self.alpha = 1.f;
self.hidden = !visible;
return;
}
self.hidden = NO;
CGFloat fromAlpha = visible ? 0.f : 1.f;
CGFloat toAlpha = visible ? 1.f : 0.f;
NSString *animationKey = visible ? UIViewVisibilityAnimationKeyShow : UIViewVisibilityAnimationKeyHide;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.duration = 0.25;
animation.fromValue = @(fromAlpha);
animation.toValue = @(toAlpha);
animation.delegate = self;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[self.layer addAnimation:animation forKey:animationKey];
}
#pragma mark - CAAnimationDelegate
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished
{
if ([[self.layer animationForKey:UIViewVisibilityAnimationKeyHide] isEqual:animation]) {
self.hidden = YES;
}
}
@end
Swift 4
extension UIView {
func fadeIn(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
self.alpha = 0.0
UIView.animate(withDuration: duration, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations: {
self.isHidden = false
self.alpha = 1.0
}, completion: completion)
}
func fadeOut(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
self.alpha = 1.0
UIView.animate(withDuration: duration, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations: {
self.alpha = 0.0
}) { (completed) in
self.isHidden = true
completion(true)
}
}
}
Et pour l'utiliser, appelez simplement ces fonctions comme:
yourView.fadeOut() // this will hide your view with animation
yourView.fadeIn() /// this will show your view with animation
Swift 4.2
avec extension:
extension UIView {
func hideWithAnimation(hidden: Bool) {
UIView.transition(with: self, duration: 0.5, options: .transitionCrossDissolve, animations: {
self.isHidden = hidden
})
}
}
méthode simple:
func setView(view: UIView, hidden: Bool) {
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.isHidden = hidden
})
}
func flipViews(fromView: UIView, toView: UIView) {
toView.frame.Origin.y = 0
self.view.isUserInteractionEnabled = false
UIView.transition(from: fromView, to: toView, duration: 0.5, options: .transitionFlipFromLeft, completion: { finished in
fromView.frame.Origin.y = -900
self.view.isUserInteractionEnabled = true
})
}
Vous pouvez le faire TRÈS facilement en utilisant Animatics library:
//To hide button:
AlphaAnimator(0) ~> button
//to show button
AlphaAnimator(1) ~> button
Vous pouvez essayer ça.
func showView(objView:UIView){
objView.alpha = 0.0
UIView.animate(withDuration: 0.5, animations: {
objView.alpha = 0.0
}, completion: { (completeFadein: Bool) -> Void in
objView.alpha = 1.0
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionFade
objView.layer.add(transition, forKey: nil)
})
}
func HideView(objView:UIView){
UIView.animate(withDuration: 0.5, animations: {
objView.alpha = 1.0
}, completion: { (completeFadein: Bool) -> Void in
objView.alpha = 0.0
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionFade
objView.layer.add(transition, forKey: nil)
})
}
Et passez votre nom de vue
showView(objView: self.viewSaveCard)
HideView(objView: self.viewSaveCard)
J'ai essayé certaines réponses, certaines ne fonctionnent que dans une situation, d'autres doivent ajouter deux fonctions.
Option 1
Rien à voir avec view.isHidden
.
extension UIView {
func animate(fadeIn: Bool, withDuration: TimeInterval = 1.0) {
UIView.animate(withDuration: withDuration, delay: 0.0, options: .curveEaseInOut, animations: {
self.alpha = fadeIn ? 1.0 : 0.0
})
}
}
Puis passez isFadeIn
(true
ou false
)
view.animate(fadeIn: isFadeIn)
Option 2
Ne passez aucun paramètre. Il apparaît ou disparaît selon isUserInteractionEnabled
. Cela convient aussi très bien à la situation animée.
func animateFadeInOut(withDuration: TimeInterval = 1.0) {
self.isUserInteractionEnabled = !self.isUserInteractionEnabled
UIView.animate(withDuration: withDuration, delay: 0.0, options: .curveEaseInOut, animations: {
self.alpha = self.isUserInteractionEnabled ? 1.0 : 0.0
})
}
Alors tu appelles
yourView.animateFadeInOut()
Pourquoi
self.isUserInteractionEnabled
?J'ai essayé de remplacer
self.isUserInteractionEnabled
parself.isHidden
, sans aucune chance.
C'est tout. Cela me coûte quelque temps, espérons que cela aide quelqu'un.
le code de @Umair Afzal fonctionne bien dans Swift 5 après quelques modifications
extension UIView {
func fadeIn(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
self.alpha = 0.0
UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
self.isHidden = false
self.alpha = 1.0
}, completion: completion)
}
func fadeOut(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
self.alpha = 1.0
UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
self.alpha = 0.0
}) { (completed) in
self.isHidden = true
completion(true)
}
}
}
pour utilisation
yourView.fadeOut()
yourView.fadeIn()
Ma solution pour Swift 3 . J'ai donc créé la fonction, qui masque/masque la vue dans le bon ordre (lorsque vous cachez - définissez alpha sur 0, puis sur Caché sur true; annulez - révélez tout d'abord la vue, puis définissez sa valeur alpha sur 1):
func hide(_ hide: Bool) {
let animations = hide ? { self.alpha = 0 } :
{ self.isHidden = false }
let completion: (Bool) -> Void = hide ? { _ in self.isHidden = true } :
{ _ in UIView.animate(withDuration: duration, animations: { self.alpha = 1 }) }
UIView.animate(withDuration: duration, animations: animations, completion: completion)
}
Swift 4 Transition
UIView.transition(with: view, duration: 3, options: .transitionCurlDown,
animations: {
// Animations
view.isHidden = hidden
},
completion: { finished in
// Compeleted
})
Si vous utilisez l'approche pour les anciennes versions de Swift, vous obtiendrez une erreur:
Cannot convert value of type '(_) -> ()' to expected argument type '(() -> Void)?'
Utile référence .
Utilisez cette solution pour un effet de fondu en douceur
extension UIView {
func fadeIn(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in }) {
self.alpha = 0.0
UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseIn, animations: {
self.isHidden = false
self.alpha = 1.0
}, completion: completion)
}
func fadeOut(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in }) {
self.alpha = 1.0
UIView.animate(withDuration: duration, delay: delay, options: UIView.AnimationOptions.curveEaseOut, animations: {
self.isHidden = true
self.alpha = 0.0
}, completion: completion)
}
}
l'utilisation est comme
uielement.fadeIn()
uielement.fadeOut()
Merci
Ce code donne une animation comme en poussant viewController dans contrôleur de navigation ...
CATransition *animation = [CATransition animation];
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromRight;
animation.duration = 0.3;
[_viewAccountName.layer addAnimation:animation forKey:nil];
_viewAccountName.hidden = true;
Utilisé pour l'animation pop ...
CATransition *animation = [CATransition animation];
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromLeft;
animation.duration = 0.3;
[_viewAccountName.layer addAnimation:animation forKey:nil];
_viewAccountName.hidden = false;