13 ответов:
в iOS 4 и более поздних версиях есть способ сделать это просто с помощью метода перехода UIView без необходимости импортировать QuartzCore. Можно просто сказать:
[UIView transitionWithView:button duration:0.4 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ button.hidden = YES; } completion:NULL];Предыдущие Решения
решение Михаила будет работать, но это на самом деле не лучший подход.
проблема с Альфа-замиранием заключается в том, что иногда разные перекрывающиеся слои вида выглядят странно, когда они исчезают. Есть и другие альтернативы, использующие основную анимацию. Первые включают QuartzCore framework в вашем приложении и добавить
#import <QuartzCore/QuartzCore.h>в свой заголовок. Теперь вы можете сделать одно из следующих действий:1) set
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не является одним из них, так как я вижу, что это лучший способ:Swift 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
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]и получить правильный результат. Это довольно просто, но очень полезно.кроме того, разрешается избегать использования "отрицательной булевой логики" (см. код завершен, страница 269, используйте положительные имена булевых переменных дополнительные информация.)
Свифт
UIView+Visibility.swiftimport 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
вы можете сделать это очень легко с помощью аниматик библиотека:
//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 }) }
мое решение для Swift 3. Итак, я создал функцию, которая скрывает / отображает представление в правильном порядке(при скрытии-установите Альфа в 0, а затем isHidden в true; 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 })Если вы используете подход для более старых версий swift, вы получите сообщение об ошибке:
Cannot convert value of type '(_) -> ()' to expected argument type '(() -> Void)?'полезное ссылка.
Вы можете попробовать это.
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 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
этот код дает анимацию, как нажатие 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;
Comments