How should i use UIpageControl from UIScrollView - ios

How should I use UIpageControl from UIScrollView? I am stuck, help me out.
Here is my code please help;
class home: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var mainScrollView: UIScrollView!
#IBOutlet weak var pagecontrol: UIPageControl!
var imageArray = [UIImage]()
var pageControl : UIPageControl!
override func viewDidLoad() {
super.viewDidLoad()
mainScrollView.delegate = self
imageArray = [#imageLiteral(resourceName: "sliderImage"), #imageLiteral(resourceName: "clothing"), #imageLiteral(resourceName: "sports")]
for i in 0..<imageArray.count{
let imageView = UIImageView()
imageView.image = imageArray[i]
imageView .contentMode = .scaleToFill
let xPosition = self.view.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPosition, y: 0, width: self.mainScrollView.frame.width, height: self.mainScrollView.frame.height)
mainScrollView.contentSize.width = mainScrollView.frame.width * CGFloat(i + 1)
mainScrollView.addSubview(imageView)
}
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

Check out this answer
Things have been pretty much the same over these years:
Set your UIScrollView delegate to your view controller (which you did);
Add code for scrollViewDidScroll delegate method:
func scrollViewDidScroll(_ scrollView: UIScrollView)
{
self.pageControl.currentPage = Int(floorf(Float(scrollView.contentOffset.x / scrollView.width)))
}
Add the same in scrollViewDidEndDecelerating method:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
{
self.pageControl.currentPage = Int(floorf(Float(scrollView.contentOffset.x / scrollView.width)))
}
Although, it depends on your needs - try how it works with and without each of them.

Related

UIPageControl and UIScrollView not scrolling

I'm having a relatively simple UIViewController with a UIScrollView that's taking relatively half the screen and a UIImageView placed inside the UIScrollView that's the exact same size as the UIScrollView.
On top of the UIImageView there's a UIPageControl. The point is have a horizontal scrolling and present an image like a slider based on the amount of images in an array. The problem is that the scroll view is not scrolling and I don't know why.
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var pageControl: UIPageControl!
let imagelist = ["3.jpg", "1.jpg", "2.png", "4.png", "5.png"]
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
configurePageControl()
for i in stride(from: 0, to: imagelist.count, by: 1) {
var frame = CGRect.zero
frame.origin.x = self.scrollView.frame.size.width * CGFloat(i)
frame.origin.y = 0
frame.size = self.scrollView.frame.size
scrollView.isPagingEnabled = true
scrollView.isScrollEnabled = true
let myImage:UIImage = UIImage(named: imagelist[i])!
let bgColorFromImage = myImage.averageColor
imageView.image = myImage
imageView.contentMode = UIViewContentMode.scaleAspectFit
imageView.frame = frame
scrollView.backgroundColor = bgColorFromImage
scrollView.addSubview(imageView)
}
self.scrollView.contentSize = CGSize(width: self.scrollView.frame.size.width * CGFloat(imagelist.count), height: self.scrollView.frame.size.height)
pageControl.addTarget(self, action: #selector(changePage), for: UIControlEvents.valueChanged)
}
func configurePageControl() {
self.pageControl.numberOfPages = imagelist.count
self.pageControl.currentPage = 0
self.pageControl.tintColor = UIColor.red
self.pageControl.pageIndicatorTintColor = UIColor.black
self.pageControl.currentPageIndicatorTintColor = UIColor.green
self.imageView.addSubview(pageControl)
}
#objc func changePage() {
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)
}
This is what the UIStoryboard looks like:
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
The problem is that the scroll view itself is positioned with autolayout. Once you do that, you cannot set the contentSize to make the scroll view scrollable. You must use internal constraints to configure the content size.

Zoom array of images in UIScrollView

How i can zoom array of images? Now i can zoom image as a .gif
My code:
class ScrollImageViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scrollImage: UIScrollView!
private var imageView: UIImageView!
var imagesArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.scrollImage.minimumZoomScale = 1.0
self.scrollImage.maximumZoomScale = 5.0
for i in 0..<imagesArray.count {
imageView = UIImageView()
imageView.sd_setImage(with: URL(string: imagesArray[i]))
imageView.contentMode = .scaleAspectFit
let xPosition = self.view.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPosition, y: 0, width: self.scrollImage.frame.width, height: self.scrollImage.frame.height)
scrollImage.contentSize.width = scrollImage.frame.width * CGFloat(i + 1)
scrollImage.addSubview(imageView)
}
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}
}
I tried lesson from raywenderlich, but they did not help me :(
I want to get result like a AirBnB or example:
Scrolling once and zoom in, zoom out, scrolling twice - zoom in, zoom out and so on
You can check below framework
https://github.com/zvonicek/ImageSlideshow
It has a FullScreenSlideshowViewControllerclass which can be used for your purpose, also it can be customised.

Cannot Zoom UIImageView

I am new to swift.
I am doing an exercise from an app development book. I am trying to create an UIImageView and put a image in it, but I can not zoom the image in. There is something wrong in my code, but I don't know what is going on.
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var image: UIImageView!
#IBOutlet weak var scroll: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
scroll.delegate = ViewController()
updateZoomFor(size:view.bounds.size)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func viewForZooming(in scrollView: UIScrollView) -> UIImageView{
return image
}
func updateZoomFor(size:CGSize){
let widthScale = size.width / image.bounds.width
let heightScale = size.height / image.bounds.height
let scale = min(widthScale, heightScale)
scroll.minimumZoomScale = scale
}
}
First, set scroll.delegate = self as suggested by 3stud1ant3.
Second, you need to match the definition of theUIScrollViewDelegate method:
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return image
}
Make sure you set the zoom scale in updateZoomFor as well: scroll.zoomScale = scale.
Also you need to implement this:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
updateZoomFor(size: view.bounds.size)
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
updateConstraintsForSize(view.bounds.size)
}
fileprivate func updateConstraintsForSize(_ size: CGSize) {
let yOffset = max(0, (size.height - imageView.frame.height) / 2)
imageViewTopConstraint.constant = yOffset
imageViewBottomConstraint.constant = yOffset
let xOffset = max(0, (size.width - imageView.frame.width) / 2)
imageViewLeadingConstraint.constant = xOffset
imageViewTrailingConstraint.constant = xOffset
view.layoutIfNeeded()
}

