How to Create a Scroll View with a Page Control Using Swift

How to create a Scroll View with a page control using swift?

import UIKit

class DummyVC: UIViewController, UIScrollViewDelegate {

let scrollView = UIScrollView(frame: CGRect(x:0, y:0, width:320,height: 300))
var colors:[UIColor] = [UIColor.red, UIColor.blue, UIColor.green, UIColor.yellow]
var frame: CGRect = CGRect(x:0, y:0, width:0, height:0)
var pageControl : UIPageControl = UIPageControl(frame: CGRect(x:50,y: 300, width:200, height:50))

override func viewDidLoad() {
super.viewDidLoad()

configurePageControl()

scrollView.delegate = self
scrollView.isPagingEnabled = true

self.view.addSubview(scrollView)
for index in 0..<4 {

frame.origin.x = self.scrollView.frame.size.width * CGFloat(index)
frame.size = self.scrollView.frame.size

let subView = UIView(frame: frame)
subView.backgroundColor = colors[index]
self.scrollView .addSubview(subView)
}

self.scrollView.contentSize = CGSize(width:self.scrollView.frame.size.width * 4,height: self.scrollView.frame.size.height)
pageControl.addTarget(self, action: #selector(self.changePage(sender:)), for: UIControlEvents.valueChanged)

}

func configurePageControl() {
// The total number of pages that are available is based on how many available colors we have.
self.pageControl.numberOfPages = colors.count
self.pageControl.currentPage = 0
self.pageControl.tintColor = UIColor.red
self.pageControl.pageIndicatorTintColor = UIColor.black
self.pageControl.currentPageIndicatorTintColor = UIColor.green
self.view.addSubview(pageControl)

}

// MARK : TO CHANGE WHILE CLICKING ON PAGE CONTROL
func changePage(sender: AnyObject) -> () {
let x = CGFloat(pageControl.currentPage) * scrollView.frame.size.width
scrollView.setContentOffset(CGPoint(x:x, y:0), animated: true)
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
pageControl.currentPage = Int(pageNumber)
}

}

Swift: how to make a ScrollView work with PageControl?

You should update the scroll view's offset to the be equal to the offset of the image you want to be showing after you transition. self.scrollView.contentOffset = CGPoint(x: pagesScrollViewSize.width * CGFloat(self.firstToShow), y: 0.0) You can do this in viewDidLayoutSubviews, which would make it look like:

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.scrollView.delegate = self
self.scrollView.maximumZoomScale = 2.0
self.scrollView.zoomScale = 1.0
self.scrollView.minimumZoomScale = 0.5

self.pageControl.numberOfPages = self.pageImages.count
self.pageControl.currentPage = self.firstToShow

for _ in 0.. self.pageViews.append(nil)
}

/* The scroll view, as before, needs to know its content size.
Since you want a horizontal paging scroll view, you calculate the width to be the number of pages multiplied by the width of the scroll view.
The height of the content is the same as the height of the scroll view
*/
let pagesScrollViewSize = self.scrollView.frame.size
self.scrollView.contentSize = CGSize(width: pagesScrollViewSize.width * CGFloat(self.pageImages.count),
height: pagesScrollViewSize.height)

self.scrollView.contentOffset = CGPoint(x: pagesScrollViewSize.width * CGFloat(self.firstToShow), y: 0.0)

// You’re going to need some pages shown initially, so you call loadVisiblePages()
self.loadVisiblePages()

}

The line you highlighted is just rounding down to the closest image index to determine what page the scroll view is on. The problem is when your view controller is displayed no scrolling has been done so it will always show the first image. To get the image you want to show first, you can just calculate what the offset should be for the image set your scroll view's offset to that as shown above.

Scroll view with page control to display images in iOS

The answer is a bit late. So, may be helpful for someone else:

Swift 3x:

First of all, give the delegation like this:

class YOUR_VIEW_CONTROLLER: UIViewController, UIScrollViewDelegate 

