How to set a tap for imageview array in Swift/Xcode - ios

I am trying to set tap listeners for each imageview from my imageview array and print when one is selected. Ideally I would like each imageview to have its on listener - such as "imageview 2 was selected." Thanks!
class ViewController2: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
var index: Int = 0
var images: [UIImage] = [UIImage(named: "image1.png")!, UIImage(named: "image2.png")!, UIImage(named: "image3.png")!, UIImage(named: "image4.png")!, UIImage(named: "image5.png")!, UIImage(named: "image6.png")!, UIImage(named: "image7.png")!, UIImage(named: "image8.png")!, UIImage(named: "image9.png")!, UIImage(named: "image10.png")!, UIImage(named: "image11.png")!, UIImage(named: "image12.png")!, UIImage(named: "image13.png")!, UIImage(named: "image14.png")!, UIImage(named: "image15.png")!, UIImage(named: "image16.png")!, UIImage(named: "image17.png")!, UIImage(named: "image18.png")!, UIImage(named: "image19.png")!, UIImage(named: "image20.png")!, UIImage(named: "image21.png")!, UIImage(named: "image22.png")!, UIImage(named: "image23.png")!, UIImage(named: "image24.png")!, UIImage(named: "image25.png")!, UIImage(named: "image26.png")!, UIImage(named: "image27.png")!, UIImage(named: "image28.png")!, UIImage(named: "image29.png")!, UIImage(named: "image30.png")!]
var imageView: [UIImageView] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width
//let screenHeight = screenSize.height
let numWidth: CGFloat = 3
let numHeight: CGFloat = 10
self.scrollView.frame.size.width = screenWidth
let width: CGFloat = (self.scrollView.frame.size.width - (numWidth + 1))/3
var tap = UITapGestureRecognizer(target: self, action: Selector("tappedMe"))
for var i:CGFloat = 0; i < 3; ++i{
for var j:CGFloat = 0; j < 10; ++j {
let image: UIImage = images[index]
imageView.append(UIImageView(image: image))
imageView[index].frame = CGRectMake(width*i, width*j, width, width)
self.scrollView.addSubview(imageView[index])
imageView[index].addGestureRecognizer(tap)
imageView[index].userInteractionEnabled = true
index++
}
}
scrollView.contentSize.height = (width)*numHeight
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func imageTapped(img: AnyObject)
{
// Your action
print("tapped")
}
}

you should use custom class instead of holding array of UIImageView.
import UIKit
class MyCustomImageView : UIImageView{
var myId : String = "";
override init(frame: CGRect){
super.init(frame: frame);
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
println("IM TOUCHED\(myId)");
}
}
.
.
.
var imageView: [MyCustomImageView] = []
and in your loop:
for var i:CGFloat = 0; i < 3; ++i{
for var j:CGFloat = 0; j < 10; ++j {
let image: UIImage = images[index]
imageView.append(MyCustomImageView(frame: CGRectMake(width*i, width*j, width, width)))
imageView[index].image = image;
self.scrollView.addSubview(imageView[index])
imageView[index].myId = "Image number \(index)";
index++
}
}
and btw, dont know what are you trying to do with all width height,
but this is a bit more clear way:
class ViewController2: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
let imageIndex : (begin:Int,end:Int) = (begin:1,end:30);
var imageView: [MyCustomImageView] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width
//let screenHeight = screenSize.height
let numWidth: CGFloat = 3
let numHeight: CGFloat = 10
self.scrollView.frame.size.width = screenWidth
let width: CGFloat = (self.scrollView.frame.size.width - (numWidth + 1))/3
var index = self.imageIndex.begin;
for var i:CGFloat = 0; i < 3; ++i{
for var j:CGFloat = 0; j < 10; ++j {
let image: UIImage? = UIImage(named: "image\(index++).png");
var currentImageView = MyCustomImageView(frame: CGRectMake(width*i, width*j, width, width))
currentImageView.image = image;
currentImageView.userInteractionEnabled = true
currentImageView.myId = "image\(index++).png";
self.scrollView.addSubview(imageView[index])
imageView.append(currentImageView);
}
}
scrollView.contentSize.height = (width)*numHeight
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Related

