Created
March 31, 2019 17:19
-
-
Save ahmedAlmasri/b230033758a749f2cf72e94a676bae76 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import UIKit | |
func getWidth() -> CGFloat{ | |
return UIScreen.main.bounds.width | |
} | |
func getHeight() -> CGFloat{ | |
return UIScreen.main.bounds.height | |
} | |
public enum rotationWay { | |
case horizontal | |
case vertical | |
} | |
protocol SNPagerDelegate { | |
func currentPage(_ index:Int) | |
} | |
class SNPager: UIView{ | |
var delegate:SNPagerDelegate? | |
private var _rotation: rotationWay! | |
var _count: Int! | |
/* | |
this count variable is added for binding between scrollViewDidScroll functions and limit of page. | |
If there have 3 page, SNPager has provide to scroll just between 0 and 3 section. | |
*/ | |
var scrollView: UIScrollView! | |
var pageControl: UIPageControl! | |
// init function that represent SNPager with view | |
public init(frame: CGRect, viewArray uiviewArray:[UIView], _ rotation: rotationWay) { | |
// set the count before the init cause that otherwise return nil when detect scrolling | |
self._count = uiviewArray.count | |
super.init(frame: frame) | |
// set the rotation | |
self._rotation = rotation | |
let count:Int = uiviewArray.count | |
self._count = uiviewArray.count; | |
scrollView = UIScrollView() | |
scrollView.frame = CGRect(x: 0, y: 0, width: Int(UIScreen.main.bounds.width), height: Int(UIScreen.main.bounds.height)) | |
scrollView.backgroundColor = UIColor.clear | |
scrollView.isPagingEnabled = true | |
// setting scroll view contentsize for given direction | |
switch rotation { | |
case .horizontal: | |
scrollView.contentSize = CGSize(width: Int(UIScreen.main.bounds.width)*count, height: 0) | |
scrollView.showsHorizontalScrollIndicator = false | |
case .vertical: | |
scrollView.contentSize = CGSize(width: 0, height: Int(UIScreen.main.bounds.height)*count) | |
scrollView.showsVerticalScrollIndicator = false | |
} | |
scrollView.delegate = self | |
// settings up pagecontrol | |
switch rotation { | |
case .vertical: | |
pageControl = UIPageControl(frame: CGRect(x: UIScreen.main.bounds.width-50-UIScreen.main.bounds.width/2 , y: 0, width: 50, height: 20)) | |
pageControl.pageIndicatorTintColor = #colorLiteral(red: 0.9254901961, green: 0.6862745098, blue: 0.1411764706, alpha: 0.5184033891) | |
pageControl.currentPageIndicatorTintColor = #colorLiteral(red: 0.9254901961, green: 0.6862745098, blue: 0.1411764706, alpha: 1) | |
pageControl.transform = pageControl.transform.rotated(by: .pi/2) | |
pageControl.center.y = scrollView.center.y | |
case .horizontal: | |
pageControl = UIPageControl(frame: CGRect(x: 0, y:self.frame.height-35, width: 100, height: 20)) | |
pageControl.pageIndicatorTintColor = #colorLiteral(red: 0.9254901961, green: 0.6862745098, blue: 0.1411764706, alpha: 0.5184033891) | |
pageControl.currentPageIndicatorTintColor = #colorLiteral(red: 0.9254901961, green: 0.6862745098, blue: 0.1411764706, alpha: 1) | |
pageControl.center.x = self.center.x | |
} | |
self.attributesForPageControl(pageControl,count) | |
self.addSubview(pageControl) | |
var viewArray: [UIView?] = [UIView?].init(repeating: nil, count: count) | |
// initialize and setting up frame the uiviews with every view of viewArray | |
for i in 0...count-1 { | |
viewArray[i] = UIView() | |
switch rotation{ | |
case .horizontal: | |
viewArray[i]?.frame = CGRect(x: pageToFloatHorizontal(i), y: 0, width: getWidth(), height: getHeight()) | |
uiviewArray[i].frame.origin = CGPoint(x: pageToFloatHorizontal(i), y: 0) | |
case .vertical: | |
viewArray[i]?.frame = CGRect(x: 0, y: pageToFloatVertical(i), width: getWidth(), height: getHeight()) | |
uiviewArray[i].frame.origin = CGPoint(x: 0, y: pageToFloatVertical(i)) | |
} | |
viewArray[i]! = uiviewArray[i] | |
scrollView.addSubview(viewArray[i]!) | |
} | |
self.addSubview(scrollView) | |
switch rotation { | |
case .vertical: | |
scrollView.setContentOffset(CGPoint.init(x: 0, y: 20), animated: false) | |
scrollView.setContentOffset(CGPoint.init(x: 0, y: 0), animated: false) | |
default: | |
break | |
} | |
} | |
// init function that represent SNPager with images | |
public init(frame: CGRect, imageArray uiimageArray:[UIImage],_ rotation: rotationWay ){ | |
self._count = uiimageArray.count; | |
super.init(frame: frame) | |
self._rotation = rotation | |
let count:Int = uiimageArray.count | |
scrollView = UIScrollView() | |
scrollView.frame = CGRect(x: 0, y: 0, width: Int(UIScreen.main.bounds.width), height: Int(UIScreen.main.bounds.height)) | |
scrollView.backgroundColor = UIColor.clear | |
scrollView.isPagingEnabled = true | |
// setting scroll view contentsize for given direction | |
switch rotation { | |
case .horizontal: | |
scrollView.contentSize = CGSize(width: Int(UIScreen.main.bounds.width)*count, height: 0) | |
scrollView.showsHorizontalScrollIndicator = false | |
case .vertical: | |
scrollView.contentSize = CGSize(width: 0, height: Int(UIScreen.main.bounds.height)*count) | |
scrollView.showsVerticalScrollIndicator = false | |
} | |
scrollView.delegate = self | |
// settings up pagecontrol | |
switch rotation { | |
case .vertical: | |
pageControl = UIPageControl(frame: CGRect(x: UIScreen.main.bounds.width-50-UIScreen.main.bounds.width/2 , y: 0, width: 50, height: 20)) | |
// transform the pageControl for vertical position | |
pageControl.transform = pageControl.transform.rotated(by: .pi/2) | |
pageControl.center.y = scrollView.center.y | |
case .horizontal: | |
pageControl = UIPageControl(frame: CGRect(x: 0, y: UIScreen.main.bounds.height-50, width: 100, height: 20)) | |
pageControl.center.x = self.center.x | |
} | |
self.attributesForPageControl(pageControl,count) | |
self.addSubview(pageControl) | |
var imageViewArray: [UIImageView?] = [UIImageView?].init(repeating: nil, count: count) | |
// initialize and setting up frame the uiviews with every view of viewArray | |
for i in 0...count-1 { | |
imageViewArray[i] = UIImageView() | |
switch rotation{ | |
case .horizontal: | |
imageViewArray[i]?.frame = CGRect(x: pageToFloatHorizontal(i), y: 0, width: getWidth(), height: getHeight()) | |
case .vertical: | |
imageViewArray[i]?.frame = CGRect(x: 0, y: pageToFloatVertical(i), width: getWidth(), height: getHeight()) | |
} | |
imageViewArray[i]?.image = (uiimageArray[i]) | |
scrollView.addSubview(imageViewArray[i]!) | |
} | |
self.addSubview(scrollView) | |
switch rotation { | |
case .vertical: | |
scrollView.setContentOffset(CGPoint.init(x: 0, y: 20), animated: false) | |
scrollView.setContentOffset(CGPoint.init(x: 0, y: 0), animated: false) | |
default: | |
break | |
} | |
} | |
// helper methods | |
func scrollToPage(page: Int, animated: Bool) { | |
var frame: CGRect = self.scrollView.frame | |
// frame.origin.x = | |
frame.origin.y = 0 | |
//self.scrollView.scrollRectToVisible(frame, animated: animated) | |
scrollView.setContentOffset(CGPoint(x: frame.size.width * CGFloat(page), y: 0), animated: true) | |
} | |
private func attributesForPageControl(_ pageControl: UIPageControl, _ count:Int){ | |
pageControl.numberOfPages = count | |
pageControl.currentPage = 0 | |
pageControl.layer.zPosition = 1 | |
pageControl.backgroundColor = UIColor.clear | |
} | |
fileprivate func pageToFloatVertical(_ simpleInteger: Int) -> CGFloat{ | |
return CGFloat(simpleInteger) * UIScreen.main.bounds.height | |
} | |
fileprivate func pageToFloatHorizontal(_ simpleInteger: Int) -> CGFloat{ | |
return CGFloat(simpleInteger) * UIScreen.main.bounds.width | |
} | |
fileprivate func offsetToPage(_ scrollViewOffset: CGFloat) -> Int{ | |
return Int(scrollViewOffset / UIScreen.main.bounds.width) | |
} | |
fileprivate func offsetToPageVertical(withHeightOffset scrollViewOffset: CGFloat) -> Int{ | |
return Int(scrollViewOffset / UIScreen.main.bounds.height) | |
} | |
required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
} | |
} | |
extension SNPager: UIScrollViewDelegate{ | |
func scrollViewDidScroll(_ scrollView: UIScrollView) { | |
// its forbidden to scroll to negative offset or upper offset of biggest offset limit. | |
let rotation: rotationWay = _rotation! | |
let count: Int = _count! | |
switch rotation { | |
case .horizontal: | |
if scrollView.contentOffset.x <= 0{ | |
scrollView.setContentOffset(CGPoint.init(x: 0, y: 0), animated: false) | |
}else if scrollView.contentOffset.x >= UIScreen.main.bounds.width*CGFloat(count-1){ | |
scrollView.setContentOffset(CGPoint.init(x: Int(UIScreen.main.bounds.width)*(count-1), y: 0), animated: false) | |
} | |
case .vertical: | |
if scrollView.contentOffset.y <= 0{ | |
scrollView.setContentOffset(CGPoint.init(x: 0, y: 0), animated: false) | |
}else if scrollView.contentOffset.y >= UIScreen.main.bounds.height*CGFloat(count-1){ | |
scrollView.setContentOffset(CGPoint.init(x: 0, y: Int(UIScreen.main.bounds.height)*(count-1)), animated: false) | |
} | |
} | |
} | |
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { | |
// setting pageControl currentPage with every changing on scrollView page. | |
let rotation: rotationWay = _rotation! | |
switch rotation { | |
case .horizontal: | |
pageControl.currentPage = offsetToPage(scrollView.contentOffset.x) | |
case .vertical: | |
pageControl.currentPage = offsetToPageVertical(withHeightOffset: scrollView.contentOffset.y) | |
} | |
delegate?.currentPage(pageControl.currentPage) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment