Моя простая цель - скрывать скрытые и отображаемые функции.
Button.hidden = YES;
Прост достаточно. Однако возможно ли, чтобы оно исчезло, а не просто исчезло? Это выглядит довольно непрофессионально.
Моя простая цель - скрывать скрытые и отображаемые функции.
Button.hidden = YES;
Прост достаточно. Однако возможно ли, чтобы оно исчезло, а не просто исчезло? Это выглядит довольно непрофессионально.
В iOS 4 и более поздних версиях есть способ сделать это, используя метод перехода UIView без необходимости импортировать QuartzCore. Вы можете просто сказать:
[UIView transitionWithView:button
duration:0.4
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
button.hidden = YES;
}
completion:NULL];
Решение Michail будет работать, но на самом деле это не лучший подход.
Проблема с альфа-замиранием заключается в том, что иногда разные перекрывающиеся слои выглядят странно, когда они исчезают. Существуют и другие альтернативы, использующие Core Animation. Сначала включите среду QuartzCore в ваше приложение и добавьте #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;
Самое приятное в этом подходе - вы можете перечеркнуть любое свойство кнопки, даже если они не являются анимированными (например, текст или изображение кнопки), просто настройте переход, а затем сразу установите свои свойства.
Анимированные свойства UIView:
- frame
- bounds
- center
- transform
- alpha
- backgroundColor
- contentStretch
Опишите в: Анимации
isHidden
не является одним из них, поэтому, на мой 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*)
}];
// swift:
UIView.animateWithDuration(0.3, animations: {
button.alpha = 0
}) { (finished) in
button.hidden = finished
}
Затухать в:
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
}
Я использую это небольшое расширение 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)
}
}
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
})
}
Я создал для этой категории категорию UIView
и реализовал специальную немного другую концепцию: visibility
. Основное отличие моего решения заключается в том, что вы можете вызвать [view setVisible:NO animated:YES]
и сразу после этого синхронно проверить [view visible]
и получить правильный результат. Это довольно просто, но очень полезно.
Кроме того, разрешено избегать использования "отрицательной логической логики" (см. Code Complete, стр. 269, Использовать логические имена переменных boolean для более информация).
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)
}
}
}
И чтобы использовать его, просто вызовите эти функции, такие как:
yourView.fadeOut() // this will hide your view with animation
yourView.fadeIn() /// this will show your view with animation
Swift 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
})
}
Код @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()
Вы можете сделать это ОЧЕНЬ легко, используя 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)
Мое решение для Swift 3. Таким образом, я создал функцию, которая скрывает/скрывает представление в правильном порядке (при укрытии - устанавливает альфа-значение в 0, а затем isHidden для истины; unhiding - сначала открывает представление, а затем устанавливает альфа-значение в 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
})
Если вы используете подход для более старых версий, вы получите сообщение об ошибке:
Cannot convert value of type '(_) -> ()' to expected argument type '(() -> Void)?'
Полезно ссылка.
Этот код дает анимацию, как нажатие viewController в контроллере uinavigation...
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
, не повезло вообще.
Это. Стоит мне когда-нибудь, надеюсь, это кому-нибудь поможет.
Используйте это решение для плавного эффекта 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()
Спасибо
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
})