Now connect the outlets of UIScrollView and UIPageControl like this:

@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var pageControl: UIPageControl!

NOTE:I'm using colours array. You can use image array instead.

var colors:[UIColor] = [UIColor.red, UIColor.blue, UIColor.green, UIColor.yellow]
var frame: CGRect = CGRect(x:0, y:0, width:0, height:0)

Now just copy and paste the below code in your class:

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
configurePageControl()

self.view.bringSubview(toFront: pageControl)
scrollView.delegate = self
self.view.addSubview(scrollView)
for index in 0..<4 {

frame.origin.x = self.scrollView.frame.size.width * CGFloat(index)
frame.size = self.scrollView.frame.size

let subView = UIView(frame: frame)
subView.backgroundColor = colors[index]
self.scrollView.addSubview(subView)
}

self.scrollView.isPagingEnabled = true


self.scrollView.contentSize = CGSize(width:self.scrollView.frame.size.width * 4,height: self.scrollView.frame.size.height)

pageControl.addTarget(self, action: #selector(self.changePage(sender:)), for: UIControlEvents.valueChanged)

}

func configurePageControl() {
// The total number of pages that are available is based on how many available colors we have.
self.pageControl.layer.zPosition = 1

self.pageControl.numberOfPages = colors.count
self.pageControl.currentPage = 0
self.pageControl.tintColor = UIColor.red
self.pageControl.pageIndicatorTintColor = UIColor.black
self.pageControl.currentPageIndicatorTintColor = UIColor.green
self.view.addSubview(pageControl)

}

// MARK : TO CHANGE WHILE CLICKING ON PAGE CONTROL
func changePage(sender: AnyObject) -> () {
let x = CGFloat(pageControl.currentPage) * scrollView.frame.size.width
scrollView.setContentOffset(CGPoint(x:x, y:0), animated: true)
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
pageControl.currentPage = Int(pageNumber)
}

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..
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)

}

}

scroll view, collection view and one page control

You can try

func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard scrollView != collectionView else { return }
let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
pageControl.currentPage = Int(pageIndex)
}

or

guard scrollView == self.scrollView else { return }

UIPageControl and UIScrollView not scrolling

Inside the for loop you use the same object of imageView , you only set the frame and the image

imageView.frame = frame
imageView.image = myImage

but you have to create a new instance of the UIImageView

//

Suppose you have a scrollView in IB with top , leading and trailing constraints to the superView , and a height of say 200 , you can add imageViews dynamically like this

class ViewController: UIViewController {

@IBOutlet weak var scrollView: UIScrollView!

override func viewDidLoad() {
super.viewDidLoad()


for i in 0..<10 {

let f = CGRect(x: CGFloat(i) * scrollView.frame.width, y: 0, width: scrollView.frame.width, height: scrollView.frame.height)

let imgV = UIImageView(frame: f)

imgV.image = UIImage(named: "re-fuel.png")

scrollView.addSubview(imgV)


}

scrollView.contentSize = CGSize(width: CGFloat(10) * scrollView.frame.width, height: scrollView.frame.height)
}
}

Result

Sample Image

Swift: Updating UIPageControl from ScrollView

You can certainly do what you're describing, if you have a paging scroll view; I have an example of it that uses this code:

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
let x = scrollView.contentOffset.x
let w = scrollView.bounds.size.width
pageControl.currentPage = Int(x/w)
}

Except for your round, that looks a lot your code, which makes me think that your code should work. That makes me think that something else is just misconfigured. Is this a paging scroll view? Did you remember to make this object your scroll view's delegate? Use logging or a breakpoint to be certain that your scrollViewDidEndDecelerating is even being called in the first place.

However, I would just like to point out that the configuration you are describing is effectively what UIPageViewController gives you for free — a scroll view with view controller views, plus a page control — so you might want to use that instead.



Related Topics



Leave a reply



Submit