Swift image do not fit in the scrollview

i have a scrollview wich load a image to zoom in and zoom out , the problem is that i want the image to be loaded full like this
http://www.capital.cl/wp-content/uploads/2015/04/avengers.jpg
so the user can see the complete image first
but it looks like this
this is the code
import UIKit
class Paso2: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var noCheckBox2: CheckBox!
#IBOutlet weak var siCheckBox2: CheckBox!
var imageView = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
// imageView.contentMode = UIViewContentMode.ScaleAspectFill
// imageView.clipsToBounds = true
imageView.image = UIImage(named: "avengers.jpg")
let imagee = UIImage(named: "avengers.jpg")
let size = imagee?.size
imageView.frame = CGRectMake(0, 0, size!.width, size!.height)
imageView.contentMode = .Top
scrollView.addSubview(imageView)
scrollView.contentSize = size!
let scrollViewFrame = scrollView.frame
let scaleWidth = scrollViewFrame.size.width / scrollView.contentSize.width
let scaleHeight = scrollViewFrame.size.height / scrollView.contentSize.height
let minScale = min(scaleHeight, scaleWidth)
scrollView.minimumZoomScale = 1
scrollView.maximumZoomScale = 4
scrollView.zoomScale = minScale
centerScrollViewContents()
}
func centerScrollViewContents(){
let boundsSize = scrollView.bounds.size
var contentsFrame = imageView.frame
if contentsFrame.size.width < boundsSize.width {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2
}
else {
contentsFrame.origin.x = 0
}
if contentsFrame.size.height < boundsSize.height {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2
}
else {
contentsFrame.origin.y = 0
}
imageView.frame = contentsFrame
// scrollView.frame = contentsFrame
}
func scrollViewDidZoom(scrollView: UIScrollView) {
centerScrollViewContents()
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return imageView
}
Help plz
Just change this.
imageView.contentMode = .ScaleAspectFit
without zoom
with zoom
You should use .contentMode property of the UIImageView for the proper representation of the image.
This is small comparison of the content modes.
You want to display full image without scrolling or you want to display scrollable image?
Try this code for fast start:
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
var imageView = UIImageView()
private var imageViewOriginalSize = CGRect ()
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = UIImage(named: "avengers.jpg")
imageView.contentMode = .ScaleAspectFit
let size = UIScreen.mainScreen().bounds
imageViewOriginalSize = size
imageView.frame = CGRectMake(0, 0, size.width, size.height)
scrollView.addSubview(imageView)
let pinch = UIPinchGestureRecognizer(target: self, action: #selector(ViewController.pinchGestureRecognizerAction))
self.scrollView.addGestureRecognizer(pinch)
}
func pinchGestureRecognizerAction(gestureRecoginzer: UIPinchGestureRecognizer) {
imageView.frame.size.height = imageViewOriginalSize.height*gestureRecoginzer.scale
imageView.frame.size.width = imageViewOriginalSize.width*gestureRecoginzer.scale
imageView.frame.origin.x = imageViewOriginalSize.origin.x*gestureRecoginzer.scale
imageView.frame.origin.y = imageViewOriginalSize.origin.y*gestureRecoginzer.scale
scrollView.contentSize = imageView.frame.size
}}

nil in UIPageControl view subview

