How to add PageControl inside UICollectionView Image Scrolling
Here you have a complete class with Page Control pagination in a horizontal collection view.
This is working on one of my applications, right now, and is working correctly. If you cannot get it work, do feel free to ask me and I'll help you.
First, in the Storyboard you have to set up your CollectionView with:
Layout: Flow
Scroll Direction: Horizontal
Scrolling enabled
Paging enabled
@IBOutlet weak var collectionView: UICollectionView! //img: 77
@IBOutlet weak var pageControl: UIPageControl!
var thisWidth:CGFloat = 0
override func awakeFromNib() {
super.awakeFromNib()
thisWidth = CGFloat(self.frame.width)
collectionView.delegate = self
collectionView.dataSource = self
pageControl.hidesForSinglePage = true
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YourCell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
self.pageControl.currentPage = indexPath.section
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
thisWidth = CGFloat(self.frame.width)
return CGSize(width: thisWidth, height: self.frame.height)
}
How to connect UIPageControl to UICollectionView (Swift)
Firstly add your UIPageControl
into your storyboard with your UICollectionView
, then connect them as outlets to your view controller.
@IBOutlet var pageControl: UIPageControl!
@IBOutlet var collectionView: UICollectionView!
Adjust your numberOfItemsInSection
method in UICollectionViewDataSource
to set the count of the page control to always be equal to the number of cells in the collection view.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let count = ...
pageControl.numberOfPages = count
pageControl.isHidden = !(count > 1)
return count
}
Lastly, using the UIScrollViewDelegate
, we can tell which cell the UICollectionView
stops on. If you are not using a UICollectionViewController
, you may have to add the delegate protocol.
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
pageControl?.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
pageControl?.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}
This is possible because a UICollectionView
is in fact a UIScrollView
under the hood.
How to connect UIPageControl and CollectionView?
You can use this. In this code block, collection view cell size equal to collection view and collection view scroll horizontally. I hope, this helps you.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offSet = scrollView.contentOffset.x
let width = scrollView.frame.width
let horizontalCenter = width / 2
pageControl.currentPage = Int(offSet + horizontalCenter) / Int(width)
}
How to use the pageControl in Collectionview Inside the Tableview?
You can compare which view is scrolling now inside scrollViewDidScroll
.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == self.collectionView { //Your scrollView outlet
//Your code here
}
}
Edit: First of all you need to implement collectionView's datasource and delegate method with your tableViewCell not with your ViewController also you need to put pageControlSwipe
in tableViewCell not in the collectionViewCell
. So it should be look something like this.
class FbHomeCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UIScrollViewDelegate {
@IBOutlet var collectionView: UICollectionView!
@IBOutlet var pageControlSwipe: UIPageControl!
@IBOutlet var btnPushImage: UIButton!
var colorArray = [UIColor]()
var currentPage = 0
func setCollectionViewWith(colorArray: [UIColor]) {
self.colorArray = colorArray
self.collectionView.isPagingEnabled = true
self.collectionView.datasource = self
self.collectionView.delegate = self
self.collectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return colorArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let collCell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! FBHomeCollectionCell
collCell.backgroundColor = self.colorArray[indexPath.item]
self.pageControlSwipe.numberOfPages = colorArray.count
return collCell
}
//ScrollView delegate method
func scrollViewDidScroll(_ scrollView: UIScrollView)
{
let pageWidth = scrollView.frame.width
self.currentPage = Int((scrollView.contentOffset.x + pageWidth / 2) / pageWidth)
self.pageControlSwipe.currentPage = self.currentPage
}
}
Now call this method in your tableView's datasource method like this.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return model.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! FbHomeCell
cell.btnPushImage.tag = indexPath.row
cell.collectionView.tag = indexPath.row
cell.setCollectionViewWith(colorArray: model[indexPath.row])
return cell
}
iOS6 UICollectionView and UIPageControl - How to get visible cell?
You must setup yourself as UIScrollViewDelegate
and implement the scrollViewDidEndDecelerating:
method like so:
Objective-C
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
CGFloat pageWidth = self.collectionView.frame.size.width;
self.pageControl.currentPage = self.collectionView.contentOffset.x / pageWidth;
}
Swift
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageWidth = self.collectionView.frame.size.width
pageControl.currentPage = Int(self.collectionView.contentOffset.x / pageWidth)
}
CollectionView + Page control
I figured it out. the code below work with landscape orintation (with 2 cells) and portrait orintation (with 1 cell) I still have one problem the counting doesn't appear until the scrolling starts.
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if UIWindow.isLandscape {
let x = scrollView.contentOffset.x
let w = scrollView.bounds.size.width/2
let currentPage = Int(ceil(x/w))
numberOfPagesLabel.text = "\(self.pages.count)/\(currentPage + 2)"
pageControl.currentPage = Int(currentPage) }
else
{
let x = scrollView.contentOffset.x
let w = scrollView.bounds.size.width
let currentPage = Int(ceil(x/w))
numberOfPagesLabel.text = "\(self.pages.count)/\(currentPage + 1)"
pageControl.currentPage = Int(currentPage)
}
extension UIWindow {
static var isLandscape: Bool {
if #available(iOS 13.0, *) {
return UIApplication.shared.windows
.first?
.windowScene?
.interfaceOrientation
.isLandscape ?? false
} else {
return UIApplication.shared.statusBarOrientation.isLandscape
}
}
}
Add imageview to a scrollview page control
Here I suppose that you have 4 images attached in your project named 0,1,2,3 png , try this
import UIKit
class ViewController: UIViewController , UIScrollViewDelegate {
let scrollView = UIScrollView()
let pageCon = UIPageControl()
override func viewDidLoad() {
super.viewDidLoad()
let viewsCount = 4
var prevView = self.view!
scrollView.delegate = self
scrollView.isPagingEnabled = true
pageCon.numberOfPages = viewsCount
pageCon.currentPage = 0
pageCon.tintColor = .green
pageCon.currentPageIndicatorTintColor = .orange
pageCon.backgroundColor = .blue
pageCon.translatesAutoresizingMaskIntoConstraints = false
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
view.insertSubview(pageCon, aboveSubview: scrollView)
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant:20),
scrollView.heightAnchor.constraint(equalToConstant: 400),
pageCon.centerXAnchor.constraint(equalTo: view.centerXAnchor),
pageCon.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant:-20),
])
for i in 0..<viewsCount {
let imageV = UIImageView()
imageV.image = UIImage(named: "\(i).png")
imageV.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(imageV)
if prevView == self.view {
imageV.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
}
else {
imageV.leadingAnchor.constraint(equalTo: prevView.trailingAnchor).isActive = true
}
NSLayoutConstraint.activate([
imageV.topAnchor.constraint(equalTo: scrollView.topAnchor),
imageV.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
imageV.widthAnchor.constraint(equalToConstant: self.view.frame.width),
imageV.heightAnchor.constraint(equalToConstant: 400)
])
if i == viewsCount - 1 {
imageV.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
}
prevView = imageV
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
pageCon.currentPage = Int(scrollView.contentOffset.x / self.view.frame.width)
}
}
Related Topics
Swift Tableview in a Uiview Not Displaying Data
How to Get the Indexpath.Row When an Element Is Activated
Nsnotificationcenter Addobserver in Swift
Cfnetwork Sslhandshake Failed iOS 9
How to Localise a String Inside the iOS Info.Plist File
How to Get Current Location from User in Ios
How to Count Occurrences of an Element in a Swift Array
Get Location Updates For iOS App Even When Suspended
Append Data to a Post Nsurlrequest
Cell Size Not Updating After Changing Flow Layout'S Itemsize
Looking to Understand the iOS Uiviewcontroller Lifecycle
Uialertcontroller Custom Font, Size, Color
Swift - Get Device'S Wifi Ip Address
How to Use Timer (Formerly Nstimer) in Swift
How to Find Specific Subclass of Nsmanagedobject
Swift Compiler Error: "Expression Too Complex" on a String Concatenation