循环播放视图

头文件:

#import 

@class ArticleViewController;

@interface ArticleScrollViewController : UIViewController  {
        //不使用数组,看起来更明了,为了节省内存同时还要看起来无缝,3个view最好
	ArticleViewController	*article1;
	ArticleViewController	*article2;
	ArticleViewController	*article3;
}

@end

实现:

#import "ArticleScrollViewController.h"
#import "ArticleViewController.h"
#import "ViewSwitcher.h"
@implementation ArticleScrollViewController

// vieDidLoad函数不重要,只要初始化了三个view并放在uiscrollview里面,正确设定uiscrollview的content size就行了
- (void)viewDidLoad {
    [super viewDidLoad];

    UIScrollView *scrollView = (UIScrollView *)self.view;
    scrollView.contentSize = CGSizeMake(self.view.frame.size.width*3, self.view.frame.size.height);
    CGRect frame = self.view.frame;
    frame.origin.y = 0.0f;
    NSInteger article2Index = [ViewSwitcher getInstance].currentArticleIndex;
    NSInteger article1Index = article2Index - 1;
    article1Index = article1Index < 0 ? [ViewSwitcher getInstance].articleCount - 1 : article1Index;
    article1Index = article1Index >= [ViewSwitcher getInstance].articleCount ? 0 : article1Index;
    NSInteger article3Index = article2Index + 1;
    article3Index = article3Index < 0 ? [ViewSwitcher getInstance].articleCount - 1 : article3Index;
    article3Index = article3Index >= [ViewSwitcher getInstance].articleCount ? 0 : article3Index;

    article1 = [[ArticleViewController alloc] initWithArticleIndex:article1Index];
    [article1.view setFrame:frame];

    article2 = [[ArticleViewController alloc] initWithArticleIndex:article2Index];
    frame.origin.x += self.view.frame.size.width;
    [article2.view setFrame:frame];

    article3 = [[ArticleViewController alloc] initWithArticleIndex:article3Index];
    frame.origin.x += self.view.frame.size.width;
    [article3.view setFrame:frame];

    [scrollView addSubview:article1.view];
    [scrollView addSubview:article2.view];
    [scrollView addSubview:article3.view];

    CGPoint p = CGPointZero;
    p.x = scrollView.frame.size.width;
    [scrollView setContentOffset:p animated:NO];
    [article2 reloadData];
}
#pragma mark -
#pragma mark UIScrollViewDelegate

#define SET_FRAME(ARTICLEX) x = ARTICLEX.view.frame.origin.x + increase;                            if(x < 0) x = pageWidth * 2;                            if(x > pageWidth * 2) x = 0.0f;                            [ARTICLEX.view setFrame:CGRectMake(x,                                 ARTICLEX.view.frame.origin.y,                                ARTICLEX.view.frame.size.width,                                ARTICLEX.view.frame.size.height)]
//将三个view都向右移动,并更新三个指针的指向,article2永远指向当前显示的view,article1是左边的,article3是右边的
- (void)allArticlesMoveRight:(CGFloat)pageWidth {
    //上一篇
    article3.articleIndex = article1.articleIndex - 1;
    if (article3.articleIndex < 0) {
        article3.articleIndex = [ViewSwitcher getInstance].articleCount - 1;
    }
    [article1 reloadData];
    ArticleViewController *tmpArticleViewController = article3;
    article3 = article2;
    article2 = article1;
    article1 = tmpArticleViewController;

    float increase = pageWidth;
    CGFloat x = 0.0f;
    SET_FRAME(article3);
    SET_FRAME(article1);
    SET_FRAME(article2);
}
- (void)allArticlesMoveLeft:(CGFloat)pageWidth {
    article1.articleIndex = article3.articleIndex + 1;
    if (article1.articleIndex >= [ViewSwitcher getInstance].articleCount) {
        article1.articleIndex = 0;
    }
    [article3 reloadData];//[article2 resetView];[article3 resetView];
    ArticleViewController *tmpArticleViewController = article1;
    article1 = article2;
    article2 = article3;
    article3 = tmpArticleViewController;

    float increase = -pageWidth;
    CGFloat x = 0.0f;
    SET_FRAME(article2);
    SET_FRAME(article3);
    SET_FRAME(article1);
}
/*
 循环滚动
 每次滚动后都将scrollview的offset设置为中间的一页
 若本次滚动是向前一页滚动,则把三页都向后放置,最后一页放到开头
 若本次滚动是向后一页滚动,则把三页都向前放置,第一页放到末尾
 */
