我正在制作的iPad应用程序是一本书。要跳转到特定页面,用户可以按下覆盖当前视图顶部视图的按钮,显示书中每个页面的缩略图图像。
当用户按顺序浏览书籍并显示此缩略图菜单时,如果用户显示菜单,则滚动动画平滑且精细。如果用户在加载了大约15页之后调用showBookmarkMenu
,滚动视图动画非常慢,并且滚动视图不再捕获触摸,则会出现问题。
我注意到当滚动动画正常且平滑(加载应用程序后不久)时会调用scrollViewDidEndDecelerating
,但在用户经过多个页面后不会调用它。因此,一个假设是CPU正在努力研究scrollview内容定位的动画。我使用Instruments的Activity Monitor运行应用程序,但有时候应用程序使用97%以上的CPU并且滚动视图滚动得很好......
关于这个问题的任何想法?我在下面发布了我的代码。
MainClass.m
//Called when user presses the open/close bookmark menu button
-(IBAction)toggleBookmarksMenu{
if([bookMarkMenu isHidden]){
[currentPage.view addSubview:bookMarkMenu];
[bookMarkMenu showBookmarkMenu];
}
else{
[bookMarkMenu hideBookmarksMenu];
}
}
ScrollViewClass.h
@interface BookmarkManager : UIView<UIScrollViewDelegate>{
UIScrollView *thumbnailScrollView;
}
@property (strong, nonatomic) UIScrollView *thumbnailScrollView;
@property (strong) id <BookmarkManagerDelegate> bookmarkManagerDelegate;
-(void)showBookmarkMenu;
-(void)hideBookmarksMenu;
@end
ScrollViewClass.m
-(void)showBookmarkMenu{
[self setHidden:NO];
[UIView animateWithDuration:0.5
animations:^{
self.center = CGPointMake(512, 384);
}
];
}
-(void)hideBookmarksMenu{
[UIView animateWithDuration:1
animations:^{
self.center = CGPointMake(512, -120);
}
completion:^(BOOL finished){
[self setHidden:YES];
[self removeFromSuperview];
}
];
}
-(id)init{
self = [super initWithFrame:CGRectMake(0, 0, 1024, 768)];
if(self){
[self setBackgroundColor:[UIColor clearColor]];
self.center = CGPointMake(512, 0);
thumbnailScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 1024, 120)];
[thumbnailScrollView setBackgroundColor:[UIColor clearColor]];
thumbnailScrollView.showsHorizontalScrollIndicator = NO;
//Add the UIButtons with images of the thumbnails
for(int i = 0; i < totalPages; i++){
UIButton *pageThumbnail = [UIButton buttonWithType:UIButtonTypeCustom];
pageThumbnail.frame = CGRectMake(0, 0, 125, 95);
[pageThumbnail setBackgroundImage:[UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/p%d_thumb.png", [[NSBundle mainBundle] resourcePath], i]] forState:UIControlStateNormal];
[thumbnailScrollView addSubview:pageThumbnail];
[pageThumbnail addTarget:self action:@selector(thumbnailTapped:) forControlEvents:UIControlEventTouchDown];
}
[self addSubview:thumbnailScrollView];
[thumbnailScrollView setContentSize:CGSizeMake(totalPages * 125 + (20*(totalPages+1)), 120)];
[thumbnailScrollView setDelegate:self];
[self setHidden:YES];
}
return self;
}
答案 0 :(得分:1)
在黑暗中拍摄,基于您观察到在加载15页左右后滚动变慢:可能您的设备正在忙于处理低内存条件。在这种情况下,您可能知道,系统范围的通知会发送到相当数量的应用程序/对象,以便他们尽可能多地恢复内存。
您是否可以在滚动速度变慢的同时检查您的应用正在执行didReceiveMemoryWarning
?
如果您确认问题可能与内存饱和/回收有关,那么我建议您为图片实施延迟加载方案:
您只需在需要显示图片时加载图片;
您只需保存3-5张图片,以确保滚动顺畅。
基本步骤需要id提供您的代表
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
实现。在这里,您将预加载图像:
了解您的位置,您知道当前的图像(例如图像编号N);
卸载图像N-2,N + 2;
加载图片N-1,N + 1。
如果您只想要一个“缓冲”图像,我提供的加载/卸载图像就可以了。
无论如何,如果你google“iso scroll view lazy loading”你会发现很多信息。
答案 1 :(得分:1)
我必须考虑可能的低内存问题。
使用大量按钮的另一种可能方法是使用UITableView。代码当前的工作方式,它会将所有按钮加载到图像中。对于一本大书,这可能很痛苦。
使用UITableView只能使用你所看到的内存(约)。并且,由于每个图像都是动态加载的,因此您的内存使用量仅与显示的一样多。这就是我要去做的事情(实际上,我现在正在这样做,而不是一本书)。
答案 2 :(得分:0)
原来这不是一个低内存问题,而是一个过于繁忙的CPU问题。
CPU执行滚动视图滚动动画所需的计算,当滚动变慢时,我想我会试着找出为什么我首先使用97%的CPU。事实证明,在过去的第15页,我有无限循环捕获的CPU密集型递归函数(为应用程序的另一部分计算UIBezierPaths)。该应用程序每秒计算数百个UIBezierPaths,并且达到了CPU无法跟上scrollview动画的计算的程度。
一旦我确定递归函数在不需要时停止调用自身,整个应用程序的CPU使用率仍然低于20%,并且滚动视图表现非常好。