Swift Add Image to UIImageView from User Tap

I have a ScrollView with an ImageView inside.
Here a user can select a point on the image and it will print out the coordinates.
I'm also trying to add an image ("pin") to the tapped coordinate but am unsure how to...
// MARK: - Outlets
#IBOutlet weak var containerView: UIView!
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var sharkImage: UIImageView!
// MARK: - View Did Load
override func viewDidLoad() {
super.viewDidLoad()
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 6.0
scrollView.delegate = self
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapAction))
self.sharkImage.isUserInteractionEnabled = true
self.sharkImage.addGestureRecognizer(tapGestureRecognizer)
}
// MARK: - Scroll View
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return sharkImage
}
// MARK: - Functions
func tapAction(sender: UITapGestureRecognizer) {
// Get points for the UIImageView
let touchPoint = sender.location(in: self.sharkImage)
print(touchPoint)
// Get points from the image itself
let z1 = touchPoint.x * (sharkImage.image?.size.width)! / sharkImage.frame.width
let z2 = touchPoint.y * (sharkImage.image?.size.height)! / sharkImage.frame.height
print("Touched point (\(z1), \(z2)")
}
In your tapAction:
let pin = UIImageView(frame: CGRect(x: touchPoint.x - 20, y: touchPoint.y - 20, width: 40, height: 40))
pin.image = UIImage(named: "pin")
sharkImage.addSubview(pin)
So what I´m doing is adding a new UIImageView with the x and y from touchPoint.x and touchPoint.y into your current sharkImage.

View does not stick on top (does not change position)

I am trying to stick the UIView on top while scrolling. Tried using max(x:T, y:T) method as suggested here on stackOverflow but it does not work. I manage to detect when the scrollView should be re-positioned but updating frame does not have any affect.
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate{
#IBOutlet var objectView: UIView!
#IBOutlet var scrollView: UIScrollView!
//var originalOffsetY : CGFloat!
//var originalOffestX : CGFloat!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let size = CGSize.init(width: self.view.frame.width, height: self.view.frame.height*2)
scrollView.contentSize = size
scrollView.backgroundColor = UIColor.blueColor()
objectView.backgroundColor = UIColor.whiteColor()
scrollView.delegate = self
scrollView.addSubview(objectView)
}
// override func viewWillAppear(animated: Bool) {
// originalOffsetY = objectView.frame.origin.y
// originalOffestX = objectView.frame.origin.x
// }
func scrollViewDidScroll(scrollView: UIScrollView) {
print("ScrollView \(scrollView.contentOffset.y)")
print("ObjectView \(objectView.frame.origin.y)")
let location = CGPointMake(0, scrollView.contentOffset.y)
let size = objectView.frame.size
if scrollView.contentOffset.y >= objectView.frame.origin.y {
objectView.frame = CGRect.init(origin: location, size: size)
print("Detected \(objectView.frame)")
}
// var newRect = objectView.frame
// newRect.origin.y = max(originalOffsetY!, scrollView.contentOffset.y)
// objectView.frame = newRect
}
}
The condition is matched successfully as can be seen here in Logs . But the view remains unchanged. I require the objectView to scroll a bit.. from around y=270 to 0 .. but not beyond it.
You need to keep track of the original position of the view within the scroll view, and calculate using that value, here's a very simplified example:
class StickyScrollViewController: UIViewController {
var stickyView = UIView(frame: CGRect(x: 0, y: 100, width: 300, height: 100))
var originalStickyOrigin: CGPoint = CGPoint(x: 0, y: 100)
func scrollViewDidScroll(_ scrollView: UIScrollView) {
var nextYOffset = max(originalStickyOrigin.y, scrollView.contentOffset.y)
stickyView.frame = CGRect(x: 0, y: nextYOffset, width: 300, height: 100)
}
}

Resources