我正在尝试使用视图模拟翻书页面。每个UIView在查看一本打开的书时会显示两页(左和右)。当页面被翻转时,应显示新的UIView。我目前的方法是使用一个自定义的UIViewController,其空白根UIView,并使页面成为子视图。当我添加一个新的子视图时,我从最后一个子视图转换到新的子视图。转换完成后,我想删除之前的最后一个子视图,因为它不再需要 - 它不再可见并占用内存。
从本质上讲,就是这样:
UIView * myOldPageView = [[self.view subviews] lastObject];
[self.view addSubview:myNewPageView];
// ... transition between the two views
[myOldPageView removeFromSuperview];
这是我最初的一次尝试,它在没有堆栈跟踪的情况下发生了神秘的崩溃。这个方法在我的自定义UIViewController中:
-(void) switchToController:(UIViewController *) controller {
[controller viewWillAppear:YES];
if (self.currentScreenController != nil) {
[self.currentScreenController viewWillDisappear:YES];
}
[self.view addSubview:[controller view]];
if (self.currentScreenController != nil) {
[[self.currentScreenController view] removeFromSuperview];
[self.currentScreenController viewDidDisappear:YES];
}
self.currentScreenController = controller;
[controller viewDidAppear:YES];
}
在此方法调用之后执行[controller release]
会导致崩溃,这很奇怪,因为保留计数大于0.如果我没有执行释放,则会出现内存泄漏。
[编辑] 这是另一种不使用控制器的方法,当从其超级视图中删除旧页面视图时崩溃:
-(void) switchToView:(UIView *) screen {
[self.view addSubview:screen];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:screen cache:NO];
[UIView commitAnimations];
if (3 < [[self.view subviews] count]) {
[[[self.view subviews] objectAtIndex:0] removeFromSuperview]; // <- crash
}
}
[编辑]即使我在添加后立即尝试删除新的子视图,我也会崩溃,没有过渡动画:
-(void) switchToView:(UIView *) screen {
[self.view addSubview:screen];
if (3 < [[self.view subviews] count]) {
[screen removeFromSuperview]; // <- crash
}
}
[编辑]我现在强烈认为问题在于解除分配添加的视图,这意味着它与动画或视图控制器无关。
答案 0 :(得分:3)
您可能需要查看UIView方法transitionFromView:toView:duration:options:completion:
使用options:
,您可以指定页面卷曲效果。
来自文档:讨论 此方法是从fromView参数中的视图转换到toView参数中的视图的简单方法。默认情况下,fromView中的视图在视图层次结构中由toView中的视图替换。如果两个视图都已经是视图层次结构的一部分,则可以在options参数中包含UIViewAnimationOptionShowHideTransitionViews选项以隐藏或显示它们。
答案 1 :(得分:0)
尝试删除您要处置的视图的removeFromSuperview。
答案 2 :(得分:0)
这只是来自文档,但我们在这里:使用NavigationController并操纵
中的数组- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
其中添加到数组的最后一项成为导航堆栈的顶部项目。来自文档:
如果启用了动画,则此方法 决定转换的类型 根据是否最后一项执行 在items数组中已经在 导航堆栈。如果是看法 控制器目前在堆栈中, 但这不是最重要的项目 方法使用pop转换;如果是 最顶层的项目,没有过渡 执行。如果视图控制器是 不在堆栈上,此方法使用a 推动转型。只有一个过渡 执行,但转移时 完成,整个内容 堆栈将替换为新视图 控制器。例如,如果 控制器A,B和C在上面 堆栈,你设置控制器D,A, 和B,这个方法使用pop 过渡和结果堆栈 包含控制器D,A和B.
即。如果您有视图控制器A和B,则创建数组
{A,B} {B,A} {一个} {B}。
并且假设您从第一页开始是A.然后您想要推送到B,将数组设置为{B},请注意:
如果视图控制器不在 堆栈,此方法使用推送 过渡。
下次将其设置为{A},依此类推,以便向前进行迭代。 现在,如果您想要从B到A的弹出过渡,请注意
如果视图控制器当前处于 堆栈,但不是最顶层的 item,此方法使用pop 过渡;
你将它设置为{B,A},反之亦然,从A到B.然后当然在动画(?)之后,只需返回{A}和{B}阵列即可返回起点 - 如果视图控制器已经是最顶层的,不执行任何转换。祝你好运;)