I'm new in ios swift and want to change UIPageControl dots size via images.
I found same issue here (UIPageControl custom class - found nil changing image to the dots)
but seems the answer is wrong, still in page control view subviews(UIImageView) is nil
As I don't have enough reputation have to ask here.
here how I'm adding image views to the scroll view
let imgOne = UIImageView(frame: CGRectMake(0, 0,scrollViewWidth, scrollViewHeight))
imgOne.image = UIImage(named: "1")
let imgTwo = UIImageView(frame: CGRectMake(scrollViewWidth, 0,scrollViewWidth, scrollViewHeight))
imgTwo.image = UIImage(named: "2")
let imgThree = UIImageView(frame: CGRectMake(scrollViewWidth*2, 0,scrollViewWidth, scrollViewHeight))
imgThree.image = UIImage(named: "3")
let imgFour = UIImageView(frame: CGRectMake(scrollViewWidth*3, 0,scrollViewWidth, scrollViewHeight))
imgFour.image = UIImage(named: "4")
self.scrollView.addSubview(imgOne)
self.scrollView.addSubview(imgTwo)
self.scrollView.addSubview(imgThree)
self.scrollView.addSubview(imgFour)
and below the answer to the problem
class PageControl: UIPageControl {
var activeImage: UIImage!
var inactiveImage: UIImage!
override var currentPage: Int {
willSet {
self.updateDots()
}
}
convenience init(activeImage: UIImage, inactiveImage: UIImage) {
self.init()
self.activeImage = activeImage
self.inactiveImage = inactiveImage
self.pageIndicatorTintColor = UIColor.clearColor()
self.currentPageIndicatorTintColor = UIColor.clearColor()
}
func updateDots() {
for var i = 0; i < count(subviews); i++ {
var view: UIView = subviews[i] as! UIView
if count(view.subviews) == 0 {
self.addImageViewOnDotView(view, imageSize: activeImage.size)
}
var imageView: UIImageView = view.subviews.first as! UIImageView // nil
imageView.image = self.currentPage == i ? activeImage : inactiveImage
}
}
// MARK: - Private
func addImageViewOnDotView(view: UIView, imageSize: CGSize) {
var frame = view.frame
frame.origin = CGPointZero
frame.size = imageSize
var imageView = UIImageView(frame: frame)
imageView.contentMode = UIViewContentMode.Center
view.addSubview(imageView)
}
}
Spending few days I solved it in the following way...
Don't know how is good the solution, feel free to to improve...
There was 2 problems
1: in function updateDots, should look like this
func updateDots() {
for var i = 0; i < subviews.count; i++ {
var imageView: UIImageView? = nil
let view: UIView = subviews[i]
if (view.subviews.first is UIImageView) {
if (subviews.count == 0) {
addImageViewOnDotView(view, imageSize: activeImage.size)
}
imageView = (view.subviews.first as! UIImageView)
imageView!.image = self.currentPage == i ? activeImage : inactiveImage
}
if (imageView == nil) {
imageView = UIImageView(frame: CGRectMake(0.0, 0.0, view.frame.size.width, view.frame.size.height));
imageView!.image = self.currentPage == i ? activeImage : inactiveImage
view.addSubview(imageView!)
}
}
}
2: When call this function, should be after (didSet) scroll not before (willSet)
override var currentPage: Int {
didSet {
self.updateDots()
}
}

Swift - Custom control for UISlider

