ios – 取消呈现视图控制器的交互式解雇转换后,视图控制器不会自动旋转

前端之家收集整理的这篇文章主要介绍了ios – 取消呈现视图控制器的交互式解雇转换后,视图控制器不会自动旋转前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个视图控制器使用modalPresentationStyle = UIModalPresentationCustom呈现另一个视图控制器.设置的内容使得呈现视图控制器视图的一部分显示在呈现的视图控制器视图下方.在此状态下,呈现视图控制器仍然可以正确处理自动旋转,并使用autolayout处理呈现的视图控制器的旋转.

我现在正尝试使用iOS 7的自定义视图控制器转换API以交互方式实现解除所呈现的视图控制器.它的工作原理除外,当取消交互式解雇时,自动旋转的处理停止工作. (它会在稍后解除所呈现的视图控制器之后再次工作.)为什么会发生这种情况,我该如何解决这个问题?

编辑:这是您可以运行以演示问题的代码.从下面弹出一个视图,您可以通过向下滑动来消除它.如果通过不完全向下滑动来取消解雇,则呈现视图控制器的视图不再响应旋转,并且呈现的视图控制器的视图具有混乱的布局.

编辑:以下是作为Xcode项目的代码链接
https://drive.google.com/file/d/0BwcBqUuDfCG2YlhVWE1QekhUWlk/edit?usp=sharing

对于大规模的代码转储感到抱歉,但我不知道我做错了什么.这是一个正在发生的事情的草图:ViewController1呈现ViewController2. ViewController1实现了UIViewControllerTransitioningDelegate,因此它返回了转换的动画/交互式控制器. ViewController2有一个平移手势识别器,可以驱动交互式解雇;它实现了UIViewControllerInteractiveTransitioning作为解雇的交互式控制器.如果用户将视图拖得足够远,它还会保留对动画控制器的引用以解除转换以完成转换.最后,有两个动画控制器对象. PresentAnimationController设置autolayout约束来处理呈现的视图控制器视图的旋转,DismissAnimationController结束解雇.

ViewController1.h

  1. #import <UIKit/UIKit.h>
  2.  
  3. @interface ViewController1 : UIViewController <UIViewControllerTransitioningDelegate>
  4.  
  5. @end

