如何使用 collectionView 自动滑动图像

How to Auto Sliding Images with collectionView

我想用 UICollectionView 创建幻灯片。现在我已经创建了一个集合视图和一个自定义单元格。我正在显示所有图像,但不是自动滚动。所以我想,当加载视图控制器时,集合视图的所有单元格都应该自动滚动,即使按下滑动按钮也是如此。但是我搜索了所有的文件却没有找到。所以请给我任何想法或给我任何教程 link。

我已经为 UICollectionView 实现了一个简单的自动滚动组件,您可以从这里获取 - BJAutoScrollingCollectionView.

我在下面包含了您需要的原始代码:

Swift 3.0+:

    @IBOutlet weak var collectionView: UICollectionView!

    var timer:Timer? = nil        
    var datasource: [UIImage]?

    @IBAction func previousButtonAction(sender: UIButton) {

            if self.datasource != nil {

                if self.datasource?.count != 0 {

                    self.scrollToPreviousOrNextCell(direction: "Previous")

                }

            }

        }


    @IBAction func nextButtonAction(sender: UIButton) {

        if self.datasource != nil {

            if self.datasource?.count != 0 {

                self.scrollToPreviousOrNextCell(direction: "Next")

            }

        }

    }

    @IBAction func pauseButtonAction(sender: UIButton) {

         self.timer.invalidate()

    }

    //After you've received data from server or you are ready with the datasource, call this method. Magic!
    func reloadCollectionView() {

        self.collectionView.reloadData()

        // Invalidating timer for safety reasons
        self.timer?.invalidate()

        // Below, for each 3.5 seconds MyViewController's 'autoScrollImageSlider' would be fired
        self.timer = Timer.scheduledTimer(timeInterval: 3.5, target: self, selector: #selector(MyViewController.autoScrollImageSlider), userInfo: nil, repeats: true)

        //This will register the timer to the main run loop
        RunLoop.main.add(self.timer!, forMode: .commonModes)

    }

    func scrollToPreviousOrNextCell(direction: String) {

            DispatchQueue.global(qos: .background).async {

                DispatchQueue.main.async {

                    let firstIndex = 0
                    let lastIndex = (self.datasource?.count)! - 1

                    let visibleIndices = self.collectionView.indexPathsForVisibleItems

                    let nextIndex = visibleIndices[0].row + 1
                    let previousIndex = visibleIndices[0].row - 1

                    let nextIndexPath: IndexPath = IndexPath.init(item: nextIndex, section: 0)
                    let previousIndexPath: IndexPath = IndexPath.init(item: previousIndex, section: 0)

                    if direction == "Previous" {

                        if previousIndex < firstIndex {


                        } else {

                            self.collectionView.scrollToItem(at: previousIndexPath, at: .centeredHorizontally, animated: true)
                        }

                    } else if direction == "Next" {

                        if nextIndex > lastIndex {


                        } else {

                            self.collectionView.scrollToItem(at: nextIndexPath, at: .centeredHorizontally, animated: true)

                        }

                    }

                }

            }

        }

    func autoScrollImageSlider() {

            DispatchQueue.global(qos: .background).async {

                DispatchQueue.main.async {

                    let firstIndex = 0
                    let lastIndex = (self.datasource?.count)! - 1

                    let visibleIndices = self.collectionView.indexPathsForVisibleItems
                    let nextIndex = visibleIndices[0].row + 1

                    let nextIndexPath: IndexPath = IndexPath.init(item: nextIndex, section: 0)
                    let firstIndexPath: IndexPath = IndexPath.init(item: firstIndex, section: 0)

                    if nextIndex > lastIndex {

                        self.collectionView.scrollToItem(at: firstIndexPath, at: .centeredHorizontally, animated: true)

                    } else {

                        self.collectionView.scrollToItem(at: nextIndexPath, at: .centeredHorizontally, animated: true)

                    }

                }

            }

        }


    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cellId = "cell"

        //Use your custom cell
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! UICollectionViewCell
        cell.imageView.image = self.datasource[indexPath.row]

        return cell

    }

    //Make sure you invalidate the timer here
    override func viewWillDisappear(_ animated: Bool) { self.timer?.invalidate() }


Objective C:

@interface MyViewController () <UICollectionViewDelegate, UICollectionViewDataSource> {

    NSTimer *timer;
    NSMutableArray *datasource;

}

@property (nonatomic, weak) IBOutlet UICollectionView *collectionView;

@end

@implementation MyViewController

- (IBAction)previousButtonAction:(UIButton *)sender {

    if (datasource != nil) {
        if (datasource.count != 0) {
            [self scrollToPreviousOrNextCell:@"Previous"];
        }
    }
}

- (IBAction)nextButtonAction:(UIButton *)sender {

    if (datasource != nil) {
        if (datasource.count != 0) {
            [self scrollToPreviousOrNextCell:@"Next"];
        }
    }
}

