自动滚动时如何使用 iCarousel 设置每个项目的显示时间
Posted
技术标签:
【中文标题】自动滚动时如何使用 iCarousel 设置每个项目的显示时间【英文标题】:How to set display time for each item using iCarousel when auto-scroll 【发布时间】:2017-01-12 02:41:44 【问题描述】:正如我的标题所示,我想知道是否有一个 iCarousel 委托方法以及属性,我可以使用它来设置自动滚动时横幅视图的每个项目的显示时间。
以前,我使用 SDCycleScrollView 作为横幅视图,并在下面这样做:
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didScrollToIndex:(NSInteger)index
BannerData *data = self.bannerDatas[index];
NSLog(@"***************cycleScrollView************************");
NSLog(@"index --> %ld", (long)index);
NSLog(@"banner data --> %@", data);
NSLog(@"banner data duration --> %d", data.duration);
cycleScrollView.autoScrollTimeInterval = data.duration;
data.duration 是每个项目保持静止的持续时间。 如何使用 iCarousel 实现这一目标?提前致谢。
到目前为止,以下是我的 iCarousel 方法:
- (NSInteger)numberOfItemsInCarousel:(__unused iCarousel *)carousel
NSLog(@">>>>>>>>>number of items in Carousel --> %lu", (unsigned long)[self.bannerDatas count]);
return (NSInteger)[self.bannerDatas count];
- (UIView *)carousel:(__unused iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 520, 375)];
NSLog(@"url --> %@", [NSURL URLWithString:[self.netImages objectAtIndex:index]]);
[((UIImageView *)view)sd_setImageWithURL:[NSURL URLWithString:[self.netImages objectAtIndex:index]] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
view.contentMode = UIViewContentModeCenter;
return view;
- (void)scrollToItemAtIndex:(NSInteger)index duration:(NSTimeInterval)duration
BannerData *data = self.bannerDatas[index];
NSLog(@"***************cycleScrollView************************");
NSLog(@"index --> %ld", (long)index);
NSLog(@"banner data --> %@", data);
NSLog(@"banner data duration --> %d", data.duration);
- (CGFloat)carousel:(__unused iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value
//customize carousel display
switch (option)
case iCarouselOptionWrap:
//normally you would hard-code this to YES or NO
return YES;
case iCarouselOptionSpacing:
//add a bit of spacing between the item views
//return value * 1.05;
case iCarouselOptionFadeMax:
// if (self.carousel.type == iCarouselTypeCustom)
//
// //set opacity based on distance from camera
// return 0.0;
//
// return value;
case iCarouselOptionShowBackfaces:
case iCarouselOptionRadius:
case iCarouselOptionAngle:
case iCarouselOptionArc:
case iCarouselOptionTilt:
case iCarouselOptionCount:
case iCarouselOptionFadeMin:
case iCarouselOptionFadeMinAlpha:
case iCarouselOptionFadeRange:
case iCarouselOptionOffsetMultiplier:
case iCarouselOptionVisibleItems:
return value;
#pragma mark -
#pragma mark iCarousel taps
- (void)carousel:(__unused iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index
BannerData *data = self.bannerDatas[index];
if (![data.playlistId isEqualToString:@""]) //Play Playlist
CategoryDetailData *detailData = [[CategoryDetailData alloc]init];
detailData.categoryId = data.playlistId;
RandomSecondVC *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"RandomSecondVC"];
vc.detailData = detailData;
NSLog(@"vc.detailData.categoryId --> %@", vc.detailData.categoryId );
vc.hidesBottomBarWhenPushed = YES; //????sanit
[self.navigationController pushViewController:vc animated:YES];
else if (![data.url isEqualToString:@""]) //Show webview
WebViewVC *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"WebViewVC"];
vc.hidesBottomBarWhenPushed = YES;
vc.navTitle = @"";
vc.urlString = data.url;
[self.navigationController pushViewController:vc animated:YES];
else if (![data.videoId isEqualToString:@""]) //Play video
VideoDetailVC *detailView = [self.storyboard instantiateViewControllerWithIdentifier:@"VideoDetailVC"];
detailView.videoId = data.videoId;
detailView.hidesBottomBarWhenPushed = YES; //????sanit
[self.navigationController pushViewController:detailView animated:YES];
下面是我放置轮播视图的方式:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *tableCell = nil;
if (indexPath.section == 0) //for banner
//++++++++++++++++++++??sanit iCarousel ver.1++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
NSLog(@"first section!!!!!!!!");
static NSString *BannerCellIdentifier = @"BannerTableViewCell"; //original
BannerTableViewCell *bannerCell = [tableView dequeueReusableCellWithIdentifier:BannerCellIdentifier]; //original
//BannerTableViewCell *bannerCell = [[BannerTableViewCell alloc]init];
[self setUpNetImages];
bannerCell.carouselView.type = iCarouselTypeCoverFlow2;
//bannerCell.carouselView.type = iCarouselTypeLinear;
//bannerCell.carouselView.autoscroll = 1; //?????sanit set autoscroll
bannerCell.carouselView.delegate = self;
bannerCell.carouselView.dataSource =self;
//??????sanit to fix banner timing issue first banner
//BannerData *data0 = self.bannerDatas[1]; //???santi
//self.cycleScrollView.autoScrollTimeInterval = data0.duration; // use this to fix timing issue of first slide
//[bannerCell.carouselView scrollToItemAtIndex:0 duration:data0.duration];
//bannerCell.carouselView.autoscroll = 0.8;
//[bannerCell.carouselView scrollToItemAtIndex:0 duration:5];
//[bannerCell.carouselView scrollToItemAtIndex:1 animated:YES];
[bannerCell.carouselView reloadData];
tableCell = bannerCell;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=//
else //for collection cell below
NSLog(@"not first section!!!!!!!! %d",(int)indexPath.section);
static NSString *MainHeaderCellIdentifier = @"MainHeaderTableViewCell";
MainHeaderTableViewCell *mainHeaderCell = (MainHeaderTableViewCell *)[tableView dequeueReusableCellWithIdentifier:MainHeaderCellIdentifier]; //original
mainHeaderCell.collectionView = (UICollectionView *)[mainHeaderCell viewWithTag:100];
mainHeaderCell.collectionView.delegate = self;
mainHeaderCell.collectionView.dataSource = self;
//NSLog(@"mainHeaderCell.index = %d",(int)mainHeaderCell.index);
//original
if (mainHeaderCell.collectionView == nil)
NSLog(@"CollectionView Nil!!!!!!!");
tableCell = mainHeaderCell;
return tableCell;
【问题讨论】:
【参考方案1】:好像 iCarousel 没有这个选项,不过幸运的是,你可以自己实现这样的功能:
@property (nonatomic, strong) NSMutableDictionary *operations;
@property (nonatomic) BOOL isDragging;
- (void) carouselDidEndScrollingAnimation:(iCarousel *)carousel
if (!self.isDragging)
NSNumber *tag = @(carousel.tag);
[self.operations[tag] cancel];
self.operations[tag] = [NSBlockOperation blockOperationWithBlock:^
double duration = [self durationForItemAtIndex:carousel.currentItemIndex inCarousel:carousel];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
NSInteger i = carousel.currentItemIndex + 1;
NSInteger next = i < carousel.numberOfItems ? i : 0;
[carousel scrollToItemAtIndex:next animated:YES];
);
];
[(NSOperation*)(self.operations[tag]) start];
- (void) carouselWillBeginDragging:(iCarousel *)carousel
[self.operations[@(carousel.tag)] cancel];
self.isDragging = YES;
- (void) carouselDidEndDragging:(iCarousel *)carousel willDecelerate: (BOOL)decelerate
self.isDragging = NO;
- (double) durationForItemAtIndex:(NSInteger)index inCarousel:(iCarousel*)carousel
return <appropriate_duration_for_particular_carousel_and_item_index_in_it>;
- (void) startCarousel:(iCarousel*)carousel
[self carouselDidEndScrollingAnimation:carousel];
更新-[tableView:cellForRowAtIndexPath:]
方法:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
<...>
if (indexPath.section == 0)
<...>
bannerCell.carouselView.tag = indexPath.row;
[self startCarousel:bannerCell.carouselView];
else
<...>
return tableCell;
并且不要忘记在使用前在某处初始化operations
字典:
self.operations = [NSMutableDictionary new];
但是,所有这些都是草稿 - 您可能需要根据需要调整和升级这些 sn-ps。
【讨论】:
谢谢,但我一直不知道如何引用我的 Carousel 视图,因为它是我的 tableview 单元格的属性。有关更多详细信息,请参阅我的 tableView cellForRowAtIndexPath。所以我不能只使用 self.carousel。 非常感谢。几乎解决了我的问题,因为我想做的一件事是获取每个项目的持续时间数据并用该值替换<appropriate_duration_for_particular_carousel_and_item_index_in_it>
。这就是我在 durationForItemAtIndex 中所做的。 BannerData *data = self.bannerDatas[index]; return data.duration;
但它崩溃了。
崩溃是这样 *** 由于未捕获的异常 'NSRangeException' 导致应用程序终止,原因:'*** -[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 4]' 那里'是 5 个项目,所以它是 0 到 4,但似乎超出了这个范围。
但我已经有了这个- (NSInteger)numberOfItemsInCarousel:(__unused iCarousel *)carousel NSLog(@">>>>>>>>>number of items in Carousel --> %lu", (unsigned long)[self.bannerDatas count]); return (NSInteger)[self.bannerDatas count];
,所以它应该知道 Carousel 应该有多少项目,对吧?
@SanitLee 你确定你不会同时在任何地方改变bannerDatas
吗? setUpNetImages
是做什么的?此外,对于每个轮播,您是否有单独的 bannerDatas
数组,或者它是唯一的?在这种情况下,所有轮播应具有相同数量的项目。以上是关于自动滚动时如何使用 iCarousel 设置每个项目的显示时间的主要内容,如果未能解决你的问题,请参考以下文章