好的..这是整个场景
概念是在屏幕上显示多个订单,用户可以向左或向右滑动以查看下一个。订单被接受或拒绝后,订单视图会向下滑动,如果订单结束,则会被旁边的订单或之前的订单替换。
我有一个标签栏视图,其中包含一个简单的UIScrollView和几个按钮(Accept& Decline)。在ViewDidLoad中,我准备了一个Orders数组,用Nib文件初始化ViewControllers(等于总命令),并将这些ViewController的视图添加到ScrollView并设置ScrollView的内容大小等。(用于垂直和水平滚动)
当用户点击AcceptButton时,会执行动画,滑动UIScrollView中的Visible View,然后将其从超级视图中删除。
动画代码执行如下。
BOOL lastPage = NO;
BOOL ordersEmpty = NO;
if (self.views.count == 1){
ordersEmpty = YES;
lastPage = YES;
}
UIViewController *controller2;
if (self.views.count == page+1 && !ordersEmpty){
lastPage = YES;
controller2 = [self.views objectAtIndex:page-1];
} else if (!ordersEmpty){
controller2 = [self.views objectAtIndex:page+1];
}
[UIView animateWithDuration:1.5 animations:^{
CGRect frame = controller.view.frame;
frame.origin.y = frame.size.height + 100;
controller.view.frame = frame;
if (lastPage == NO){
CGRect frame2 = controller2.view.frame;
frame2.origin.x = frame.origin.x;
controller2.view.frame = frame2;
}else{
// [self.scrollView scrollRectToVisible:controller2.view.frame animated:YES];
}
} completion:^(BOOL value){
[controller.view removeFromSuperview];
[self.views removeObject:controller];
totalPages.text = [NSString stringWithFormat:@"%i", self.views.count];
// currentPage.text = [NSString stringWithFormat:@"%i",
self.pageControl.numberOfPages = self.views.count;
if (lastPage && !ordersEmpty){
[self.scrollView scrollRectToVisible:controller2.view.frame animated:YES];
lastPageMoving = YES;
}else if (ordersEmpty){
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 30)];
label.text = @"There are currently no notifications";
label.textAlignment = UITextAlignmentCenter;
label.center = CGPointMake(self.scrollView.frame.size.width/2, self.scrollView.frame.size.height/3);
[self.scrollView addSubview:label];
[label release];
ofPages.text = @"";
totalPages.text = @"";
currentPage.text = @"";
self.scrollView.contentSize = CGSizeMake(320, 267);
}
int i = 0;
for (UIViewController *c in self.views)
{
c.view.frame = CGRectMake(self.scrollView.frame.size.width * i, 0, c.view.frame.size.width, c.view.frame.size.height);
i++;
}
if (controller2 != nil)
{
if ([controller2 isKindOfClass:[CancelledController class]]) {
self.acceptButton.hidden = YES;
[self.declineButton setTitle:@"Close" forState:UIControlStateNormal];
[self.declineButton setTitle:@"Close" forState:UIControlStateHighlighted];
}else{
self.acceptButton.hidden = NO;
[self.declineButton setTitle:@"Decline" forState:UIControlStateNormal];
[self.declineButton setTitle:@"Decline" forState:UIControlStateHighlighted];
}
}
}];
动画工作正常,删除的视图已取消分配
当接受最后一个视图时,应用程序在[UIView animateWithDuration:animations:completion]方法调用时与exc_bad_access完全崩溃。
NSZombies未检测到确切的泄漏点/原因..
经过广泛的研究,我认为这可能是由于使用了块...内存管理很好,因为如果我过度发布任何东西,NSZombies会指出它。
(代码在模拟器中精细化 - 不会出现任何错误)
我制作了一个视频来演示动画是如何工作的......这是模拟器所以没有错误,但是当我在设备上运行它时,应用程序会在我按下关闭按钮时崩溃。
有趣的是,如果我先关闭第二个订单并接受第一个订单,那么代码也可以正常运行=(非常令人困惑的确!!)
http://www.mediafire.com/?w1up9g9u6w0ucrn
该项目的目标是iOS 4.0
答案 0 :(得分:2)
您可以先将声明UIViewController *controller2
更改为UIViewController *controller2 = nil;
,然后最好只使用属性,所以行:
[controller.view removeFromSuperview];
[self.views removeObject:controller];
将被调用此属性的访问器方法替换,您和我们将确切地了解是否保留了ivar controller
。这适用于您正在使用的所有其他ivars:lastPageMoving
,ofPages
,totalPages
,currentPage
等。 - 只需将其更改为属性并确保其正确使用记忆管理。