cocoa-touch - 未调用 UINavigationControllerDelegate 方法(github 上的演示代码)

标签 cocoa-touch delegates uinavigationcontroller

弹出到不支持当前方向的 View Controller 时,未调用 UINavigationControllerDelegate 方法。

我有一个 UINavigationController 作为我的应用程序的 Root View Controller (我的 Storyboard中的初始 View Controller )。

假设我用这个来推送一个 ViewController A 来定位:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

因此我们不支持任何横向模式。最重要的是,让我们用代码推送另一个 ViewController:
@interface B : UIViewController <UINavigationControllerDelegate>
@end

@implementation B
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;   // any orientation supported
}

- (void)viewDidLoad {
    [super viewDidLoad];

    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    UINavigationController *nc = (UINavigationController*)appDelegate.window.rootViewController;
    nc.delegate = self;
}

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    // not always called...
}

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    // not always called...
}
@end

现在,如果我的 iPhone 是纵向的,我通过一些触摸事件将 View Controller B 推到 A 上,然后触摸导航栏中的“后退”按钮,一切都很好,并且调用了委托(delegate)方法(我在那里做了一些事情)。

但是,如果当我查看 View B 时,我旋转到横向,然后点击后退按钮,则不会调用这些委托(delegate)方法!如果有时调用方法但不调用其他方法,那么为 UINavigationController 设置委托(delegate)有什么意义?我肯定做错了什么。

我尝试将委托(delegate)放在其他类中,例如 AppDelegate 或我的 MainView,没有任何变化。

有任何想法吗 ?

演示代码: git://github.com/malaba/NavBarTest.git

从一个基本的主从模板,如上修改。

如何表明我的观点?这是一步一步:
  • 在主视图中添加一些行(+ 右上角)
  • 然后触摸一条线进入详细信息 View
  • 请参阅显示的登录输出
  • 点击返回按钮(标记为“Master”),再次显示日志。

  • 现在尝试在细节 View 中旋转 iPhone(或模拟器),然后“返回”并查看 没有日志出现?!

    最佳答案

    嗨,这对我来说也是一个棘手的问题,直到我看到这个想法:http://www.hanspinckaers.com/custom-action-on-back-button-uinavigationcontroller

    当 NavigationController 和 TopViewController 具有相同的方向时,IOS 使用以下代码创建以下调用序列(单点触控)

  • SomeTopViewController ViewWillDisappear
  • WillShowViewController viewController:新的 TopViewController
  • SomeTopViewController ViewDidDisappear
  • DidShowViewController viewController:新的 TopViewController

  • 当 NavigationController 和 TopViewController 有 不同方向然后 NavigationController 委托(delegate)是 不是 如你所描述的那样调用。因此调用顺序为:
  • SomeTopViewController ViewWillDisappear
  • SomeTopViewController ViewDidDisappear

  • 以下代码通过覆盖 NavigationController 的 PopViewControllerAnimated 来重现 ios 调用序列:
    public class MyNavigationControllerDelegate : UINavigationControllerDelegate {
      public MyNavigationControllerDelegate( ) : base() {}
    
      public bool WasCalled {get;set;}  // flag that we use to track whether iOS calls the handlers or we have to 
    
      public override void WillShowViewController( UINavigationController navigationController, UIViewController viewController, bool animated ) {
        Console.WriteLine( "WillShowViewController viewController: {0}", viewController.GetType() );
        WasCalled = true;  // signal that we have been called
        //.….. do your stuff
      }
    
      public override void DidShowViewController( UINavigationController navigationController, UIViewController viewController, bool animated ) {
        Console.WriteLine( "DidShowViewController viewController: {0}", viewController.GetType() );
        //.….. do your stuff
      }
    }
    
    public partial class MyNavigationController : UINavigationController {
      MyNavigationControllerDelegate navigationControllerDelegate;
    
      public override void ViewDidLoad() {
        base.ViewDidLoad();
        navigationControllerDelegate = new MyNavigationControllerDelegate( viewSelectionControl );
        Delegate = navigationControllerDelegate;
      }
    
    public override UIViewController PopViewControllerAnimated( bool animated ) {
      Console.WriteLine( "PopViewControllerAnimated TopViewController.GetType: {0}", TopViewController.GetType() );
      navigationControllerDelegate.WasCalled = false;   // reset flag before we start the popsequence
    
      UIViewController ctrl = base.PopViewControllerAnimated( animated );
    
      AppDelegate.MainWindow.BeginInvokeOnMainThread( delegate {
        if( !navigationControllerDelegate.WasCalled )  {   // if iOS did not call the delegate handler then we must do it
          Delegate.WillShowViewController( this, TopViewController, animated );
          navigationControllerDelegate.WasCalled = false;  // reset flag to be used in the next DidShowViewController step of the popsequence
          }
      } );
    
      Thread t = new Thread( () => RunPop(animated) );
      tt.Start();
    
      return ctrl;
    }
    
    void RunPop(bool animated) {
      Thread.Sleep( 500 );
      AppDelegate.MainWindow.BeginInvokeOnMainThread( delegate {
        if( !navigationControllerDelegate.WasCalled ) {  // if iOS did not call the delegate handler then we must do it
          Delegate.DidShowViewController(this,TopViewController,animated);
        }
      } );
    }
    

    }

    关于cocoa-touch - 未调用 UINavigationControllerDelegate 方法(github 上的演示代码),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10301973/

    相关文章:

    ios - 当用户更改联系人访问权限时,iOS 6 中的应用程序崩溃

    ios - 如何在 Swift 中获取 UIScrollView 垂直方向?

    c# - 性能——FunctionCall vs Event vs Action vs Delegate

    c# - 委托(delegate)变量未被垃圾收集

    ios - UIScrollView动态状态栏

    ios - NSJSON 序列化错误?

    iphone - 如何使用 Sharekit 检索 Twitter 用户名

    ios - Swift - 使用委托(delegate)传递变量

    ios - UIToolbar 项目未显示在弹出窗口中

    swift - 在使用 Swift 创建新条目两个 View Controller 后返回原始详细信息 View Controller