uiscrollview 无缝循环滚动

转载 2012年03月30日 15:24:41

最近开发一个ipad/iphone应用,要用到无缝循环滚动,网上搜了一下uiscrollview循环滚动,都是那么一个帖子转来转去,循环的时候其实没法无缝,只好自己实现一个。

头文件:

1
2
3
4
5
6
7
8
9
10
11
12
#import
 
@class ArticleViewController;
 
@interface ArticleScrollViewController : UIViewController  {
        //不使用数组,看起来更明了,为了节省内存同时还要看起来无缝,3个view最好
    ArticleViewController   *article1;
    ArticleViewController   *article2;
    ArticleViewController   *article3;
}
 
@end

实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#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
          【屏幕】

无缝循环实现了。

uiscrollview 无缝循环滚动

最近开发一个ipad/iphone应用,要用到无缝循环滚动,网上搜了一下uiscrollview循环滚动,都是那么一个帖子转来转去,循环的时候其实没法无缝,只好自己实现一个。 头文件: ...

滚动视图(UIScrollView)无限无缝左右切换图片,自动顺序加逆序循环播放图片

// // LoopView.h // Test_LoopScrollView // // Created by lanouhn on 14-8-30. // Copyright (c) 20...
  • vaercly
  • vaercly
  • 2014年08月31日 22:12
  • 1193

UIScrollview循环滚动

  • 2016年03月29日 09:22
  • 743KB
  • 下载

iOS 编程 利用UIScrollView 编写无缝循环显示图片

实现思路: 1、使用UIScrollView来显示图片 2、UIScrollView中使用三个UIImageView左中右来显示 3、UISCollView动画滚动,滚动完毕后立即把三个UIIm...

uiscrollview循环滚动

  • 2012年12月18日 17:24
  • 475KB
  • 下载

UIScrollView循环滚动

  • 2014年04月16日 15:22
  • 227KB
  • 下载

文字从上到下无缝轮播,一直循环滚动轮播

思路:无缝循环轮播,是一个轮播框(父节点)包含两个子节点,其中一个子节点是文字主体,另一个是这个子节点的复制品,即:在父类节点一定的高度下,这两个子节点实现由下而上的滚动。 贴代码前说下大家一般遇到...

循环滚动的UIscrollview

  • 2013年11月13日 13:00
  • 21.23MB
  • 下载

一个循环滚动的UIScrollView

  • 2014年07月25日 22:07
  • 114KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:uiscrollview 无缝循环滚动
举报原因:
原因补充:

(最多只允许输入30个字)