【问题标题】:Loop an UIScrollView [duplicate]循环 UIScrollView [重复]
【发布时间】:2024-05-03 14:35:02
【问题描述】:

可能重复:
UIScrollView. Any thoughts on implementing “infinite” scroll/zoom?

我有一个 UIScrollView 和不同的图像(大约 30 个)。我想让它成为可能,当用户到达最后一个图像以显示它之后的第一个图像时,依此类推。我想用第一张图片实现相同的功能(转到最后一张)。 我想流畅地循环图像,用户甚至不会注意到他正在制作另一个循环。

实现这一目标的最佳方法是什么?

谢谢。

【问题讨论】:

  • 更好的描述方式是圆形 (IMO)。

标签: iphone cocoa-touch


【解决方案1】:

我刚刚完成了这个。我有一个图像数组要添加到滚动视图,所以我首先将最后一个添加到滚动视图,然后遍历数组以添加所有图像,然后再次添加数组中的第一个图像。

看看这段代码:

#import "MainViewController.h"
#import "MainView.h"

#define WIDTH_OF_SCROLL_PAGE 320
#define HEIGHT_OF_SCROLL_PAGE 352
#define WIDTH_OF_IMAGE 320
#define HEIGHT_OF_IMAGE 352
#define LEFT_EDGE_OFSET 0

@implementation MainViewController

@synthesize scrollView, slideImages;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad {
    scrollView = [[UIScrollView alloc] init];
    CGRect scrollFrame;
    scrollFrame.origin.x = 0;
    scrollFrame.origin.y = 0;  
    scrollFrame.size.width = WIDTH_OF_SCROLL_PAGE;
    scrollFrame.size.height = HEIGHT_OF_SCROLL_PAGE;

    scrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
    scrollView.bounces = YES;
    scrollView.pagingEnabled = YES;
    scrollView.delegate = self;
    scrollView.userInteractionEnabled = YES;

    slideImages = [[NSMutableArray alloc] init];
    [slideImages addObject:@"welcome-small.jpg"];
    [slideImages addObject:@"football-small.jpg"];
    [slideImages addObject:@"dancing-small.jpg"];
    [slideImages addObject:@"celebration-small.jpg"];

    //add the last image first
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[slideImages objectAtIndex:([slideImages count]-1)]]];
    imageView.frame = CGRectMake(LEFT_EDGE_OFSET, 0, WIDTH_OF_IMAGE, HEIGHT_OF_IMAGE);
    [scrollView addSubview:imageView];
    [imageView release];

    for (int i = 0;i<[slideImages count];i++) {
        //loop this bit
        UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[slideImages objectAtIndex:i]]];
        imageView.frame = CGRectMake((WIDTH_OF_IMAGE * i) + LEFT_EDGE_OFSET + 320, 0, WIDTH_OF_IMAGE, HEIGHT_OF_IMAGE);
        [scrollView addSubview:imageView];
        [imageView release];
        //
    }

    //add the first image at the end
    imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[slideImages objectAtIndex:0]]];
    imageView.frame = CGRectMake((WIDTH_OF_IMAGE * ([slideImages count] + 1)) + LEFT_EDGE_OFSET, 0, WIDTH_OF_IMAGE, HEIGHT_OF_IMAGE);
    [scrollView addSubview:imageView];
    [imageView release];

    [scrollView setContentSize:CGSizeMake(WIDTH_OF_SCROLL_PAGE * ([slideImages count] + 2), HEIGHT_OF_IMAGE)];
    [scrollView setContentOffset:CGPointMake(0, 0)];
    [self.view addSubview:scrollView];
    [self.scrollView scrollRectToVisible:CGRectMake(WIDTH_OF_IMAGE,0,WIDTH_OF_IMAGE,HEIGHT_OF_IMAGE) animated:NO]; 
    [super viewDidLoad];
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    int currentPage = floor((self.scrollView.contentOffset.x - self.scrollView.frame.size.width / ([slideImages count]+2)) / self.scrollView.frame.size.width) + 1;
    if (currentPage==0) {
        //go last but 1 page
        [self.scrollView scrollRectToVisible:CGRectMake(WIDTH_OF_IMAGE * [slideImages count],0,WIDTH_OF_IMAGE,HEIGHT_OF_IMAGE) animated:NO];
    } else if (currentPage==([slideImages count]+1)) {
        [self.scrollView scrollRectToVisible:CGRectMake(WIDTH_OF_IMAGE,0,WIDTH_OF_IMAGE,HEIGHT_OF_IMAGE) animated:NO];
    }
}


- (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 {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [scrollView release];
    [slideImages release];
    [super dealloc];
}


@end

然后我使用 scrollViewDidEndDecelerating 来检查用户在滚动中的位置,然后将它们跳转到第二张图像或最后一张图像,以便他们可以连续滚动...抱歉,如果我没有很好地解释它 - 短时间!但是这段代码在我的设备上运行良好..

【讨论】:

  • 显示为:imageView.frame = CGRectMake((WIDTH_OF_IMAGE * i) + LEFT_EDGE_OFSET + 320, 0, WIDTH_OF_IMAGE, HEIGHT_OF_IMAGE); 的行应更改为:imageView.frame = CGRectMake((WIDTH_OF_IMAGE * i) + LEFT_EDGE_OFSET + WIDTH_OF_IMAGE, 0, WIDTH_OF_IMAGE, HEIGHT_OF_IMAGE);
  • 嗨克雷格!非常感谢您的代码。我正在尝试制作与此类似的东西,但是我不想拥有单个图像大小的滚动视图,而是希望在滚动视图中看到几个图像(例如 3 个)。怎么做??你能帮助我吗??谢谢
【解决方案2】:

您也可以在不分页的情况下进行无限滚动。 Here is a great explanation at WWDC

【讨论】: