Yanıtlar:
İOS 4 ve sonraki sürümlerde, bunu sadece QuartzCore'u içe aktarmaya gerek kalmadan UIView geçiş yöntemini kullanarak yapmanın bir yolu var. Sadece şunu söyleyebilirsiniz:
[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
})
Michail'in çözümü işe yarayacak, ama aslında en iyi yaklaşım bu değil.
Alfa solması ile ilgili sorun, bazen farklı örtüşen görünüm katmanlarının soluklaştıkça garip görünmesidir. Core Animation kullanan başka alternatifler de var. Önce uygulamanıza QuartzCore çerçevesini ekleyin #import <QuartzCore/QuartzCore.h>
ve başlığınıza ekleyin . Şimdi aşağıdakilerden birini yapabilirsiniz:
1) button.layer.shouldRasterize = YES;
Michail'in cevabında verdiği alfa animasyon kodunu ayarlayın ve kullanın. Bu, katmanların garip bir şekilde karışmasını önler, ancak hafif bir performans cezasına sahiptir ve tam olarak bir piksel sınırına hizalanmamışsa düğmenin bulanık görünmesini sağlayabilir.
Alternatif:
2) Solmaya animasyon uygulamak için aşağıdaki kodu kullanın:
CATransition *animation = [CATransition animation];
animation.type = kCATransitionFade;
animation.duration = 0.4;
[button.layer addAnimation:animation forKey:nil];
button.hidden = YES;
Bu yaklaşımla ilgili güzel olan şey, canlandırılamıyor olsalar bile (örneğin, metnin veya düğmenin resmi), düğmenin herhangi bir özelliğini çapraz ifade edebilmeniz, sadece geçişi ayarlamanız ve hemen sonra özelliklerinizi ayarlamanızdır.
transitionWithView
başarılı bir solma sağlamak için , animasyon yaptığınız şeyin denetimini parametre olarak kullanmalısınız.
UIView animasyonlu özellikleri şunlardır:
- frame
- bounds
- center
- transform
- alpha
- backgroundColor
- contentStretch
Açıklama: Animasyonlar
isHidden
onlardan biri değil, bu yüzden en iyi şekilde gördüğüm gibi:
Hızlı 4:
func setView(view: UIView, hidden: Bool) {
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.isHidden = hidden
})
}
Hedef C:
- (void)setView:(UIView*)view hidden:(BOOL)hidden {
[UIView transitionWithView:view duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^(void){
[view setHidden:hidden];
} completion:nil];
}
Kaybolmak için:
Objective-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*)
}];
Hızlı 2
UIView.animateWithDuration(0.3, animations: {
button.alpha = 0
}) { (finished) in
button.hidden = finished
}
Hızlı 3, 4, 5
UIView.animate(withDuration: 0.3, animations: {
button.alpha = 0
}) { (finished) in
button.isHidden = finished
}
Solmaya:
Objective-C
button.alpha = 0;
button.hidden = NO;
[UIView animateWithDuration:0.3 animations:^{
button.alpha = 1;
}];
Hızlı 2
button.alpha = 0
button.hidden = false
UIView.animateWithDuration(0.3) {
button.alpha = 1
}
Hızlı 3, 4, 5
button.alpha = 0
button.isHidden = false
UIView.animate(withDuration: 0.3) {
button.alpha = 1
}
Bu küçük Swift 3 uzantısını kullanıyorum:
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)
}
}
hızlı 4.2
uzantısı ile:
extension UIView {
func hideWithAnimation(hidden: Bool) {
UIView.transition(with: self, duration: 0.5, options: .transitionCrossDissolve, animations: {
self.isHidden = hidden
})
}
}
basit yöntem:
func setView(view: UIView, hidden: Bool) {
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.isHidden = hidden
})
}
Düzgün bir solma ve solma efektleri için bu çözümü kullanın
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)
}
}
kullanım gibi
uielement.fadeIn()
uielement.fadeOut()
Teşekkürler
fadeOut
iOS 13'te yalnızca ayarlanan çizgileri kaldırırsam çalışır self.isHidden
.
Ben kategorisini oluşturdu UIView
bu amaçla özel bir biraz farklı konsepti bit uygulanmaktadır: visibility
. Çözümümün temel farkı, [view setVisible:NO animated:YES]
eşzamanlı olarak kontrol [view visible]
edip doğru sonucu alabilmenizdir. Bu oldukça basit ama son derece kullanışlı.
Ayrıca, "negatif boole mantığı" kullanmaktan kaçınılmasına izin verilir ( daha fazla bilgi için bkz. Kod Tamamlandı, sayfa 269, Pozitif boole değişken adları kullanma).
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
@Umair Afzal kodu bazı değişikliklerden sonra hızlıca 5 iyi çalışıyor
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)
}
}
}
kullanmak için
yourView.fadeOut()
yourView.fadeIn()
Hızlı 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)
}
}
}
Ve kullanmak için, aşağıdaki gibi basit işlevleri çağırın:
yourView.fadeOut() // this will hide your view with animation
yourView.fadeIn() /// this will show your view with animation
isHidden
hemen bir değerdir ve üzerindeki bir animasyonu etkileyemezsiniz, bunun yerine görünümünüzü gizlemek için Alfa'yı kullanabilirsiniz
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.alpha = 0
})
Ve göstermek için:
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.alpha = 1
})
Animatics kütüphanesini kullanarak ÇOK kolayca yapabilirsiniz :
//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
})
}
Bunu deneyebilirsiniz.
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)
})
}
Ve görünüm adınızı iletin
showView(objView: self.viewSaveCard)
HideView(objView: self.viewSaveCard)
Görünümünüz varsayılan olarak gizli olarak ayarlanmışsa veya birçok durumda yapmanız gerektiğini düşündüğüm Gizli durumu değiştirirseniz, bu sayfadaki yaklaşımlardan hiçbiri size FadeIn / FadeOut animasyonu vermez, bu durumlardan yalnızca birine animasyon uygular, sebebi aradığınız önce false değeri için Gizli devlet ayarlarken edilir UIView.animate Bunun nedeni, ani bir görünüme neden olacak yöntemini yalnızca alfaya animasyon uygularsanız nesne alanı hala oradadır, ancak bazı UI sorunlarına neden olacak görünür değildir.
Bu yüzden en iyi yaklaşım önce görünümün gizli olup olmadığını kontrol etmektir, ardından alfa değerini 0.0 olarak ayarlayın, Gizli durumunu yanlış olarak ayarladığınızda ani bir görünürlük görmezsiniz.
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 (ile :) işlevi güzel ve derli toplu.
Birçoğu yayınladı ama hiçbiri sadece onu çalıştırdığınızda ortaya çıkacak bir hata olduğunu fark etmedi.
Hidden özelliğini true değerine mükemmel bir şekilde geçirebilirsiniz, oysa false değerine geçmeye çalıştığınızda, görünüm herhangi bir animasyon olmadan aniden kaybolacaktır.
Çünkü bu api sadece bir görünüm içinde çalışır , yani bir görünümü göstermek için geçiş yaptığınızda, aslında hemen kendini gösterir, sadece içeriği yavaş yavaş canlandırılır.
Bu görünümü gizlemeye çalıştığınızda, kendisi hemen gizlenir, animasyonu içeriğine anlamsız hale getirir.
Bunu çözmek için bir görünümü gizlerken geçiş hedefi, gizlemek istediğiniz görünüm yerine ana görünümü olmalıdır.
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)
}
Swift 3 için çözümüm . Bu nedenle, görünümü doğru sırayla gizleyen / göstermeyen işlevi oluşturdum (gizlendiğinde - alfa değerini 0 olarak ayarlayın ve sonra true olarak saklanır; gizleme - önce görünümü ortaya çıkarın ve ardından alfa değerini 1 olarak ayarlayın):
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
blokta hide
yanlış olduğunda başka bir animasyon var ?
Swift 4 Geçişi
UIView.transition(with: view, duration: 3, options: .transitionCurlDown,
animations: {
// Animations
view.isHidden = hidden
},
completion: { finished in
// Compeleted
})
Eski hızlı sürümler için yaklaşımı kullanırsanız bir hata alırsınız:
Cannot convert value of type '(_) -> ()' to expected argument type '(() -> Void)?'
Yararlı referans .
isHidden
değeri (yani anında görünümünü gösteren / gizleme) anında oluşturulur.
Bu kod, uinavigation kontrol cihazında viewController'ı itmek gibi bir animasyon verir ...
CATransition *animation = [CATransition animation];
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromRight;
animation.duration = 0.3;
[_viewAccountName.layer addAnimation:animation forKey:nil];
_viewAccountName.hidden = true;
Bunu pop animasyonu için kullandı ...
CATransition *animation = [CATransition animation];
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromLeft;
animation.duration = 0.3;
[_viewAccountName.layer addAnimation:animation forKey:nil];
_viewAccountName.hidden = false;
Çıkılan cevaplardan bazıları denendi, bazıları sadece bir durum için çalışıyor, bazılarının iki işlev eklemesi gerekiyor.
seçenek 1
Yapacak bir şey yok 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
})
}
}
Sonra geç isFadeIn
( true
veya false
)
view.animate(fadeIn: isFadeIn)
seçenek 2
Herhangi bir parametre iletmeyin. Buna göre içeri veya dışarı kaybolur isUserInteractionEnabled
. Bu durum aynı zamanda ileri geri canlandırma durumuna da çok uygundur.
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
})
}
Sonra ara
yourView.animateFadeInOut()
Neden
self.isUserInteractionEnabled
?Yerine çalıştı
self.isUserInteractionEnabled
tarafındanself.isHidden
tüm hiç şans.
Bu kadar. Bir ara bana mal ol, umarım birisine yardım eder.