답변:
iOS 4 이상에서는 QuartzCore를 가져올 필요없이 UIView 전환 방법을 사용하여이 작업을 수행 할 수 있습니다. 당신은 단지 말할 수 있습니다 :
[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의 솔루션은 효과가 있지만 실제로 최선의 방법은 아닙니다.
알파 페이딩의 문제점은 때때로 서로 다른 겹치는 뷰 레이어가 페이드 아웃 될 때 이상하게 보입니다. 코어 애니메이션을 사용하는 다른 대안이 있습니다. 먼저 QuartzCore 프레임 워크를 앱에 포함시키고 #import <QuartzCore/QuartzCore.h>
헤더에 추가 하십시오. 이제 다음 중 하나를 수행 할 수 있습니다.
1) button.layer.shouldRasterize = YES;
Michail이 자신의 답변에서 제공 한 알파 애니메이션 코드를 설정 한 다음 사용하십시오. 이렇게하면 레이어가 이상하게 블렌딩되는 것을 방지 할 수 있지만 약간의 성능 저하가 발생하며 픽셀 경계에 정확하게 정렬되지 않으면 버튼이 흐리게 보일 수 있습니다.
또는
2) 대신 다음 코드를 사용하여 페이드에 애니메이션을 적용하십시오.
CATransition *animation = [CATransition animation];
animation.type = kCATransitionFade;
animation.duration = 0.4;
[button.layer addAnimation:animation forKey:nil];
button.hidden = YES;
이 방법의 좋은 점은 버튼의 텍스트 나 이미지와 같이 애니메이션을 적용 할 수없는 경우에도 버튼의 모든 속성을 크로스 페이드 할 수 있으며 전환을 설정 한 다음 바로 속성을 설정하는 것입니다.
transitionWithView
성공적인 페이드 인 및 아웃을 보장하기 위해 애니메이션하려는 항목의 슈퍼 뷰를 매개 변수로 사용해야합니다 .
UIView 애니메이션 속성은 다음과 같습니다.
- frame
- bounds
- center
- transform
- alpha
- backgroundColor
- contentStretch
설명 : 애니메이션
isHidden
가장 좋은 방법은 다음과 같습니다.
스위프트 4 :
func setView(view: UIView, hidden: Bool) {
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.isHidden = hidden
})
}
목표 C :
- (void)setView:(UIView*)view hidden:(BOOL)hidden {
[UIView transitionWithView:view duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^(void){
[view setHidden:hidden];
} completion:nil];
}
페이드 아웃하려면 :
목표 -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*)
}];
스위프트 2
UIView.animateWithDuration(0.3, animations: {
button.alpha = 0
}) { (finished) in
button.hidden = finished
}
스위프트 3, 4, 5
UIView.animate(withDuration: 0.3, animations: {
button.alpha = 0
}) { (finished) in
button.isHidden = finished
}
페이드 인 :
목표 -C
button.alpha = 0;
button.hidden = NO;
[UIView animateWithDuration:0.3 animations:^{
button.alpha = 1;
}];
스위프트 2
button.alpha = 0
button.hidden = false
UIView.animateWithDuration(0.3) {
button.alpha = 1
}
스위프트 3, 4, 5
button.alpha = 0
button.isHidden = false
UIView.animate(withDuration: 0.3) {
button.alpha = 1
}
이 작은 Swift 3 확장을 사용합니다.
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)
}
}
스위프트 4.2
확장명 :
extension UIView {
func hideWithAnimation(hidden: Bool) {
UIView.transition(with: self, duration: 0.5, options: .transitionCrossDissolve, animations: {
self.isHidden = hidden
})
}
}
간단한 방법 :
func setView(view: UIView, hidden: Bool) {
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.isHidden = hidden
})
}
부드러운 페이드 아웃 및 페이드 인 효과를 위해이 솔루션을 사용하십시오.
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)
}
}
사용법은
uielement.fadeIn()
uielement.fadeOut()
감사
fadeOut
내가 설정 한 줄을 제거해야 iOS 13에서 작동합니다 self.isHidden
.
UIView
이 목적 을 위해 카테고리를 만들고 특별한 약간 다른 개념을 구현했습니다 visibility
. 내 솔루션의 주요 차이점은 호출 [view setVisible:NO animated:YES]
후 바로 동기화하여 확인 [view visible]
하고 올바른 결과를 얻을 수 있다는 것입니다. 이것은 매우 간단하지만 매우 유용합니다.
또한 "부울 부울 논리"를 사용하지 않아도됩니다 (자세한 내용은 269 페이지 코드 완료, 양의 부울 변수 이름 사용 참조 ).
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의 코드는 약간의 변경 후 swift 5에서 잘 작동합니다.
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)
}
}
}
사용하기위한
yourView.fadeOut()
yourView.fadeIn()
스위프트 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)
}
}
}
그리고 그것을 사용하려면 다음과 같이 간단히 다음 함수를 호출하십시오.
yourView.fadeOut() // this will hide your view with animation
yourView.fadeIn() /// this will show your view with animation
isHidden
즉각적인 가치이며 애니메이션에 영향을 줄 수 없으며 대신 알파를 사용하여 뷰를 숨길 수 있습니다
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.alpha = 0
})
그리고 보여주기 위해 :
UIView.transition(with: view, duration: 0.5, options: .transitionCrossDissolve, animations: {
view.alpha = 1
})
Animatics 라이브러리를 사용하면 매우 쉽게 할 수 있습니다 .
//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
})
}
당신은 이것을 시도 할 수 있습니다.
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)
})
}
뷰 이름을 전달하십시오.
showView(objView: self.viewSaveCard)
HideView(objView: self.viewSaveCard)
뷰가 기본적으로 숨김으로 설정되어 있거나 숨겨져있는 상태를 변경하는 경우가 많지만이 페이지의 어떤 방법도 FadeIn / FadeOut 애니메이션을 제공하지 않으면 이러한 상태 중 하나만 애니메이션으로 표시합니다. 그 이유는 UIView.animate 메서드를 호출하기 전에 Hidden 상태를 false로 설정하여 갑작스런 가시성을 유발하고 알파에만 애니메이션을 적용하면 객체 공간이 여전히 남아 있지만 표시되지 않아 일부 UI 문제가 발생하기 때문입니다.
따라서 가장 좋은 방법은 먼저 뷰가 숨겨져 있는지 확인한 다음 알파를 0.0으로 설정하는 것입니다. 숨겨진 상태를 false로 설정하면 갑자기 표시되지 않습니다.
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 (with :) 함수는 훌륭하고 깔끔합니다.
많은 사람들이 그것을 게시했지만 아무도 그것을 실행할 때만 오류가 표시되는 것을 알지 못했습니다.
숨겨진 속성을 완벽하게 true로 전환 할 수 있지만, 속성을 false로 전환하려고하면 뷰가 애니메이션없이 갑자기 사라집니다.
이 api 는보기 내 에서만 작동하기 때문에 보기를 전환하여 표시 할 때 실제로 그 자체 만 즉시 표시되며 콘텐츠 만 점차적으로 애니메이션으로 표시됩니다.
이보기를 숨기려고하면 즉시 숨겨져 서 해당 내용의 애니메이션이 의미가 없게됩니다.
이를 해결하려면 뷰를 숨길 때 전환 대상이 숨기려는 뷰 대신 상위 뷰 여야합니다.
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)
}
스위프트 3에 대한 내 솔루션 . 그래서 올바른 순서로보기를 숨기거나 숨기기 해제하는 함수를 만들었습니다 (숨기기-알파를 0으로 설정하고 isHidden을 true로 설정하면 숨기지 않음-먼저보기를 표시 한 다음 알파를 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)
}
completion
때 왜 다른 애니메이션이 블록에 hide
있습니까?
스위프트 4 전환
UIView.transition(with: view, duration: 3, options: .transitionCurlDown,
animations: {
// Animations
view.isHidden = hidden
},
completion: { finished in
// Compeleted
})
구식 빠른 버전에 대한 접근 방식을 사용하면 오류가 발생합니다.
Cannot convert value of type '(_) -> ()' to expected argument type '(() -> Void)?'
유용한 참조 .
isHidden
값 (즉, 즉시보기를 표시 / 숨기기) 즉시 렌더링됩니다.
이 코드는 uinavigation 컨트롤러에서 viewController를 누르는 것과 같은 애니메이션을 제공합니다.
CATransition *animation = [CATransition animation];
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromRight;
animation.duration = 0.3;
[_viewAccountName.layer addAnimation:animation forKey:nil];
_viewAccountName.hidden = true;
팝 애니메이션에 사용했습니다 ...
CATransition *animation = [CATransition animation];
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromLeft;
animation.duration = 0.3;
[_viewAccountName.layer addAnimation:animation forKey:nil];
_viewAccountName.hidden = false;
종료 된 답변 중 일부를 시도했지만 일부는 한 상황에서만 작동하며 일부는 두 가지 기능을 추가해야합니다.
옵션 1
와는 아무런 관련이 없습니다 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
})
}
}
그런 다음 isFadeIn
( true
또는 false
)
view.animate(fadeIn: isFadeIn)
옵션 2
매개 변수를 전달하지 마십시오. 에 따라 페이드 인 또는 페이드 아웃됩니다 isUserInteractionEnabled
. 이것은 또한 애니메이션이 앞뒤로 움직이는 상황에 매우 적합합니다.
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
})
}
그런 다음 전화
yourView.animateFadeInOut()
왜
self.isUserInteractionEnabled
?교체 시도
self.isUserInteractionEnabled
가self.isHidden
전혀 행운.
그게 다야. 언젠가는 비용이 들었습니다.