我正在使用一种不错的方法来解雇我的模态视图控制器:
[self dismissModalViewControllerWithTransition:2];
从左到右进行幻灯片转换,就像导航控制器弹出视图一样。
由于此方法是非公开方法,因此Apple不会接受它。如何在我的代码中编程这种类型的动画(从左到右滑动,关闭模态视图,从右到左滑动以呈现模态视图)?
提前致谢
答案 0 :(得分:42)
我接受了Safecase的回答,但我想在此发布我的最终解决方案:
1)为了呈现具有从右到左过渡的模态视图控制器,我写了以下方法:
-(void) presentModalView:(UIViewController *)controller {
CATransition *transition = [CATransition animation];
transition.duration = 0.35;
transition.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromRight;
// NSLog(@"%s: self.view.window=%@", _func_, self.view.window);
UIView *containerView = self.view.window;
[containerView.layer addAnimation:transition forKey:nil];
[self presentModalViewController:controller animated:NO];
}
2)使用从左到右的幻灯片转换关闭模态视图:
-(void) dismissMe {
CATransition *transition = [CATransition animation];
transition.duration = 0.35;
transition.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromLeft;
// NSLog(@"%s: controller.view.window=%@", _func_, controller.view.window);
UIView *containerView = self.view.window;
[containerView.layer addAnimation:transition forKey:nil];
[self dismissModalViewControllerAnimated:NO];
}
谢谢你们!
答案 1 :(得分:7)
试试这个:
我认为您正在从视图控制器1中解除视图控制器2.在视图控制器2中,您正在使用此
[self dismissModalViewControlleAnimated: NO]];
现在在第一个视图控制器中,在viewWillAppear:方法中添加代码
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setDuration:0.50];
[animation setTimingFunction:
[CAMediaTimingFunction functionWithName:
kCAMediaTimingFunctionEaseInEaseOut]];
[self.view.layer addAnimation:animation forKey:kCATransition];
答案 2 :(得分:1)
下面的Swift 4 ModalService
类是一个预先打包的灵活解决方案,可以放入项目中并从任何需要的地方调用。此类将模态视图从指定方向置于当前视图的顶部,然后将其移出以在其退出时显示其后面的原始视图。如果当前正在显示presentingViewController
并且您已创建并希望显示modalViewController
,则只需致电:
ModalService.present(modalViewController, presenter: presentingViewController)
然后,要解雇,请致电:
ModalService.dismiss(modalViewController)
当然可以从modalViewController本身调用ModalService.dismiss(self)
。请注意,不必从presentsViewController调用dismissing,也不需要知道或引用原始的presentationViewController。
该类提供合理的默认值,包括从右侧和左侧转换模态视图。可以通过传递方向来定制此转换方向,该方向可以针对进入和退出进行自定义:
ModalService.present(modalViewController, presenter: presentingViewController, enterFrom: .left)
和
ModalService.dismiss(self, exitTo: .left)
可以将其设置为.left
,.right
,.top
和.bottom
。如果您愿意,您也可以在几秒钟内传递自定义持续时间:
ModalService.present(modalViewController, presenter: presentingViewController, enterFrom: .left, duration: 0.5)
和
ModalService.dismiss(self, exitTo: .left, duration: 2.0)
向@jcdmb点头,就这个问题构成了该课程解决方案内核的Objective C答案。
这是完整的课程。私有transitionSubtype
返回的值看起来很奇怪但是故意这样设置。在假设需要“纠正”之前,您应该测试观察到的行为。 :)
import UIKit
class ModalService {
enum presentationDirection {
case left
case right
case top
case bottom
}
class func present(_ modalViewController: UIViewController,
presenter fromViewController: UIViewController,
enterFrom direction: presentationDirection = .right,
duration: CFTimeInterval = 0.3) {
let transition = CATransition()
transition.duration = duration
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionMoveIn
transition.subtype = ModalService.transitionSubtype(for: direction)
let containerView: UIView? = fromViewController.view.window
containerView?.layer.add(transition, forKey: nil)
fromViewController.present(modalViewController, animated: false)
}
class func dismiss(_ modalViewController: UIViewController,
exitTo direction: presentationDirection = .right,
duration: CFTimeInterval = 0.3) {
let transition = CATransition()
transition.duration = duration
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionReveal
transition.subtype = ModalService.transitionSubtype(for: direction, forExit: true)
if let layer = modalViewController.view?.window?.layer {
layer.add(transition, forKey: nil)
}
modalViewController.dismiss(animated: false)
}
private class func transitionSubtype(for direction: presentationDirection, forExit: Bool = false) -> String {
if (forExit == false) {
switch direction {
case .left:
return kCATransitionFromLeft
case .right:
return kCATransitionFromRight
case .top:
return kCATransitionFromBottom
case .bottom:
return kCATransitionFromTop
}
} else {
switch direction {
case .left:
return kCATransitionFromRight
case .right:
return kCATransitionFromLeft
case .top:
return kCATransitionFromTop
case .bottom:
return kCATransitionFromBottom
}
}
}
}