ViewController1.m

  1. #import "ViewController1.h"
  2.  
  3. #import "ViewController2.h"
  4.  
  5. #import "PresentAnimationController.h"
  6. #import "DismissAnimationController.h"
  7.  
  8. @implementation ViewController1
  9.  
  10. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  11. {
  12. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  13. if (self) {
  14. self.title = @"View 1";
  15.  
  16. self.navigationItem.prompt = @"Press “Present” and then swipe down to dismiss.";
  17. self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Present" style:UIBarButtonItemStylePlain target:self action:@selector(pressedPresentButton:)];
  18. }
  19. return self;
  20. }
  21.  
  22. - (void)viewDidLoad
  23. {
  24. [super viewDidLoad];
  25.  
  26. self.view.backgroundColor = [UIColor whiteColor];
  27.  
  28. // Some subview just to check if layout is working.
  29. UIView * someSubview = [[UIView alloc] initWithFrame:self.view.bounds];
  30. someSubview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  31. someSubview.backgroundColor = [UIColor orangeColor];
  32. someSubview.layer.borderColor = [UIColor redColor].CGColor;
  33. someSubview.layer.borderWidth = 2;
  34. [self.view addSubview:someSubview];
  35. }
  36.  
  37. // --------------------
  38.  
  39. - (void)pressedPresentButton:(id)sender
  40. {
  41. ViewController2 * presentedVC = [[ViewController2 alloc] initWithNibName:nil bundle:nil];
  42.  
  43. presentedVC.modalPresentationStyle = UIModalPresentationCustom;
  44. presentedVC.transitioningDelegate = self;
  45.  
  46. [self presentViewController:presentedVC animated:YES completion:nil];
  47. }
  48.  
  49. // --------------------
  50.  
  51. // View Controller Transitioning Delegate Methods.
  52.  
  53. - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
  54. {
  55. return [[PresentAnimationController alloc] init];;
  56. }
  57.  
  58. - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
  59. {
  60. DismissAnimationController * animationController = [[DismissAnimationController alloc] init];
  61.  
  62. ViewController2 * presentedVC = (ViewController2 *)self.presentedViewController;
  63.  
  64. if (presentedVC.dismissalIsInteractive) {
  65. presentedVC.dismissAnimationController = animationController;
  66. }
  67.  
  68. return animationController;
  69. }
  70.  
  71. - (id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator
  72. {
  73. return nil;
  74. }
  75.  
  76. - (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator
  77. {
  78. ViewController2 * presentedVC = (ViewController2 *)self.presentedViewController;
  79.  
  80. if (presentedVC.dismissalIsInteractive) {
  81. return presentedVC;
  82. }
  83. else {
  84. return nil;
  85. }
  86. }
  87.  
  88. @end

ViewController2.h

  1. #import <UIKit/UIKit.h>
  2.  
  3. #import "DismissAnimationController.h"
  4.  
  5. @interface ViewController2 : UIViewController <UIViewControllerInteractiveTransitioning>
  6.  
  7. @property (weak,nonatomic) UIView * contentView;
  8.  
  9. @property (nonatomic,readonly) BOOL dismissalIsInteractive;
  10. @property (strong,nonatomic) DismissAnimationController * dismissAnimationController;
  11.  
  12. @end

ViewController2.m

  1. #import "ViewController2.h"
  2.  
  3. @interface ViewController2 ()
  4.  
  5. @property (strong,nonatomic) id<UIViewControllerContextTransitioning> transitionContext;
  6.  
  7. @end
  8.  
  9. @implementation ViewController2
  10.  
  11. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  12. {
  13. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  14. if (self) {
  15. _dismissalIsInteractive = NO;
  16. }
  17. return self;
  18. }
  19.  
  20. - (void)viewDidLoad
  21. {
  22. [super viewDidLoad];
  23.  
  24. self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
  25.  
  26. // Set up content view.
  27. CGRect frame = UIEdgeInsetsInsetRect(self.view.bounds,UIEdgeInsetsMake(15,15,15));
  28. UIView * contentView = [[UIView alloc] initWithFrame:frame];
  29. self.contentView = contentView;
  30. contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  31. contentView.backgroundColor = [UIColor cyanColor];
  32. contentView.layer.borderColor = [UIColor blueColor].CGColor;
  33. contentView.layer.borderWidth = 2;
  34. [self.view addSubview:contentView];
  35.  
  36. // Set up pan dismissal gesture recognizer.
  37. UIPanGestureRecognizer * panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(dismissalPan:)];
  38. [self.view addGestureRecognizer:panGesture];
  39. }
  40.  
  41. // --------------------
  42.  
  43. - (void)dismissalPan:(UIPanGestureRecognizer *)panGesture
  44. {
  45. switch (panGesture.state) {
  46. case UIGestureRecognizerStateBegan: {
  47. _dismissalIsInteractive = YES;
  48.  
  49. [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
  50.  
  51. break;
  52. }
  53.  
  54. case UIGestureRecognizerStateChanged: {
  55. CGPoint translation = [panGesture translationInView:self.view];
  56.  
  57. CGFloat percent;
  58. if (translation.y > 0) {
  59. percent = translation.y / self.view.bounds.size.height;
  60. percent = MIN(percent,1.0);
  61. }
  62. else {
  63. percent = 0;
  64. }
  65.  
  66. // Swiping content view down.
  67. CGPoint center;
  68. center.x = CGRectGetMidX(self.view.bounds);
  69. center.y = CGRectGetMidY(self.view.bounds);
  70. if (translation.y > 0) {
  71. center.y += translation.y; // Only allow swiping down.
  72. }
  73. self.contentView.center = center;
  74.  
  75. self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:(0.5 * (1.0 - percent))];
  76.  
  77. [self.transitionContext updateInteractiveTransition:percent];
  78.  
  79. break;
  80. }
  81.  
  82. case UIGestureRecognizerStateEnded: // Fall through.
  83. case UIGestureRecognizerStateCancelled: {
  84. _dismissalIsInteractive = NO;
  85.  
  86. id<UIViewControllerContextTransitioning> transitionContext = self.transitionContext;
  87. self.transitionContext = nil;
  88.  
  89. DismissAnimationController * dismissAnimationController = self.dismissAnimationController;
  90. self.dismissAnimationController = nil;
  91.  
  92. CGPoint translation = [panGesture translationInView:self.view];
  93.  
  94. if (translation.y > 100) {
  95. // Complete dismissal.
  96.  
  97. [dismissAnimationController animateTransition:transitionContext];
  98. }
  99. else {
  100. // Cancel dismissal.
  101.  
  102. void (^animations)() = ^() {
  103. CGPoint center;
  104. center.x = CGRectGetMidX(self.view.bounds);
  105. center.y = CGRectGetMidY(self.view.bounds);
  106. self.contentView.center = center;
  107.  
  108. self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
  109. };
  110. void (^completion)(BOOL) = ^(BOOL finished) {
  111. [transitionContext cancelInteractiveTransition];
  112. [transitionContext completeTransition:NO];
  113. };
  114. [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaSEOut animations:animations completion:completion];
  115. }
  116.  
  117. break;
  118. }
  119.  
  120. default: {
  121.  
  122. break;
  123. }
  124. }
  125. }
  126.  
  127. // --------------------
  128.  
  129. // View Controller Interactive Transitioning Methods.
  130.  
  131. - (void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)transitionContext
  132. {
  133. self.transitionContext = transitionContext;
  134. }
  135.  
  136. @end

PresentAnimationController.h

  1. #import <Foundation/Foundation.h>
  2.  
  3. @interface PresentAnimationController : NSObject <UIViewControllerAnimatedTransitioning>
  4.  
  5. @end

PresentAnimationController.m

  1. #import "PresentAnimationController.h"
  2.  
  3. #import "ViewController2.h"
  4.  
  5. @implementation PresentAnimationController
  6.  
  7. - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
  8. {
  9. UIViewController * fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
  10. ViewController2 * toVC = (ViewController2 *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
  11.  
  12. UIView * containerView = [transitionContext containerView];
  13.  
  14. CGPoint toCenter = fromVC.view.center;
  15. CGRect toBounds = fromVC.view.bounds;
  16.  
  17. toVC.view.center = toCenter;
  18. toVC.view.bounds = toBounds;
  19. [toVC.view layoutIfNeeded];
  20.  
  21. [containerView addSubview:fromVC.view];
  22. [containerView addSubview:toVC.view];
  23.  
  24. CGRect contentViewEndFrame = toVC.contentView.frame;
  25.  
  26. CGRect contentViewStartFrame = contentViewEndFrame;
  27. contentViewStartFrame.origin.y += contentViewStartFrame.size.height;
  28. toVC.contentView.frame = contentViewStartFrame;
  29.  
  30. UIColor * endBackgroundColor = toVC.view.backgroundColor;
  31.  
  32. toVC.view.backgroundColor = [UIColor clearColor];
  33.  
  34. void (^animations)() = ^() {
  35. toVC.contentView.frame = contentViewEndFrame;
  36.  
  37. toVC.view.backgroundColor = endBackgroundColor;
  38. };
  39. void (^completion)(BOOL) = ^(BOOL finished) {
  40. toVC.view.autoresizingMask = UIViewAutoresizingNone;
  41.  
  42. toVC.view.translatesAutoresizingMaskIntoConstraints = NO;
  43.  
  44. NSLayoutConstraint * centerXConstraint = [NSLayoutConstraint constraintWithItem:toVC.view
  45. attribute:NSLayoutAttributeCenterX
  46. relatedBy:NSLayoutRelationEqual
  47. toItem:fromVC.view
  48. attribute:NSLayoutAttributeCenterX
  49. multiplier:1
  50. constant:0];
  51. NSLayoutConstraint * centerYConstraint = [NSLayoutConstraint constraintWithItem:toVC.view
  52. attribute:NSLayoutAttributeCenterY
  53. relatedBy:NSLayoutRelationEqual
  54. toItem:fromVC.view
  55. attribute:NSLayoutAttributeCenterY
  56. multiplier:1
  57. constant:0];
  58. NSLayoutConstraint * widthConstraint = [NSLayoutConstraint constraintWithItem:toVC.view
  59. attribute:NSLayoutAttributeWidth
  60. relatedBy:NSLayoutRelationEqual
  61. toItem:fromVC.view
  62. attribute:NSLayoutAttributeWidth
  63. multiplier:1
  64. constant:0];
  65. NSLayoutConstraint * heightConstraint = [NSLayoutConstraint constraintWithItem:toVC.view
  66. attribute:NSLayoutAttributeHeight
  67. relatedBy:NSLayoutRelationEqual
  68. toItem:fromVC.view
  69. attribute:NSLayoutAttributeHeight
  70. multiplier:1
  71. constant:0];
  72. [containerView addConstraint:centerXConstraint];
  73. [containerView addConstraint:centerYConstraint];
  74. [containerView addConstraint:widthConstraint];
  75. [containerView addConstraint:heightConstraint];
  76.  
  77. [transitionContext completeTransition:YES];
  78. };
  79. [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaSEOut animations:animations completion:completion];
  80. }
  81.  
  82. - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
  83. {
  84. return 0.5;
  85. }
  86.  
  87. @end

DismissAnimationController.h

  1. #import <Foundation/Foundation.h>
  2.  
  3. @interface DismissAnimationController : NSObject <UIViewControllerAnimatedTransitioning>
  4.  
  5. @end

DismissAnimationController.m

  1. #import "DismissAnimationController.h"
  2.  
  3. #import "ViewController2.h"
  4.  
  5. @implementation DismissAnimationController
  6.  
  7. - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
  8. {
  9. ViewController2 * fromVC = (ViewController2 *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
  10. UIViewController * toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
  11.  
  12. UIView * containerView = [transitionContext containerView];
  13.  
  14. [containerView addSubview:toVC.view];
  15. [containerView addSubview:fromVC.view];
  16.  
  17. void (^animations)() = ^() {
  18. CGRect contentViewEndFrame = fromVC.contentView.frame;
  19. contentViewEndFrame.origin.y = CGRectGetMaxY(fromVC.view.bounds) + 15;
  20. fromVC.contentView.frame = contentViewEndFrame;
  21.  
  22. fromVC.view.backgroundColor = [UIColor clearColor];
  23. };
  24. void (^completion)(BOOL) = ^(BOOL finished) {
  25. if ([transitionContext isInteractive]) {
  26. [transitionContext finishInteractiveTransition];
  27. }
  28.  
  29. [transitionContext completeTransition:YES];
  30. };
  31. [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:animations completion:completion];
  32. }
  33.  
  34. - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
  35. {
  36. return 0.5;
  37. }
  38.  
  39. @end

AppDelegate.m

  1. #import "AppDelegate.h"
  2.  
  3. #import "ViewController1.h"
  4.  
  5. @implementation AppDelegate
  6.  
  7. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  8. {
  9. self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  10.  
  11. ViewController1 * vc = [[ViewController1 alloc] initWithNibName:nil bundle:nil];
  12. UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:vc];
  13. self.window.rootViewController = nav;
  14.  
  15. [self.window makeKeyAndVisible];
  16. return YES;
  17. }
  18.  
  19. @end

解决方法

我想我找到了你的问题.在PresentAnimationController.m中指定toVC.view.translatesAutoresizingMaskIntoConstraints = NO;并在您设置的完成块中设置所有约束
– (void)animateTransition:

注释掉线和所有约束和addConstraint:调用它应该工作

编辑:

只是在手势被取消时才看到它有效,而不是在最初显示视图时.注释完成块中的所有内容除外

[transitionContext completeTransition:YES];

猜你在找的iOS相关文章