UIView转换导致崩溃

时间:2012-11-08 18:43:18

标签: iphone objective-c ios cocoa-touch

- (IBAction)StartGame:(id)sender
{
    MainGameDisplay *secondPage = [[MainGameDisplay alloc] initWithNibName:nil bundle:nil];

    [self.view addSubview:secondPage.view];
    secondPage.view.frame = CGRectMake(568, 0, 568, 320);//(N = horizontal, N = vertical)
    [UIView animateWithDuration:1.0f
                     animations:^{
                         //actual frame needed with an animation.
                         secondPage.view.frame = CGRectMake(0, 0, 568, 320);
                     }
                     completion:^(BOOL finished) {
                         //ENTER HERE ANYTHING TO RUN AFTER ANIMATION IS COMPLETED:
                         [self presentViewController: secondPage animated:NO completion:NULL];
                         //This will make the next page load correctly after the transition, otherwise you cannot. interact with anything.
                     }];
}

这非常适合输入视图。如果没有[self presentViewController: secondPage animated:NO completion:NULL];,则无法与新页面进行交互,您点击的任何按钮都会导致其崩溃。

如果我返回到第一页,正常进行,那很好,但是如果我再次单击StartGame,程序会更改视图然后简单地崩溃。问题在于行[self.view addSubview:secondPage.view];,如果我对此进行评论,程序不会崩溃但是当它更改视图时它不会转换并立即显示。

在横向模式中,过渡也非常滞后/不适,但在肖像方面却很完美。

3 个答案:

答案 0 :(得分:1)

此处您在currentView上添加secondPage作为子视图。再次你呈现它。 我认为它导致一些与内存相关的事情可能是其他一些事情(如果你在问题中加入一些crash log就会很清楚)。但是我建议你再也不要再提出secondPage了。这就是你的代码我在这里做了一行改变。

   - (IBAction)StartGame:(id)sender
      {
      MainGameDisplay *secondPage = [[MainGameDisplay alloc] initWithNibName:nil bundle:nil];



    [self.view addSubview:secondPage.view];
    secondPage.view.frame = CGRectMake(568, 0, 568, 320);//(N = horizontal, N = vertical)
    [UIView animateWithDuration:1.0f
                 animations:^{
                     //actual frame needed with an animation.
                     secondPage.view.frame = CGRectMake(0, 0, 568, 320);
                 }
                 completion:^(BOOL finished) {

                     //ENTER HERE ANYTHING TO RUN AFTER ANIMATION IS COMPLETED:

你应该在sinlge下面发表评论,因为你已经在currentView上添加了第二页作为子视图。所以还不需要再次呈现它。

                   //  [self presentViewController: secondPage animated:NO completion:NULL];
                     //This will make the next page load correctly after the transition, otherwise you cannot. interact with anything.
                 }];

}

编辑:对于横向模式,您应该在设置框架secondPage视图时更改坐标。我想你在这里为4英寸设备创建这个视图。 在这里你可以通过设置一些检查来做到这一点

   if(checkIfDeviceIsInlandscae)
    {
       secondPage.view.frame = CGRectMake(568, 0, 568, 320);

    } 

   else 
    {
      secondPage.view.frame = CGRectMake(320, 0, 320, 568);
    }

animation区域内,根据方向更改框架,就像我在拖车线上方所做的那样。

答案 1 :(得分:0)

一个问题是通过同时调用presentViewController:addSubview:来添加视图两次。我怀疑你发现有必要调用presentViewController:,因为它调用viewDidAppear:并且你正在使用它来连接第二页中的UI。我在MainGameDisplay的viewDidAppear:方法中放了一个日志语句,看看它什么时候被调用。

一次修复可能只是将[self presentViewController: secondPage animated:NO completion:NULL]替换为[secondPage viewDidAppear:NO]

答案 2 :(得分:0)

您的问题是内存分配/释放问题。您没有将secondPage保留在任何位置,因此在StartGame方法逻辑完成后将被取消分配。这种释放也将取消分配MainGameDisplay的ivars /属性,包括MainGameDisplay.view。这将在您开始与显示的视图交互之前发生,因此当您尝试更改值或与不再存在的视图交互时,您将崩溃并发生EXC_BAD_ACCESS错误。

如果您真的想在视图控制器之外管理MainGameDisplay.view,则需要在父类中的ivar或成员变量中保留secondPage:

<强> ParentClass.m:

@interface ParentClass ()
{
    MainGameDisplay *_secondPage;
}

@end

...

- (IBAction)StartGame:(id)sender
{
    _secondPage = [[MainGameDisplay alloc] initWithNibName:nil bundle:nil];
    [self.view addSubview:_secondPage.view];

    ...

}

但是,这通常不是推荐的设计模式。视图控制器负责管理其视图,特别是可能进行的布局更改,动画显示方式等等。您违反了MainGameDisplay的封装职责。你应该考虑在MainGameDisplay中做你需要做的任何视图管理。

我建议您阅读View Controller Programming Guide for iOS。它将解释有关您正在尝试做的事情的基本原则,以及执行此操作的最佳做​​法。