如何使用 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;
}
});
}
我想用 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;
}
});
}