iOS 7 navigationBar重新定位后dismissViewController
我有一个嵌入导航控制器的控制器。假设我有一个重新定位self.navigationController.navigationBar的按钮。然后,我用任何控制器(不管是否导航都无关紧要)呈现ViewControllerAnimated,并在解散导航栏后返回其原始位置(实际上它在关闭动画开始时处于原始位置)。在iOS 6和更早版本中,栏不会自动重新定位。任何想法如何防止iOS 7中重新定位?iOS 7 navigationBar重新定位后dismissViewController
好的,所以我终于明白了。
首先 - 苹果不希望我们改变UINavigationBar的位置。因此,你应该不惜一切代价避免它。在我的情况下,我有一个应用程序来解决它移动UINavigationBar显示滑出菜单。滑出菜单问题的正确解决方案是将UINavigationController 放入之内 - 然后您可以将整个UINavigationController与其内容(无论它是什么内容)滑动并且一切正常。出于某种原因,UINavigationController在此应用程序之外。所以,我不得不求助于黑客。如果您有任何选择不使用此方法,请勿使用此方法。这是一个黑客攻击,它可能会在更多的iOS版本中破解,Apple肯定不会感激它。
首先,在iOS7探索新的过渡系统:http://www.doubleencore.com/2013/09/ios-7-custom-transitions/
然后,替换:
[self presentViewController:navigationController animated:YES completion:nil];
与
if([UIApplication iOS7]) /* or any other custom iOS7 detection method you implement */
{ /* we simulate old transition with nav bar slided out */
navigationController.transitioningDelegate = [OMModalTransitionDelegate new];
}
[self presentViewController:navigationController animated:YES completion:nil];
所以,我们需要一个过渡的委托来模拟标准的行为和做还有技巧。
#import "OMModalTransitionDelegate.h"
#import "OMAnimatedTransitioning.h"
@implementation OMModalTransitionDelegate
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
OMAnimatedTransitioning *transitioning = [OMAnimatedTransitioning new];
return transitioning;
}
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
OMAnimatedTransitioning *transitioning = [OMAnimatedTransitioning new];
transitioning.reverse = YES;
return transitioning;
}
@end
而现在的实际动画管理器(你有在自己UINavigationBar的一个类别来实现sharedBar):
static NSTimeInterval const DEAnimatedTransitionDuration = 0.4f;
static NSTimeInterval const DEAnimatedTransitionMarcoDuration = 0.15f;
@implementation OMAnimatedTransitioning
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *container = [transitionContext containerView];
UIView *superView = [UINavigationBar sharedBar].superview;
CGRect barFrame = [UINavigationBar sharedBar].frame;
if(self.reverse)
{ /* Trick - first, remove the bar from it's superview before animation starts */
[[UINavigationBar sharedBar] removeFromSuperview];
}
CGRect oldFrame = container.bounds;
if (self.reverse)
{
[container insertSubview:toViewController.view belowSubview:fromViewController.view];
}
else
{
toViewController.view.frame = oldFrame;
toViewController.view.transform = CGAffineTransformMakeTranslation(0, CGRectGetHeight(oldFrame));
[container addSubview:toViewController.view];
}
[UIView animateKeyframesWithDuration:DEAnimatedTransitionDuration delay:0 options:0 animations:^
{
if (self.reverse)
{
fromViewController.view.transform = CGAffineTransformMakeTranslation(0, CGRectGetHeight(oldFrame));
double delayInSeconds = 0.01; /* Trick - after an imperceivable delay - add it back - now it is immune to whatever Apple put there to move it */
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
{
[UINavigationBar sharedBar].frame = barFrame;
[superView addSubview:[UINavigationBar sharedBar]];
});
}
else
{
toViewController.view.transform = CGAffineTransformIdentity;
}
} completion:^(BOOL finished) {
[transitionContext completeTransition:finished];
}];
}
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
return DEAnimatedTransitionDuration;
}
@end
在您的自定义导航控制器,加
- (void)viewWillLayoutSubviews {
//do your navigation bar layout
}
希望这可以帮助你。提醒,以上方法只支持ios> = 5.0。
我试过,但不幸的是它不工作 – *