I already created a custom control for UISlider. This UISlider have 2 thumbs so it can find minimum and maximum values. I take these tutorials as my references.
http://www.raywenderlich.com/76433/how-to-make-a-custom-control-swift
http://www.sitepoint.com/wicked-ios-range-slider-part-one/
Compiled successfully but my UISlider looks weird. You can take a look my github repository here.
https://github.com/datomnurdin/RevivalxSwiftSlider
My custom control for UISlider
import UIKit
class RangeSlider: UIControl {
var minimumValue: Float!
var maximumValue: Float!
var minimumRange: Float!
var selectedMinimumValue: Float!
var selectedMaximumValue: Float!
var distanceFromCenter: Float!
var _padding: Float!
var _maxThumbOn: Bool!
var _minThumbOn: Bool!
var _minThumb = UIImageView()
var _maxThumb = UIImageView()
var _track = UIImageView()
var _trackBackground = UIImageView()
override init(frame: CGRect){
super.init(frame: frame)
_minThumbOn = false;
_maxThumbOn = false;
_padding = 20;
let _trackBackground = UIImageView(image: UIImage(named: "bar-background.png"))
_trackBackground.center = self.center;
self.addSubview(_trackBackground)
let _track = UIImageView(image: UIImage(named: "bar-highlight.png"))
_track.center = self.center
self.addSubview(_track)
let _minThumb = UIImageView(image: UIImage(named: "handle.png"), highlightedImage: UIImage(named: "handle-hover.png"))
_minThumb.frame = CGRectMake(0,0, self.frame.size.height,self.frame.size.height);
_minThumb.contentMode = UIViewContentMode.Center
self.addSubview(_minThumb)
let _maxThumb = UIImageView(image: UIImage(named: "handle.png"), highlightedImage: UIImage(named: "handle-hover.png"))
_maxThumb.frame = CGRectMake(0,0, self.frame.size.height,self.frame.size.height)
_maxThumb.contentMode = UIViewContentMode.Center
self.addSubview(_maxThumb)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
_minThumb.center = CGPointMake(CGFloat(self.xForValue(selectedMinimumValue)), self.center.y);
_maxThumb.center = CGPointMake(CGFloat(self.xForValue(selectedMaximumValue)), self.center.y)
NSLog("Tapable size %f", _minThumb.bounds.size.width);
self.updateTrackHighlight()
}
func xForValue(value: Float) -> Float {
return (Float(self.frame.size.width) - (_padding * 2)) * ((value - minimumValue) / (maximumValue - minimumValue)) + _padding
}
func valueForX(x: Float) -> Float {
return minimumValue + (x - _padding) / (Float(self.frame.size.width) - (_padding * 2)) * (maximumValue - minimumValue)
}
func continueTrackingWithTouch(touch: UITouch, event: UIEvent) -> Bool {
if !_minThumbOn && !_maxThumbOn {
return true
}
var touchPoint: CGPoint = touch.locationInView(self)
if (_minThumbOn != nil) {
_minThumb.center = CGPointMake(max(CGFloat(self.xForValue(minimumValue)),min(touchPoint.x - CGFloat(distanceFromCenter), CGFloat(self.xForValue(selectedMaximumValue - minimumRange)))),CGFloat(_minThumb.center.y))
selectedMinimumValue = self.valueForX(Float(_minThumb.center.x))
}
if (_maxThumbOn != nil) {
_maxThumb.center = CGPointMake(min(CGFloat(self.xForValue(maximumValue)), max(touchPoint.x - CGFloat(distanceFromCenter), CGFloat(self.xForValue(selectedMinimumValue + minimumRange)))), CGFloat(_maxThumb.center.y))
selectedMaximumValue = self.valueForX(Float(_maxThumb.center.x))
}
self.updateTrackHighlight()
self.setNeedsLayout()
self.sendActionsForControlEvents(UIControlEvents.ValueChanged)
return true
}
func beginTrackingWithTouch(touch: UITouch, event: UIEvent) -> Bool {
var touchPoint: CGPoint = touch.locationInView(self)
if(CGRectContainsPoint(_minThumb.frame, touchPoint)){
_minThumbOn = true;
distanceFromCenter = Float(touchPoint.x - _minThumb.center.x)
}
else if(CGRectContainsPoint(_maxThumb.frame, touchPoint)){
_maxThumbOn = true;
distanceFromCenter = Float(touchPoint.x - _maxThumb.center.x)
}
return true;
}
func endTrackingWithTouch(touch: UITouch, event: UIEvent) {
_minThumbOn = false;
_maxThumbOn = false;
}
func updateTrackHighlight() {
_track.frame = CGRectMake(
_minThumb.center.x,
_track.center.y - (_track.frame.size.height/2),
_maxThumb.center.x - _minThumb.center.x,
_track.frame.size.height
);
}
}
My output
It suppose to be like this
How can I fix this?
Your problem lies at the 'let'.
_minThumb = UIImageView(image: UIImage(named: "handle.png"), highlightedImage: UIImage(named: "handle-hover.png"))
_minThumb.frame = CGRectMake(0,0, self.frame.size.height,self.frame.size.height);
_minThumb.contentMode = UIViewContentMode.Center
self.addSubview(_minThumb)
_maxThumb = UIImageView(image: UIImage(named: "handle.png"), highlightedImage: UIImage(named: "handle-hover.png"))
_maxThumb.frame = CGRectMake(0,0, self.frame.size.height,self.frame.size.height)
_maxThumb.contentMode = UIViewContentMode.Center
self.addSubview(_maxThumb)
Just remove the 'let' and it should work, this is because you are using _minThumb and _maxThumb globally, but you declared both as a constant, so they would not respond to any changes once initalized.

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

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
I am trying to create a Page View controller with numbers of view. I want a simple code sample that will use UIPageViewController.
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)
}
}
For lazy coder this is the Swift 3 implementation based on That lazy iOS Guy 웃's answer
import UIKit
class ViewController: 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()
// Do any additional setup after loading the view, typically from a nib.
configurePageControl()
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.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)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Swift 3 - Horizontal image scroll
import UIKit
class pageenabled: UIViewController,UIScrollViewDelegate
{
let imagelist = ["img1.jpg", "photo1.jpg", "photo3.jpg", "photo4.jpg", "photo5.jpg"]
var scrollView = UIScrollView()
var pageControl : UIPageControl = UIPageControl(frame:CGRect(x: 50, y: 300, width: 200, height: 50))
var yPosition:CGFloat = 0
var scrollViewContentSize:CGFloat=0;
override func viewDidLoad() {
super.viewDidLoad()
scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 300))
configurePageControl()
scrollView.delegate = self
self.view.addSubview(scrollView)
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
self.scrollView.isPagingEnabled = true
let myImage:UIImage = UIImage(named: imagelist[i])!
let myImageView:UIImageView = UIImageView()
myImageView.image = myImage
myImageView.contentMode = UIViewContentMode.scaleAspectFit
myImageView.frame = frame
scrollView.addSubview(myImageView)
}
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)
// Do any additional setup after loading the view.
}
func configurePageControl() {
// The total number of pages that are available is based on how many available colors we have.
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.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)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In Swift 3.0
craeate iboutlets through story board for scrollview and pagecontroller.
#IBOutlet weak var imgScrollView: UIScrollView!
#IBOutlet weak var imgPageController: UIPageControl!
var sliderImagesArray = NSMutableArray()
in viewdidload method write this code
sliderImagesArray = ["https://images.unsplash.com/photo-1432679963831-2dab49187847?w=1080","https://images.unsplash.com/photo-1447746249824-4be4e1b76d66?w=1080", "https://images.unsplash.com/photo-1463595373836-6e0b0a8ee322?w=1080"]
imgScrollView.delegate = self
for i in 0..<sliderImagesArray.count {
var imageView : UIImageView
let xOrigin = self.imgScrollView.frame.size.width * CGFloat(i)
imageView = UIImageView(frame: CGRect(x: xOrigin, y: 0, width: self.imgScrollView.frame.size.width, height: self.imgScrollView.frame.size.height))
imageView.isUserInteractionEnabled = true
let urlStr = sliderImagesArray.object(at: i)
print(imgScrollView,imageView, urlStr)
imageView.sd_setImage(with: URL(string: urlStr as! String), placeholderImage: UIImage(named: "placeholder.png"))
imageView .contentMode = UIViewContentMode.scaleToFill
self.imgScrollView.addSubview(imageView)
}
self.imgScrollView.isPagingEnabled = true
self.imgScrollView.bounces = false
self.imgScrollView.showsVerticalScrollIndicator = false
self.imgScrollView.showsHorizontalScrollIndicator = false
self.imgScrollView.contentSize = CGSize(width:
self.imgScrollView.frame.size.width * CGFloat(sliderImagesArray.count), height: self.imgScrollView.frame.size.height)
imgPageController.addTarget(self, action: #selector(self.changePage(sender:)), for: UIControlEvents.valueChanged)
self.imgPageController.numberOfPages = sliderImagesArray.count
self.imgPageController.currentPage = 0
self.imgPageController.tintColor = UIColor.red
self.imgPageController.pageIndicatorTintColor = UIColor.black
self.imgPageController.currentPageIndicatorTintColor = UIColor.blue
after that implement scrollview delegate methods
func changePage(sender: AnyObject) -> () {
let x = CGFloat(imgPageController.currentPage) * imgScrollView.frame.size.width
imgScrollView.setContentOffset(CGPoint(x: x,y :0), animated: true)
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageNumber = round(imgScrollView.contentOffset.x / imgScrollView.frame.size.width)
imgPageController.currentPage = Int(pageNumber)
}
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var imageViewBottomConstraint: NSLayoutConstraint!
#IBOutlet weak var imageViewLeadingConstraint: NSLayoutConstraint!
#IBOutlet weak var imageViewTopConstraint: NSLayoutConstraint!
#IBOutlet weak var imageViewTrailingConstraint: NSLayoutConstraint!
extension ZoomedPhotoViewController: UIScrollViewDelegate {
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return imageView
}
}
private func updateMinZoomScaleForSize(size: CGSize) {
let widthScale = size.width / imageView.bounds.width
let heightScale = size.height / imageView.bounds.height
let minScale = min(widthScale, heightScale)
scrollView.minimumZoomScale = minScale
scrollView.zoomScale = minScale
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
updateMinZoomScaleForSize(view.bounds.size)
}
private 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()
}
func scrollViewDidZoom(scrollView: UIScrollView) {
updateConstraintsForSize(view.bounds.size)
}
import UIKit
public class PhotoCommentViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var nameTextField: UITextField!
public var photoName: String!
override public func viewDidLoad() {
super.viewDidLoad()
if let photoName = photoName {
self.imageView.image = UIImage(named: photoName)
}
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let cell = sender as? UICollectionViewCell,
indexPath = collectionView?.indexPathForCell(cell),
photoCommentViewController = segue.destinationViewController as? PhotoCommentViewController {
photoCommentViewController.photoName = "photo\(indexPath.row + 1)"
}
}
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(PhotoCommentViewController.keyboardWillShow(_:)),
name: UIKeyboardWillShowNotification,
object: nil
)
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(PhotoCommentViewController.keyboardWillHide(_:)),
name: UIKeyboardWillHideNotification,
object: nil
)
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func adjustInsetForKeyboardShow(show: Bool, notification: NSNotification) {
guard let value = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue else { return }
let keyboardFrame = value.CGRectValue()
let adjustmentHeight = (CGRectGetHeight(keyboardFrame) + 20) * (show ? 1 : -1)
scrollView.contentInset.bottom += adjustmentHeight
scrollView.scrollIndicatorInsets.bottom += adjustmentHeight
}
func keyboardWillShow(notification: NSNotification) {
adjustInsetForKeyboardShow(true, notification: notification)
}
func keyboardWillHide(notification: NSNotification) {
adjustInsetForKeyboardShow(false, notification: notification)
}
#IBAction func hideKeyboard(sender: AnyObject) {
nameTextField.endEditing(true)
}
public var photoIndex: Int!
import UIKit
class ManagePageViewController: UIPageViewController {
var photos = ["photo1", "photo2", "photo3", "photo4", "photo5"]
var currentIndex: Int!
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
// 1
if let viewController = viewPhotoCommentController(currentIndex ?? 0) {
let viewControllers = [viewController]
// 2
setViewControllers(
viewControllers,
direction: .Forward,
animated: false,
completion: nil
)
}
}
func viewPhotoCommentController(index: Int) -> PhotoCommentViewController? {
if let storyboard = storyboard,
page = storyboard.instantiateViewControllerWithIdentifier("PhotoCommentViewController")
as? PhotoCommentViewController {
page.photoName = photos[index]
page.photoIndex = index
return page
}
return nil
}
}

