2014-01-22 77 views
0

我有一個嵌入導航控制器的控制器。假設我有一個重新定位self.navigationController.navigationBar的按鈕。然後,我用任何控制器(不管是否導航都無關緊要)呈現ViewControllerAnimated,並在解散導航欄後返回其原始位置(實際上它在關閉動畫開始時處於原始位置)。在iOS 6和更早版本中,欄不會自動重新定位。任何想法如何防止iOS 7中重新定位?iOS 7 navigationBar重新定位後dismissViewController

回答

1

好的,所以我終於明白了。

首先 - 蘋果不希望我們改變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 
0

在您的自定義導航控制器,加

- (void)viewWillLayoutSubviews { 
    //do your navigation bar layout 
} 

希望這可以幫助你。提醒,以上方法只支持ios> = 5.0。

+0

我試過,但不幸的是它不工作 – Terminus