如何在 iOS 上正确使用 Container View Controller

Posted

技术标签:

【中文标题】如何在 iOS 上正确使用 Container View Controller【英文标题】:How to use properly Container View Controller on iOS 【发布时间】:2013-04-10 20:01:03 【问题描述】:

我的应用程序有一个父视图控制器(MainViewController.h/m - UIViewController,没有 NIB 文件)用于所有其他 UIViewController,它同时是 RootViewController。

我的应用应该支持 ios 5,所以 AutoLayout 关闭了..

继承一些代码:

在 AppDelegate.m 中

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.mainViewController = [[MainViewController alloc] init];
    [self.window setRootViewController:self.mainViewController];
    [self.window makeKeyAndVisible];
    return YES;

在 MainViewController.m 中

- (void)viewDidLoad 
    [super viewDidLoad];
// Do any additional setup after loading the view.


    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) 

        if ([[UIScreen mainScreen] bounds].size.height == 568) 
            _homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController~iPhone5" bundle:nil];
         else 
            _homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController~iPhone" bundle:nil];
        
     else 
        _homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
    


    [self addChildViewController:_homeViewController];
    [self.view addSubview:_homeViewController.view];
    [_homeViewController didMoveToParentViewController:self];


- (void)changeFromViewController:(UIViewController*)fromViewController toViewController:(UIViewController*)toViewController withDuration:(NSNumber*)duration 

    toViewController.view.frame = self.view.bounds;
    [toViewController.view layoutIfNeeded];

    [self addChildViewController:toViewController];
    [self transitionFromViewController:fromViewController
                      toViewController:toViewController
                              duration:[duration floatValue]
                               options:UIViewAnimationOptionTransitionCrossDissolve
                            animations:nil
                            completion:^(BOOL finished) 

                                [toViewController didMoveToParentViewController:self];

                                [fromViewController willMoveToParentViewController:nil];
                                [fromViewController removeFromParentViewController];
                            ];

HomeViewController*.xib 包含 7 个 UIButton。如果其中一个触及 MainViewController 类被调用以从一个 ChildViewController(HomeViewController, etc..) 更改为另一个。

HomeViewController.m

- (IBAction)firstButton_click:(id)sender 

    [(MainViewController *)self.parentViewController setAnimationForChangeFrom:self toStartTestSettingsViewControllerWithDuration:[NSNumber numberWithDouble:0.4] andWithDelay:[NSNumber numberWithDouble:0.1]];

现在关于问题。

在 iOS 6 及更高版本的 iPhone(设备或模拟器)上,UIButton 仅在多次触摸后才会响应。放置在视图底部的按钮要工作,必须触摸更多次,然后放置在顶部的按钮。几次触摸后,当事件触发并更改视图时,当我回到此视图时,一切正常。我只有 iPhone iOS 6.x 才有这个问题。它可以在 iPhone iOS 5.x 和 iPad 5.x-6.x 上正常运行。

如果我将 HomeViewController 设为 RootViewController,按钮当然会响应事件。但是我无法使用 UIViewAnimationOptionTransitionCrossDissolve Animation[[UIViewController transitionFromViewController:toViewController:duration:options:animations:completion:] 进行转换,因为视图必须具有相同的父视图控制器。 我做错了什么?是虫子吗?有什么解决办法吗? 任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

将其写入 .pch 文件中

#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )


- (void)viewDidLoad 
[super viewDidLoad];
// Do any additional setup after loading the view.



if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) 

    if (IS_IPHONE_5) 
        _homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController~iPhone5" bundle:nil];
     else 
        _homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController~iPhone" bundle:nil];
    
 else 
    _homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];



[self addChildViewController:_homeViewController];
[self.view addSubview:_homeViewController.view];

【讨论】:

【参考方案2】:

问题是因为 [_homeViewController didMoveToParentViewController:self];。 这是多余的。

MainViewController 中的 ViewDidLoad 应该是:

- (void)viewDidLoad 
    [super viewDidLoad];
// Do any additional setup after loading the view.


    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) 

        if ([[UIScreen mainScreen] bounds].size.height == 568) 
            _homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController~iPhone5" bundle:nil];
         else 
            _homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController~iPhone" bundle:nil];
        
     else 
        _homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
    


    [self addChildViewController:_homeViewController];
    [self.view addSubview:_homeViewController.view];

现在一切正常..

【讨论】:

以上是关于如何在 iOS 上正确使用 Container View Controller的主要内容,如果未能解决你的问题,请参考以下文章

vuetify.js 如何获得 v-container 的全宽

Nuxt 如何在数组上循环并使用 v-for 正确显示数据

v-lazy-container图片加载失败

Cordova 应用程序无法在 iOS 设备上正确显示

如何在 vue+ts 中正确注册组件?

Spring Docker Container 停止,因为它尝试连接到 localhost MongoDB,即使它已经正确连接到 MongoDB Container