Відповіді:
В iOS 4 і пізніших версіях є спосіб зробити це просто за допомогою методу переходу UIView без необхідності імпорту QuartzCore. Можна просто сказати:
[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
})
Рішення Михайла спрацює, але насправді це не найкращий підхід.
Проблема з відмиранням альфа полягає в тому, що іноді різні шари перегляду, що перекриваються, виглядають дивно, коли вони зникають. Існують деякі інші варіанти використання Core Animation. Спочатку включіть у ваш додаток QuartzCore Framework і додайте #import <QuartzCore/QuartzCore.h>
до свого заголовка. Тепер ви можете зробити одне з наступного:
1) встановіть, button.layer.shouldRasterize = YES;
а потім використовуйте альфа-анімаційний код, який Михайло надав у своїй відповіді. Це запобіжить дивному змішуванню шарів, але має невеликий показник продуктивності, і може зробити кнопку розмитою, якщо вона не вирівняна точно на межі пікселя.
Як варіант:
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];
}
Щоб зникнути:
Ціль-С
[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
}
Щоб зникнути:
Ціль-С
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
})
}
Використовуйте це рішення для плавного ефекту fadeOut та fadeIn
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 добре працює після швидких змін 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
є негайним значенням, і ви не можете впливати на анімацію на ній, замість цього ви можете використовувати Alpha для приховування свого перегляду
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, він лише оживить один із цих станів, Причина полягає в тому, що ви встановлюєте прихований стан на значення false, перш ніж викликати UIView.animate методу який спричинить раптова видимість, і якщо ви лише анімуєте альфа, то об’єктний простір все ще є, але це не видно, що призведе до деяких проблем із інтерфейсом.
Тож найкращим підходом є спочатку перевірити, чи перегляд приховано, а потім встановіть альфа на 0,0, наприклад, коли ви встановите прихований стан на хибне, ви не побачите раптової видимості.
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 (з функцією :) приємно і акуратно.
Багато хто опублікував це, але ніхто не помітив, що там брехня виявиться лише під час запуску.
Ви можете перевести приховану властивість до істинної ідеально, тоді як при спробі переходу її в 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)
}
Моє рішення для Swift 3 . Отже, я створив функцію, яка приховує / приховує подання в потрібному порядку (коли ховається - встановіть альфа на 0, а потім сховано на істину; приховати - спочатку розкрийте подання, а потім встановіть його альфа на 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
значення виявляється миттєво (тобто, миттєво приховування / відображення).
Цей код дає анімацію, як натискання 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
, не пощастило взагалі.
Це воно. Коштуй мене колись, сподіваюся, що хтось допоможе.