- (IBAction)pauseButtonAction:(UIButton *)sender { [timer invalidate]; }

//After you've received data from server or you are ready with the datasource, call this method. Magic!
- (void) reloadCollectionView {

    [self.collectionView reloadData];

    // Invalidating timer for safety reasons
    [timer invalidate];

    // Below, for each 3.5 seconds MyViewController's 'autoScrollImageSlider' would be fired
    timer = [NSTimer scheduledTimerWithTimeInterval:3.5 target:self selector:@selector(autoScrollImageSlider) userInfo:nil repeats:YES];

    //This will register the timer to the main run loop
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

}

- (void)scrollToPreviousOrNextCell:(NSString *)direction {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {

        NSInteger firstIndex = 0;
        NSInteger lastIndex = datasource.count - 1;

        NSArray *visibleIndices = [self.collectionView indexPathsForVisibleItems];

        NSInteger nextIndex = [[visibleIndices objectAtIndex:0] row] + 1;
        NSInteger previousIndex = [[visibleIndices objectAtIndex:0] row] - 1;

        NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:nextIndex inSection:0];
        NSIndexPath *previousIndexPath = [NSIndexPath indexPathForRow:previousIndex inSection:0];

        if ([direction isEqualToString:@"Previous"]) {

            if (previousIndex < firstIndex) {

            } else {
                [self.collectionView scrollToItemAtIndexPath:previousIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
            }

        } else if ([direction isEqualToString:@"Next"]) {

            if (nextIndex > lastIndex) {

            } else {
                [self.collectionView scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
            }
        }

    });
}

-(void) autoScrollImageSlider {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {

        NSInteger firstIndex = 0;
        NSInteger lastIndex = datasource.count - 1;

        NSArray *visibleIndices = [self.collectionView indexPathsForVisibleItems];
        NSInteger nextIndex = [[visibleIndices objectAtIndex:0] row] + 1;

        NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:nextIndex inSection:0];
        NSIndexPath *firstIndexPath = [NSIndexPath indexPathForRow:firstIndex inSection:0];

        if (nextIndex > lastIndex) {
            [self.collectionView scrollToItemAtIndexPath:firstIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
        } else {
            [self.collectionView scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
        }

    });

}


- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    NSString *cellId = @"cell";

    //Use your custom cell
    UICollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellId forIndexPath:indexPath];
    cell.imageView.image = [datasource objectAtIndex:[indexPath row]];

    return cell;

}


//Make sure you invalidate the timer here
-(void)viewWillDisappear:(BOOL)animated { [timer invalidate]; }

Objective C 试试这个代码。这对我有用,带有集合视图和自定义集合视图单元格的自动滑动图像

@interface DashboardViewController ()  <UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout> {
    
    NSMutableArray *bannerArr;
    NSTimer *timer;
    int counter;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.collectionView.delegate = self;
    self.collectionView.dataSource = self;
    UINib *nib2 = [UINib nibWithNibName:@"SliderCollectionCell" bundle:nil];
    [self.collectionView registerNib:nib2 forCellWithReuseIdentifier:@"SliderCollectionCell"];

 timer = [NSTimer scheduledTimerWithTimeInterval:3.5 target:self selector:@selector(autoScrollImageSlider) userInfo:nil repeats:YES];
    
    //This will register the timer to the main run loop
  [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
counter = 0;
}


- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    NSLog(@"%lu", (unsigned long)self->bannerArr.count);
    return [self->bannerArr count];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    SliderCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"SliderCollectionCell" forIndexPath:indexPath];
    
    NSDictionary *dict = bannerArr[indexPath.row];
    NSString *image_url = [dict objectForKey: @"image_url"];
    cell.imgBanner.image = nil;
    cell.heightConst.constant = self.collectionView.frame.size.height;
    cell.widthConst.constant = [UIScreen mainScreen].bounds.size.width;
    [cell.imgBanner sd_setImageWithURL:[NSURL URLWithString: image_url]];
    return cell;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
   
    return CGSizeMake([UIScreen mainScreen].bounds.size.height, self.collectionView.frame.size.height);
    //return CGSizeMake(375, 197);
}

-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(0, 0, 0, 0);
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    return 0.0 ;
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
    return 0.0;
}


-(void) autoScrollImageSlider {
    
    dispatch_async(dispatch_get_main_queue(), ^{
       
        if(bannerArr.count == 0) {
            return;
        }
        if (counter < bannerArr.count) {
            
            NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:counter inSection:0];
            [self.collectionView scrollToItemAtIndexPath: nextIndexPath atScrollPosition: UICollectionViewScrollPositionCenteredHorizontally animated:YES];
            counter += 1;
        }else {
            counter = 0;
            NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:counter inSection:0];
            
            [self.collectionView scrollToItemAtIndexPath: nextIndexPath atScrollPosition: UICollectionViewScrollPositionCenteredHorizontally animated:YES];
            counter = 1;
        }
        
    });
    
}