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
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
Changing Navigation Bar Color in Swift
How to Create IPA in Xcode 6 Without Apple Developer Account
Insert CSS into Loaded HTML in Uiwebview/Wkwebview
Custom Installed Font Not Displayed Correctly in Uilabel
How to Check If a View Controller Is Presented Modally or Pushed on a Navigation Stack
Navigation Bar Rightbaritem Image-Button Bug iOS 11
How to Delete Wkwebview Cookies
How to Set the Title of a Uibutton as Left-Aligned
How to Pass Multiple Values with a Notification in Swift
Swift Compiler Shows Expected Declaration Error
Dynamically Changing Font Size of Uilabel
How to Convert a String to an Md5 Hash in iOS Using Swift
Behaviour for Significant Change Location API When Terminated/Suspended
How to Detect Network Signal Strength in iOS Reachability
Swiftui Navigationview Navigationbartitle Layoutconstraints Issue