Antworten:
In iOS 4 und höher gibt es eine Möglichkeit, dies nur mit der UIView-Übergangsmethode zu tun, ohne QuartzCore importieren zu müssen. Sie können einfach sagen:
[UIView transitionWithView:button
duration:0.4
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
button.hidden = YES;
}
completion:NULL];
UIView.transition(with: button, duration: 0.4,
options: .transitionCrossDissolve,
animations: {
button.hidden = false
})
Michails Lösung wird funktionieren, aber es ist nicht der beste Ansatz.
Das Problem beim Alpha-Fading ist, dass die verschiedenen überlappenden Ansichtsebenen beim Ausblenden manchmal seltsam aussehen. Es gibt einige andere Alternativen, die Core Animation verwenden. Fügen Sie zuerst das QuartzCore-Framework in Ihre App ein und fügen Sie #import <QuartzCore/QuartzCore.h>
es Ihrem Header hinzu. Jetzt können Sie einen der folgenden Schritte ausführen:
1) Setzen Sie button.layer.shouldRasterize = YES;
den Alpha-Animationscode, den Michail in seiner Antwort angegeben hat, und verwenden Sie ihn. Dies verhindert, dass sich die Ebenen merkwürdig vermischen, hat jedoch einen leichten Leistungsverlust und kann dazu führen, dass die Schaltfläche verschwommen aussieht, wenn sie nicht genau an einer Pixelgrenze ausgerichtet ist.
Alternative:
2) Verwenden Sie stattdessen den folgenden Code, um die Überblendung zu animieren:
CATransition *animation = [CATransition animation];
animation.type = kCATransitionFade;
animation.duration = 0.4;
[button.layer addAnimation:animation forKey:nil];
button.hidden = YES;
Das Schöne an diesem Ansatz ist, dass Sie jede Eigenschaft der Schaltfläche überblenden können, auch wenn sie nicht animierbar ist (z. B. den Text oder das Bild der Schaltfläche). Richten Sie einfach den Übergang ein und legen Sie Ihre Eigenschaften unmittelbar danach fest.
transitionWithView
Parameter verwenden, um ein erfolgreiches Ein- und Ausblenden sicherzustellen.
Die animierten UIView-Eigenschaften sind:
- frame
- bounds
- center
- transform
- alpha
- backgroundColor
- contentStretch
Beschreiben Sie in: Animationen
isHidden
ist keiner von ihnen, so wie ich es sehe, ist der beste Weg:
Swift 4:
func setView(view: UIView, hidden: Bool) {
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.isHidden = hidden
})
}
Ziel c:
- (void)setView:(UIView*)view hidden:(BOOL)hidden {
[UIView transitionWithView:view duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^(void){
[view setHidden:hidden];
} completion:nil];
}
Ausblenden:
Ziel c
[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 2
UIView.animateWithDuration(0.3, animations: {
button.alpha = 0
}) { (finished) in
button.hidden = finished
}
Swift 3, 4, 5
UIView.animate(withDuration: 0.3, animations: {
button.alpha = 0
}) { (finished) in
button.isHidden = finished
}
Einblenden:
Ziel c
button.alpha = 0;
button.hidden = NO;
[UIView animateWithDuration:0.3 animations:^{
button.alpha = 1;
}];
Swift 2
button.alpha = 0
button.hidden = false
UIView.animateWithDuration(0.3) {
button.alpha = 1
}
Swift 3, 4, 5
button.alpha = 0
button.isHidden = false
UIView.animate(withDuration: 0.3) {
button.alpha = 1
}
Ich benutze diese kleine Swift 3- Erweiterung:
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)
}
}
schnell 4.2
mit Erweiterung:
extension UIView {
func hideWithAnimation(hidden: Bool) {
UIView.transition(with: self, duration: 0.5, options: .transitionCrossDissolve, animations: {
self.isHidden = hidden
})
}
}
einfache Methode:
func setView(view: UIView, hidden: Bool) {
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.isHidden = hidden
})
}
Verwenden Sie diese Lösung für reibungslose FadeOut- und FadeIn-Effekte
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)
}
}
Nutzung ist wie
uielement.fadeIn()
uielement.fadeOut()
Vielen Dank
fadeOut
funktioniert unter iOS 13 nur, wenn ich die festgelegten Zeilen entferne self.isHidden
.
Zu UIView
diesem Zweck habe ich eine Kategorie erstellt und ein spezielles, etwas anderes Konzept implementiert : visibility
. Der Hauptunterschied meiner Lösung besteht darin, dass Sie anrufen [view setVisible:NO animated:YES]
und direkt danach synchron prüfen können[view visible]
und das richtige Ergebnis erhalten können. Das ist ziemlich einfach, aber äußerst nützlich.
Außerdem darf die Verwendung einer "negativen booleschen Logik" vermieden werden ( weitere Informationen finden Sie unter Code abgeschlossen, Seite 269, Positive boolesche Variablennamen verwenden ).
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
Der Code von @Umair Afzal funktioniert nach einigen Änderungen in Swift 5 einwandfrei
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)
}
}
}
für den Einsatz
yourView.fadeOut()
yourView.fadeIn()
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)
}
}
}
Und um es zu benutzen, rufen Sie einfach diese Funktionen auf wie:
yourView.fadeOut() // this will hide your view with animation
yourView.fadeIn() /// this will show your view with animation
isHidden
ist ein unmittelbarer Wert und Sie können keine Animation darauf beeinflussen. Stattdessen können Sie Alpha verwenden, um Ihre Ansicht auszublenden
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.alpha = 0
})
Und zum Zeigen:
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.alpha = 1
})
Sie können es sehr einfach mit der Animatics- Bibliothek tun :
//To hide button:
AlphaAnimator(0) ~> button
//to show button
AlphaAnimator(1) ~> button
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
})
}
Sie können dies versuchen.
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)
})
}
Und geben Sie Ihren Ansichtsnamen weiter
showView(objView: self.viewSaveCard)
HideView(objView: self.viewSaveCard)
Wenn Ihre Ansicht standardmäßig ausgeblendet ist oder Sie den ausgeblendeten Status ändern, den Sie meiner Meinung nach in vielen Fällen sollten, bietet keiner der Ansätze auf dieser Seite beide FadeIn / FadeOut-Animationen. Es wird nur einer dieser Zustände animiert. Der Grund dafür ist, dass Sie den Status Hidden auf false setzen, bevor Sie UIView.animate aufrufen Methode " führt zu einer plötzlichen Sichtbarkeit. Wenn Sie nur das Alpha animieren, ist der Objektbereich immer noch vorhanden, aber nicht sichtbar, was zu Problemen mit der Benutzeroberfläche führt.
Der beste Ansatz ist also, zuerst zu überprüfen, ob die Ansicht ausgeblendet ist, und dann das Alpha auf 0,0 zu setzen. Wenn Sie den Status "Ausgeblendet" auf "Falsch" setzen, wird keine plötzliche Sichtbarkeit angezeigt.
func hideViewWithFade(_ view: UIView) {
if view.isHidden {
view.alpha = 0.0
}
view.isHidden = false
UIView.animate(withDuration: 0.3, delay: 0.0, options: .transitionCrossDissolve, animations: {
view.alpha = view.alpha == 1.0 ? 0.0 : 1.0
}, completion: { _ in
view.isHidden = !Bool(truncating: view.alpha as NSNumber)
})
}
UIView.transition (mit :) Funktion ist nett und ordentlich.
Viele haben es gepostet, aber keiner hat bemerkt, dass es einen Fehler gibt, der nur angezeigt wird, wenn Sie es ausführen.
Sie können versteckte Eigenschaften perfekt in true umwandeln. Wenn Sie versuchen, sie in false umzuwandeln, verschwindet die Ansicht einfach plötzlich ohne Animation.
Dies liegt daran, dass diese API nur innerhalb einer Ansicht funktioniert. Wenn Sie also eine Ansicht so umstellen, dass sie angezeigt wird , wird selbst sofort nur der Inhalt angezeigt, der schrittweise animiert wird.
Wenn Sie versuchen, diese Ansicht auszublenden, wird die Animation nach ihrem Inhalt bedeutungslos.
Um dies zu lösen, sollte beim Ausblenden einer Ansicht das Übergangsziel die übergeordnete Ansicht anstelle der Ansicht sein, die Sie ausblenden möchten.
func transitionView(_ view: UIView?, show: Bool, completion: BoolFunc? = nil) {
guard let view = view, view.isHidden == show, let parent = view.superview else { return }
let target: UIView = show ? view : parent
UIView.transition(with: target, duration: 0.4, options: [.transitionCrossDissolve], animations: {
view.isHidden = !show
}, completion: completion)
}
Meine Lösung für Swift 3 . Also habe ich die Funktion erstellt, die die Ansicht in der richtigen Reihenfolge ein- und ausblendet (beim Ausblenden - Alpha auf 0 setzen und dann auf true verbergen; Ausblenden - zuerst die Ansicht aufdecken und dann Alpha auf 1 setzen):
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)
}
completion
Block eine andere Animation, wenn sie hide
falsch ist?
Schneller 4 Übergang
UIView.transition(with: view, duration: 3, options: .transitionCurlDown,
animations: {
// Animations
view.isHidden = hidden
},
completion: { finished in
// Compeleted
})
Wenn Sie den Ansatz für ältere schnelle Versionen verwenden, wird eine Fehlermeldung angezeigt:
Cannot convert value of type '(_) -> ()' to expected argument type '(() -> Void)?'
Nützliche Referenz .
isHidden
Wert wird sofort gerendert (dh die Ansicht wird sofort ausgeblendet / angezeigt).
Dieser Code gibt eine Animation wie das Drücken von viewController in uinavigation controller ...
CATransition *animation = [CATransition animation];
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromRight;
animation.duration = 0.3;
[_viewAccountName.layer addAnimation:animation forKey:nil];
_viewAccountName.hidden = true;
Verwendet dies für Pop-Animation ...
CATransition *animation = [CATransition animation];
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromLeft;
animation.duration = 0.3;
[_viewAccountName.layer addAnimation:animation forKey:nil];
_viewAccountName.hidden = false;
Versuchte einige der verdrängten Antworten, einige funktionieren nur für eine Situation, einige müssen zwei Funktionen hinzufügen.
Option 1
Nichts damit zu tun 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
})
}
}
Dann pass isFadeIn
( true
oder false
)
view.animate(fadeIn: isFadeIn)
Option 2
Übergeben Sie keine Parameter. Es wird entsprechend ein- oder ausgeblendet isUserInteractionEnabled
. Dies passt auch gut zur Situation hin und her animieren.
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
})
}
Dann rufst du an
yourView.animateFadeInOut()
Warum
self.isUserInteractionEnabled
?Versucht zu ersetzen
self.isUserInteractionEnabled
durchself.isHidden
, überhaupt kein Glück.
Das ist es. Hat mich irgendwann gekostet, hoffe es hilft jemandem.