2017-06-10 85 views
0

我想用UICollectionView創建幻燈片。現在我創建了一個集合視圖和一個自定義單元格。我顯示了所有圖像,但沒有自動滾動。所以我想,當視圖控制器加載時,即使按下滑動按鈕,集合視圖的所有單元格也應自動滾動。但我搜查了所有的文件,但沒有找到。所以請給任何想法或給我任何教程鏈接也。如何使用collectionView自動滑動圖像

回答

2

我已經實現了一個簡單的自動滾動組件UICollectionView,你可以從這裏得到 - BJAutoScrollingCollectionView

我已經包括了原始代碼,您需要如下:

斯威夫特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() } 


目標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]; } 
+0

reloadCollectionView方法應被調用。它可以在'viewDidLoad'或任何地方調用。無論何時你想重新加載你的集合視圖,不要直接調用'reloadData',而是調用'reloadCollectionView'。它會自動開始滑動。 –

+0

@Ganesh,謝謝。假設我想按下按鈕進行滾動。我的意思是進入UI,我有三個按鈕,稱爲previous,net&pause。那個時候如何管理 – Abhinaba

+0

我會將這些添加到我的答案中。 –