iCarousel 滚动不顺畅
Posted
技术标签:
【中文标题】iCarousel 滚动不顺畅【英文标题】:iCarousel not scrolling smoothly 【发布时间】:2013-07-09 16:51:12 【问题描述】:我正在使用 iCarousel 滚动标签。在模拟器上一切正常,但在 iPad/iPhone 上滚动并不顺畅和快速
这是代码。
CitiesListView.h
#import <UIKit/UIKit.h>
#import "iCarousel.h"
@interface CitiesListView : UIView <iCarouselDataSource, iCarouselDelegate>
@property (nonatomic, retain) iCarousel *carousel;
@end
CitiesListView.m
#import "CitiesListView.h"
@interface CitiesListView ()
@property (nonatomic, retain) NSMutableArray *items;
@end
@implementation CitiesListView
@synthesize carousel;
@synthesize items;
- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
[self setUp];
return self;
- (void)setUp
carousel = [[iCarousel alloc]initWithFrame:CGRectMake(0, 0, 300, 200)];
items = [NSMutableArray arrayWithObjects:@"city1", @"city2", @"city3", @"city4", @"city5", @"city6", nil];
[self addSubview:carousel];
carousel.delegate = self;
carousel.dataSource = self;
carousel.type = iCarouselTypeRotary;
- (id)initWithCoder:(NSCoder *)aDecoder
if ((self = [super initWithCoder:aDecoder]))
[self setUp];
return self;
#pragma mark iCarousel methods
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel
return [items count];
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
UILabel *label = nil;
//create new view if no view is available for recycling
if (view == nil)
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 200.0f)];
((UIImageView *)view).image = [UIImage imageNamed:@"labelBackground.png"];
view.contentMode = UIViewContentModeCenter;
label = [[UILabel alloc] initWithFrame:view.bounds];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
label.font = [label.font fontWithSize:26];
label.tag = 1;
[view addSubview:label];
else
//get a reference to the label in the recycled view
label = (UILabel *)[view viewWithTag:1];
//set item label
//remember to always set any properties of your carousel item
//views outside of the `if (view == nil) ...` check otherwise
//you'll get weird issues with carousel item content appearing
//in the wrong place in the carousel
label.text = [items objectAtIndex:index];
return view;
- (NSUInteger)numberOfPlaceholdersInCarousel:(iCarousel *)carousel
//note: placeholder views are only displayed on some carousels if wrapping is disabled
return 2;
- (UIView *)carousel:(iCarousel *)carousel placeholderViewAtIndex:(NSUInteger)index reusingView:(UIView *)view
UILabel *label = nil;
//create new view if no view is available for recycling
if (view == nil)
//don't do anything specific to the index within
//this `if (view == nil) ...` statement because the view will be
//recycled and used with other index values later
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 200.0f)];
((UIImageView *)view).image = [UIImage imageNamed:@"labelBackground.png"];
view.contentMode = UIViewContentModeCenter;
label = [[UILabel alloc] initWithFrame:view.bounds];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
label.font = [label.font fontWithSize:50.0f];
label.tag = 1;
[view addSubview:label];
else
//get a reference to the label in the recycled view
label = (UILabel *)[view viewWithTag:1];
//set item label
//remember to always set any properties of your carousel item
//views outside of the `if (view == nil) ...` check otherwise
//you'll get weird issues with carousel item content appearing
//in the wrong place in the carousel
label.text = (index == 0)? @"[": @"]";
return view;
- (CATransform3D)carousel:(iCarousel *)_carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform
//implement 'flip3D' style carousel
transform = CATransform3DRotate(transform, M_PI / 8.0f, 0.0f, 1.0f, 0.0f);
return CATransform3DTranslate(transform, 0.0f, 0.0f, offset * carousel.itemWidth);
- (CGFloat)carousel:(iCarousel *)_carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value
//customize carousel display
switch (option)
case iCarouselOptionSpacing:
//add a bit of spacing between the item views
return value * 1.05f;
case iCarouselOptionFadeMax:
if (carousel.type == iCarouselTypeCustom)
//set opacity based on distance from camera
return 0.0f;
return value;
default:
return value;
#pragma mark iCarousel taps
- (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index
NSNumber *item = [self.items objectAtIndex:index];
NSLog(@"Tapped view number: %@", item);
@end
并在我的视图控制器 alloc/initWithFrame CitiesListView 并添加到 self.view。
我做错了什么。我需要像示例中那样平滑滚动的标签。
谢谢。
【问题讨论】:
您可能希望在 Instruments 中分析您的代码,以查看是否存在影响应用性能的特定区域。使用 Time Profiler 仪器。有关如何使用 Instruments 的更多信息,请参阅 Apple 文档:developer.apple.com/library/ios/#documentation/DeveloperTools/… 当我配置文件和使用分配工具轮播时滚动流畅。找不到问题并修复 Allocations 会告诉您内存使用情况,但 Time Profiler 会告诉您每个方法执行所需的时间。这可能有助于找出导致绘图速度变慢的原因。确保您也在设备上进行分析。 【参考方案1】:在你的 setUp
方法中,调用这个:
carousel.centerItemWhenSelected = YES;
也可以使用carousel.scrollSpeed
(值:0.0 到 1.0,默认 1.0 表示最快)来改变滚动速度。
【讨论】:
我试过 scrollSpeed 和 centerItemWhenSelected 没有帮助 你在这里做的事情是可疑的。您是否正在向图像视图添加标签?为什么不添加一个图像视图,然后将标签添加到 UIView 本身? Imageview 的布局与 UIView 不同,这可能是绘制延迟的原因。【参考方案2】:使用任何一种方法
(UIView *)carousel:(iCarousel *)carousel placeholderViewAtIndex:(NSUInteger)index reusingView:(UIView *)view(或)
(UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view【讨论】:
【参考方案3】:问题在于您试图一次将太多图像加载到内存中(视图数 x 每个视图的动画帧数)。
您需要找到一种动态加载框架的方法。试试我的 GLView 库 (https://github.com/nicklockwood/GLView),其中包含使用可以实时加载的 PVR 图像播放动画的说明。 GLView 库包含一个 GLImageView 类,它的工作方式与 UIImageView 类似,但您可以指定要播放的图像文件名数组,而不必提前加载所有图像。
【讨论】:
【参考方案4】:这可能对某人有所帮助。我遇到了类似的问题,即 iCarousel 滚动不顺畅。原来我在名为
- (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel
的方法中进行了一些繁重的验证(图像比较)
一旦我只保留了轻量级的相关验证,问题就解决了。
【讨论】:
以上是关于iCarousel 滚动不顺畅的主要内容,如果未能解决你的问题,请参考以下文章