Swift Image gallery with fullscreen slider

I want to build a facebook-like image gallery but don't know where to start from.
Here's what i think i should do:
CollectionView that shows thumbnails based on an array
On row-click, i modally open a pageViewController based on the same array of images
On Swipe left-right, i go to the next or previous image
On Swipe up-down, i close this view and go back to my collectionview
Is this logic correct/the best practice?
Maybe it's been already done by someone.
You can use banana library for showing images in slider view in Swift
get banana from https://github.com/gauravkatoch007/banana
import banana
#IBOutlet weak var imageScrollView: UIScrollView!
// Here imageArray can be a string array of Image URLs
var imageArray = [String]()
//or imageArray can be a array of UIImages
var imageArray = [UIImage]()
var imageScroll = banana( imageScrollView :self.imageScrollView )
//Load to load images in memory and display them in User Interface
imageScroll!.load(imageArray)
//Call startScroll for autoScrolling. Default scrolling timer is 8 seconds
imageScroll!.startScroll()
//Call this function to stop autoScrolling on touch or swipe.
imageScroll!.assignTouchGesture()
Update I resolved in this way:
Gallery is a collection view
On cell selected, i modally segue to another view, which contains a scrollview in which i put 5 images one (right) after the other, and handle paginating.
My image will always be the third in the middle, after every scroll, i choose the 5 images of my entire array which centers the index, or the 5 which contain this.
here's my class PhotoViewController: UIViewController, UIScrollViewDelegate {
var screenSize: CGRect = UIScreen.mainScreen().bounds
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var blackView: UIView!
#IBOutlet weak var doneButton: UIButton!
#IBOutlet weak var photoActions: UIImageView!
var img1:UIImageView = UIImageView(image: UIImage())
var img2:UIImageView = UIImageView(image: UIImage())
var img3:UIImageView = UIImageView(image: UIImage())
var img4:UIImageView = UIImageView(image: UIImage())
var img5:UIImageView = UIImageView(image: UIImage())
var w1: UIImage!
var w2: UIImage!
var w3: UIImage!
var w4: UIImage!
var w5: UIImage!
var pageIndex: Int!
var currentPage: Int!
var oldPage: Int!
var endFrame: CGRect!
var arrayIndex: Int!
// placeholder for if the image frame is scrolled
var scrolledPhotoFrame: CGRect!
override func viewDidLoad() {
super.viewDidLoad()
RightSize()
LoadData()
}
func LoadData(){
// data passed from feedViewController gets stored here
img1.image = w1
img2.image = w2
img3.image = w3
img4.image = w4
img5.image = w5
// set the right endFrame based on the selectedImage
switch pageIndex {
case 0:
img1.frame = endFrame
img1.frame.origin.x = 0
case 1:
img2.frame = endFrame
img2.frame.origin.x = screenSize.width
case 2:
img3.frame = endFrame
img3.frame.origin.x = (screenSize.width * 2)
case 3:
img4.frame = endFrame
img4.frame.origin.x = (screenSize.width * 3)
case 4:
img5.frame = endFrame
img5.frame.origin.x = (screenSize.width * 4)
default:
break
}
currentPage = pageIndex
oldPage = pageIndex
scrollView.contentSize = CGSize(width: screenSize.width*5, height: screenSize.height)
scrollView.contentOffset.x = CGFloat(pageIndex * Int(screenSize.width))
println(scrollView.contentOffset.x)
// default value of scrolledPhotoFrame is unscrolled position of photoImageView
scrolledPhotoFrame = endFrame
// required for registering scroll events
scrollView.delegate = self
// RightSize()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func doneDidPress(sender: AnyObject) {
dismissViewControllerAnimated(true, completion: nil)
}
// called while scrolling
func scrollViewDidScroll(scrollView: UIScrollView) {
currentPage = Int(scrollView.contentOffset.x / screenSize.width)
if (currentPage != oldPage){
//Ho cambiato pagina
if (currentPage>oldPage){
//Sono andato di 1 foto avanti
println("Avanti")
arrayIndex = arrayIndex+1
CambioPagina()
}else{
//Sono andato di 1 foto indietro
arrayIndex = arrayIndex-1
println("indietro")
}
oldPage=currentPage
}
var alpha = CGFloat(1 - abs(scrollView.contentOffset.y) / 100)
var alpha2 = CGFloat(1 - abs(scrollView.contentOffset.y) / 20)
blackView.alpha = alpha
doneButton.alpha = alpha2
photoActions.alpha = alpha2
}
// This method is called right as the user lifts their finger
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
var offsetY = scrollView.contentOffset.y
var alpha = CGFloat(1 - abs(scrollView.contentOffset.y) / 240)
if (abs(offsetY) > 100) {
scrolledPhotoFrame.origin.y = scrolledPhotoFrame.origin.y - offsetY
blackView.hidden = true
scrollView.hidden = true // could be wrong
doneButton.hidden = true
dismissViewControllerAnimated(true, completion: nil)
}
}
// selecting the view to zoom
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
switch currentPage {
case 0:
return img1
case 1:
return img2
case 2:
return img3
case 3:
return img4
case 4:
return img5
default:
return nil
}
}
func scrollViewWillBeginZooming(scrollView: UIScrollView, withView view: UIView!) {
img2.hidden = true
img3.hidden = true
img4.hidden = true
img5.hidden = true
}
func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView!, atScale scale: CGFloat) {
}
//Controllo per cambio pagina..! chissa!
func CambioPagina(){
switch arrayIndex{
case 0:
w1 = UIImage(named: arrayFoto[arrayIndex])
w2 = UIImage(named: arrayFoto[arrayIndex+1])
w3 = UIImage(named: arrayFoto[arrayIndex+2])
w4 = UIImage(named: arrayFoto[arrayIndex+3])
w5 = UIImage(named: arrayFoto[arrayIndex+4])
pageIndex = 0
case 1:
w1 = UIImage(named: arrayFoto[arrayIndex-1])
w2 = UIImage(named: arrayFoto[arrayIndex])
w3 = UIImage(named: arrayFoto[arrayIndex+1])
w4 = UIImage(named: arrayFoto[arrayIndex+2])
w5 = UIImage(named: arrayFoto[arrayIndex+3])
pageIndex = 1
case (arrayFoto.count-2):
w1 = UIImage(named: arrayFoto[arrayIndex-3])
w2 = UIImage(named: arrayFoto[arrayIndex-2])
w3 = UIImage(named: arrayFoto[arrayIndex-1])
w4 = UIImage(named: arrayFoto[arrayIndex])
w5 = UIImage(named: arrayFoto[arrayIndex+1])
pageIndex = 3
case (arrayFoto.count-1):
w1 = UIImage(named: arrayFoto[arrayIndex-4])
w2 = UIImage(named: arrayFoto[arrayIndex-3])
w3 = UIImage(named: arrayFoto[arrayIndex-2])
w4 = UIImage(named: arrayFoto[arrayIndex-1])
w5 = UIImage(named: arrayFoto[arrayIndex])
pageIndex = 4
default:
w1 = UIImage(named: arrayFoto[arrayIndex-2])
w2 = UIImage(named: arrayFoto[arrayIndex-1])
w3 = UIImage(named: arrayFoto[arrayIndex])
w4 = UIImage(named: arrayFoto[arrayIndex+1])
w5 = UIImage(named: arrayFoto[arrayIndex+2])
pageIndex = 2
}
LoadData()
}
func RightSize(){
img1.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height)
scrollView.addSubview(img1)
img2.frame = CGRect(x: screenSize.width, y: 0, width: screenSize.width, height: screenSize.height)
scrollView.addSubview(img2)
img3.frame = CGRect(x: (screenSize.width*2), y: 0, width: screenSize.width, height: screenSize.height)
scrollView.addSubview(img3)
img4.frame = CGRect(x: (screenSize.width*3), y: 0, width: screenSize.width, height: screenSize.height)
scrollView.addSubview(img4)
img5.frame = CGRect(x: (screenSize.width*4), y: 0, width: screenSize.width, height: screenSize.height)
scrollView.addSubview(img5)
img1.contentMode = .ScaleAspectFit
img2.contentMode = .ScaleAspectFit
img3.contentMode = .ScaleAspectFit
img4.contentMode = .ScaleAspectFit
img5.contentMode = .ScaleAspectFit
}
Any better approach will be great, for example, i cannot handle image zoom

Resources