`
zl4393753
  • 浏览: 340189 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Infinite UIScrollView

 
阅读更多
Infinite UIScrollView

http://www.touchwonders.com/infinite-scrolling-messing-with-uiscrollview/

头文件:
#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
          【屏幕】
无缝循环实现了。
分享到:
评论

相关推荐

    UIScrollView-InfiniteScroll:UIScrollView∞滚动类别

    UIScrollView + InfiniteScroll 无限滚动实现作为UIScrollView的类别。 *演示应用程序中使用的内容是公开可用的,并由hn.algolia.com和Flickr提供。 两者都是不合适的。 izz 请注意,此类别UIScrollView上的...

    uiscrollview uitableview上拉刷新

    上拉加载更多,也称为 "infinite scrolling" 或 "load more",需要开发者自己实现。通常,我们监听 `UITableView` 的 `scrollViewDidScroll` 方法,当用户滚动到接近底部时,启动加载更多数据的逻辑。以下是一个基本...

    ios UIScrollView 使用例子

    6. **Infinite Scrolling**: 如果你想实现无限滚动的效果,可以在用户接近ScrollView边缘时动态加载并添加新的图片视图。这通常需要结合委托方法`scrollViewWillEndDragging:withVelocity:targetContentOffset:`来...

    DMCircularScrollView:UIScrollView的InfiniteCircular滚动实现

    UIScrollView的无限/圆形滚动实现DMCircularScrollView实现infinite。 在为您的应用创建分页功能时,有时可能需要无限的页面循环。 例如,如果您要显示的是一个很小的照片库,则可能需要在整个场景中滑动,并在到达...

    ios-scrollview 自动轮播.zip

    这可能包括设置轮播间隔时间(interval)、是否启用无限循环(infiniteLoop)等。 为了实现自动轮播,CJScrollRollView内部可能使用了NSTimer或者CADisplayLink来定期更新contentOffset,模拟出图片平滑滚动的效果...

    无限轮播iOS

    在iOS开发中,无限轮播(Infinite Carousel)是一种常见的用户界面元素,它允许用户在一组视图或图片之间滑动,形成一个无边界、循环的效果。这种设计常见于应用的启动页、广告轮播、商品展示等场景,能够提供流畅的...

    IOS应用源码之2_Autoscroll_2.zip

    8. **Infinite Scrolling**: 通过巧妙的数据加载和视图管理,实现看似无边界的滚动效果,常用于新闻或社交媒体应用。 9. **Scroll Events**: 了解如何监听和响应滚动事件,如scrollViewDidScroll、...

    IOS应用源码——从上往下拉动态加载3.zip

    这种技术通常被称为下拉刷新(Pull-to-Refresh)或者无限滚动(Infinite Scrolling)。在这个名为"IOS应用源码——从上往下拉动态加载3.zip"的压缩包中,很可能包含了一个实现这一功能的示例项目,旨在帮助开发者...

    ios swift 上拉加载、下拉刷新数据

    本教程将深入探讨如何在Swift中实现上拉加载(infinite scrolling)和下拉刷新(pull-to-refresh)功能,尤其关注如何将这些功能集成到继承自UIScrollView的控件,如UITableView和UICollectionView。 首先,下拉...

    ios 上拉刷新

    上拉加载更多的功能也称为“Infinite Scrolling”。与下拉刷新不同,iOS SDK并没有提供内置的组件来实现这一功能。我们需要监听`UITableView`的滚动事件,当用户滚动到底部时,触发加载更多数据的逻辑。 ```swift ...

    scrollAdColumn

    2. **无限循环(Infinite Loop)**:此组件的亮点在于其无限循环功能,意味着当用户滑动到最后一个广告后,广告栏会无缝地回到第一个广告,提供不间断的用户体验,增加了广告的曝光率。 3. **UIScrollView**:苹果...

    ios-Swift广告弹窗.zip

    4. **无限循环Banner视图(Infinite Looping Banner)**: 这个特性使广告能够在用户停止操作后自动循环播放,提高广告曝光率。在iOS中,这可以通过设置`UIScrollView`的contentSize和`CADisplayLink`或`NSTimer`来...

    swift-SwiftPullToRefresh一种简单的方法来实现下拉式刷新和上拉式加载功能

    上拉加载(Infinite Scrolling或Load More)则允许用户滚动到底部时加载更多数据。这两种交互方式提高了用户体验,让用户无需离开当前界面就能获取最新或更多内容。 SwiftPullToRefresh的实现原理主要基于以下几点...

    从上往下拉动态加载.zipIOS应用例子源码下载

    在iOS开发中,这种功能通常被称为"下拉刷新"或"Infinite Scrolling",是移动应用中常见的用户体验设计,用于在用户滚动到列表底部时加载更多数据。下面我们将深入探讨这一技术的实现原理、相关知识点以及可能的应用...

    InfiniteScrollView:演示版

    在Objective-C编程语言中,Infinite ScrollView 的实现通常基于UIScrollView,这是iOS SDK中用于显示可滚动内容的基础组件。开发者需要利用UIScrollView的代理方法(如`scrollViewDidScroll:`)来监听滚动事件,并...

    仿今日头条的滑动切换条目

    首先,滑动切换条目的核心是滑动视图(Swipe View)或无限滚动(Infinite Scroll)。这种效果通常通过组合滚动视图组件和数据加载策略来实现。在Android开发中,我们可以使用`ViewPager`或者`RecyclerView`配合`...

    ios-刷新控件.zip

    实现这些功能,开发者需要熟悉Swift或Objective-C编程语言,理解UITableView和UICollectionView的生命周期以及数据源方法,掌握UIScrollView的滚动事件处理,以及可能涉及到的动画操作。"ios-刷新控件.zip"中的示例...

    ios-XLsn0wLoop.zip

    1. **无线轮播(Infinite Carousel)**:无线轮播是一种常见的UI设计,用户可以无限制地左右滑动查看内容,当滑到最后一个项目时,它会无缝地跳转回第一个项目,反之亦然,营造出一种无限循环的效果。这种设计在应用...

    ios-swift 简单下拉刷新,上拉加载更多.zip

    func scrollViewDidScroll(_ scrollView: UIScrollView) { if scrollView.contentOffset.y &gt;= (scrollView.contentSize.height - scrollView.frame.size.height) && hasMoreData { loadMoreData() } } ``` `load...

    pull-to-refresh:#忙于重新构建....#一种在Swift中使用pull刷新和无限滚动的简单方法。 Pod“ ESPullToRefresh”

    通过扩展UIScrollView,您可以轻松地为UIScrollView的任何子类添加“上拉刷新”和“无限滚动”。 如果要自定义其UI样式,只需遵循指定的协议。要求Xcode 8或更高版本iOS 8.0或更高版本弧Swift 5.0或更高版本产品...

Global site tag (gtag.js) - Google Analytics