- (void)scrollViewDidEndDecelerating:(UIScrollView *)theScrollView
{
    CGFloat pageWidth = theScrollView.frame.size.width;
    // 0 1 2
    int page = floor((theScrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
    if(page == 1) {
        //用户拖动了,但是滚动事件没有生效
        return;
    } else if (page == 0) {
        [self allArticlesMoveRight:pageWidth];
    } else {
        [self allArticlesMoveLeft:pageWidth];
    }
    CGPoint p = CGPointZero;
    p.x = pageWidth;
    [theScrollView setContentOffset:p animated:NO];
    [article1 resetView];
    [article3 resetView];
}
#pragma mark -
#pragma mark dealloc
- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn‘t have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc. that aren‘t in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    [article1    release];article1 = nil;
    [article2    release];article2 = nil;
    [article3    release];article3 = nil;
}

- (void)dealloc {
    [article1    release];
    [article2    release];
    [article3    release];
    [super dealloc];
}

@end

这里的雕虫小技主要在于:

以手指向右拖动为例,【屏幕】指的是scorllview的显示区域

  article1 article2 article3
           【屏幕】

拖动以后成这样:

 article1 article2 article3
【屏幕】

将article3放到第一个去(设定article3的frame),这是屏幕还显示的是article1的内容
article3 article1 article2
【屏幕】

将屏幕移到中间:使用setContentOffset,禁用动画,这样骗过人眼

article3 article1 article2
          【屏幕】

最后更新指针顺序:

article1 article2 article3
          【屏幕】

无缝循环实现了。

时间: 2024-12-11 10:03:50

循环播放视图的相关文章

iOS - 视频循环播放

录制完视频后,我们想在录制视频的预览层上无限循环播放我们的小视频,是不是很炫酷,这时候我们就有三中选择了:1.MPMoviePlayerController2.AVPlayer3.AVAssetReader+AVAssetReaderTrackOutput 但是我们这个预览层是自定义的喔,所以MPMoviePlayerController只能马上给筛选掉了,所以用,那么我们就要用到 AVPlayer 了,虽然上 AVPlayer 最多只能创建16个,性能上不及用 AVAssetReader+AV

React Native scrollview 循环播放

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #008400 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 18.0px; font: 12.0px Menlo; color: #d4d4d4; min-height: 14.0px } p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px He

循环播放音乐

./a.out . 表示循环播放当前目录下的音乐 #include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<dirent.h>#include<string.h> int main(int argc,char *argv[]){ DIR *dir; struct dirent *ent; char str[32][128]; char str1[128]; char str2[12

iOS scrollview循环播放加缩放

前些日子一直在研究3d的框架没有时间写博客,不过最后需求改了,也没研究出个啥.这段时间出了新的需求,需要循环播放图片,并且滑动的时候中间的图片有缩放的效果.刚开始想在网上搜索,不过并没有找到合适的demo,没办法只能写个了. 首先说下思路,做这个效果需要解决三个问题. 第一个问题,如何控制每次滑动的距离.iOS中好像并没有设置scrollview每次滑动的距离吧.设置其画框的大小和pageenable的时候已经决定了其每次滑动的距离.但是需求要显示三张图片啊,中间大图,两边的图片只显示一部分.也

一种实现无缝循环播放音乐方案

场景: 为了节省页面资源,往往需要将一段小音频循环播放,通常做法是在audio标签上添加loop属性,但不幸的是,该属性并不能保证无缝循环(gapless looping)播放,明显的感觉到中间的停顿. 解决方案: 使用audio标签的Web API提供的方法和属性进行循环播放,具体如下 事件名称 事件作用 timeupdate 当前播放的时长发生改变时触发     属性名称 属性作用 currentTime                 用来获取或控制当前播放的时间,单位为s duratio

JS可控制的图片自动循环播放查看效果

JS可控制的图片自动循环播放查看效果 <html> <head> <title>JS可控制的图片自动循环播放查看效果丨芯晴网页特效丨CsrCode.Cn</title> </head> <body> <SCRIPT LANGUAGE="JavaScript"> <!-- Begin var rotate_delay = 5000; // delay in milliseconds (5000 =

循环播放

该循环播放用到了jquery,所以在head标签里边应该加入: <script type="text/JavaScript" src="js/jQuery-3.2.1.min.js"></script> 以下是详细代码: html代码 1 <div id="lunbobox"> 2 <div class="lunbo"> 3 <a href="#">

Wpf中MediaElement循环播放

原文:Wpf中MediaElement循环播放 前一段时间做了一个项目,里面牵涉到媒体文件的循环播放问题,在网上看了好多例子,都是在xaml中添加为MediaElement添加一个TimeLine,不符合我的项目需求,就自己想了一个办法,基本的思路就是在媒体播放完毕后再次Play一下就OK了,废话不多说,首先Show一下我的代码吧: 写一个方法用来动态创建一个MediaElement:这里的ScreenModel是我创建的一个类,大家根据需要可以修改 MediaElement MediaElem

最简单的方法实现MIDI音乐循环播放 (不用在MCI回调中处理)

前几天,需要在一个Delphi小程序中需要循环播放一段midi音乐.为什么不是mp3或wav或其它?因为midi格式体积小.(总之我有我的必然理由,多喷无义意) 播放功能选择使用MMSystem中的mciSendString函数来实现,注意到"OPEN"操作时需要指定媒体类型为"TYPE SEQUENCER"(就是指midi音频),接下来使用"PLAY XXREPEAT"操作希望能循环播放,结果不但没有实现循环,而且音乐根本就不播放.详查MSDN