首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS UIScrollView 批量圖片展示:從數組到無限輪播的完整實現

     編輯:程式設計綜合問答

基礎實現:垂直堆疊模式

適用於圖片數量固定、無需複雜交互的場景(如詳情頁圖集)。

- (void)setupImageScrollViewWithImages:(NSArray *)images {
    // 1. 配置 ScrollView
    self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.scrollView.showsVerticalScrollIndicator = NO;
    self.scrollView.delegate = self;
    [self.view addSubview:self.scrollView];
    
    // 2. 批量添加 UIImageView
    CGFloat yOffset = 0;
    const CGFloat padding = 8.0f;
    const CGFloat imageWidth = self.view.bounds.size.width - 2 * padding;
    
    for (UIImage *image in images) {
        // 等比縮放計算高度
        CGFloat aspectRatio = image.size.height / image.size.width;
        CGFloat imageHeight = imageWidth * aspectRatio;
        
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:
            CGRectMake(padding, yOffset + padding, imageWidth, imageHeight)];
        imageView.image = image;
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        imageView.clipsToBounds = YES;
        [self.scrollView addSubview:imageView];
        
        yOffset += imageHeight + padding;
    }
    
    // 3. 設置 contentSize 啟用滾動
    self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, yOffset + padding);
}

進階方案:水平無限輪播

核心原理

  • 數據源複製首尾各一張實現無縫循環
  • scrollViewDidEndDecelerating 中重置偏移量
  • 定時器驅動自動翻頁
@interface BannerScrollView : UIScrollView 
@property (nonatomic, strong) NSArray *images;
@property (nonatomic, strong) NSTimer *autoScrollTimer;
@property (nonatomic, assign) NSInteger currentPage;
@end

@implementation BannerScrollView

- (void)configureWithImages:(NSArray *)images {
    self.images = images;
    self.pagingEnabled = YES;
    self.showsHorizontalScrollIndicator = NO;
    self.delegate = self;
    
    // 擴展數據源:尾部加首圖,首部加尾圖
    NSMutableArray *extended = [images mutableCopy];
    [extended insertObject:images.lastObject atIndex:0];
    [extended addObject:images.firstObject];
    
    CGFloat width = self.bounds.size.width;
    for (NSInteger i = 0; i < extended.count; i++) {
        UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(i * width, 0, width, self.bounds.size.height)];
        iv.image = extended[i];
        iv.contentMode = UIViewContentModeScaleAspectFill;
        iv.clipsToBounds = YES;
        [self addSubview:iv];
    }
    
    self.contentSize = CGSizeMake(extended.count * width, self.bounds.size.height);
    self.contentOffset = CGPointMake(width, 0); // 初始顯示真實第一張
    self.currentPage = 0;
    [self startAutoScroll];
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    NSInteger page = (NSInteger)(scrollView.contentOffset.x / scrollView.bounds.size.width);
    NSInteger realCount = self.images.count;
    
    // 邊界校正實現無限循環
    if (page == 0) {
        scrollView.contentOffset = CGPointMake(realCount * scrollView.bounds.size.width, 0);
        self.currentPage = realCount - 1;
    } else if (page == realCount + 1) {
        scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
        self.currentPage = 0;
    } else {
        self.currentPage = page - 1;
    }
    [self updatePageControl];
}

- (void)startAutoScroll {
    [self stopAutoScroll];
    self.autoScrollTimer = [NSTimer scheduledTimerWithTimeInterval:3.0
        target:self selector:@selector(autoScroll) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:self.autoScrollTimer forMode:NSRunLoopCommonModes];
}

- (void)autoScroll {
    CGPoint next = CGPointMake(self.contentOffset.x + self.bounds.size.width, 0);
    [self setContentOffset:next animated:YES];
}
@end

性能優化關鍵點

優化點方案收益
圖片解碼後台線程 ImageIO 漸進式解碼主線程不阻塞
內存佔用SDWebImage/Kingfisher 磁盤+內存雙級緩存避免重複下載解碼
佈局計算預計算 frame 避免 AutoLayout 開銷滾動 60fps 保障
大圖處理CATiledLayer 分塊渲染 / UIImageView+Zoom支持縮放查看原圖

現代化替代方案

  • UICollectionView + FlowLayout:Cell 復用機制天然適配大數據量
  • SwiftUI ScrollView + LazyHStack:聲明式語法,自動優化渲染
  • 第三方成熟庫:FSPagerView、SDCycleScrollView、CHIPageControl
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved