Scroll Vertically in a UIScrollView with Vertical Paging enabled - ios

Hoping you could give me some direction here. I have a scrollview setup with vertically paging. My problem is the views are larger than the screen (vertically). My desired effect is to have the view scroll to the bottom and then page to the next page. Like my image below is trying to depict.
I have tried setting the size of the scrollview and the content size to the size of the view which does offset the views correctly. I just can't scroll to see the bottom of the view, It just pages to the next view.
Thanks for any advice.
class ViewController: UIViewController {
let scrollView = UIScrollView() // Create the scrollView
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Set up and add scrollView to view
scrollView.frame = self.view.frame
self.scrollView.pagingEnabled = true
self.view.addSubview(scrollView)
//An array of UIColors to add to the views
let x : [UIColor] = [UIColor.blueColor(),UIColor.redColor(),UIColor.yellowColor()]
//For each UIColor add a view that is 100px larger then the height of the scrollView
for index in 0...x.count-1{
//
let subView = UIView(frame: CGRectMake(
0, //x offset
(self.scrollView.frame.height + 100) * CGFloat(index), //y offset
self.scrollView.frame.width, // width
(self.scrollView.frame.height + 100))) // height
subView.backgroundColor = x[index] //background Color
scrollView.addSubview(subView) // Add View
}
//
let c = (self.scrollView.frame.size.height + 100) * CGFloat(x.count)
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.width, c)
//Background Color
self.view.backgroundColor = UIColor.greenColor()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

The best way I've found to do it is to use a nested scrollview for the content. Here is what my code ended up looking like.
class ViewController: UIViewController, UIScrollViewDelegate {
let scrollView = ScrollView() // Create the scrollView
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Set up and add scrollView to view
scrollView.frame = self.view.frame
self.scrollView.pagingEnabled = true
self.view.addSubview(scrollView)
self.scrollView.delegate = self
//An array of UIColors to add to the views
let x : [UIColor] = [UIColor.blueColor(),UIColor.redColor(),UIColor.yellowColor()]
//For each UIColor add a view that is 100px larger then the height of the scrollView
for index in 0...x.count-1{
//
let subView = UIScrollView(frame: CGRectMake(
0, //x offset
(self.scrollView.frame.height * CGFloat(index)), //y offset
self.scrollView.frame.width, // width
(self.scrollView.frame.height))) // height
//Set the size of the content view
let contentView = UIView(frame: CGRectMake(0, 0, self.view.frame.width, 1000))
subView.contentSize = CGSizeMake(self.view.frame.width, contentView.frame.height)
contentView.backgroundColor = x[index]
subView.addSubview(contentView)
scrollView.addSubview(subView) // Add View
}
//
let c = (self.scrollView.frame.size.height) * CGFloat(x.count)
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.width, c)
//Background Color
self.view.backgroundColor = UIColor.greenColor()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

User4's answer, in objective-c:
UIScrollView *scrollView = [[UIScrollView alloc] init];
scrollView.frame = self.view.frame;
scrollView.pagingEnabled = YES;
scrollView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:scrollView];
scrollView.delegate = self;
NSArray *x = #[[UIColor blueColor], [UIColor redColor]];
for (int i = 0; i < x.count; i++) {
UIView *subView = [[UIView alloc] initWithFrame:
CGRectMake(0,
(scrollView.frame.size.height) * i,
scrollView.frame.size.width,
scrollView.frame.size.height)
];
UISwitch *switchCtrl = [[UISwitch alloc] initWithFrame:CGRectMake(5, 5, 20, 20)];
subView.backgroundColor = x[i];
[subView addSubview:switchCtrl];
[scrollView addSubview:subView];
}
float c = (scrollView.frame.size.height) * x.count;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, c);
self.view.backgroundColor = [UIColor greenColor];

A great tutorial by RayWenderlich.com does horizontal page scrolling. I've modified that code to allow for vertical page scrolling by adding a variable called "horizontalDirection". First follow his tutorial here:
http://www.raywenderlich.com/76436/use-uiscrollview-scroll-zoom-content-swift
After you have completed the section "Viewing Previous/Next Pages" replace your view controller with this: (You may need to tweak the size of your scrollview)
#IBOutlet var scrollView: UIScrollView!
#IBOutlet var pageControl: UIPageControl!
var pageImages: [UIImage] = []
var pageViews: [UIImageView?] = []
let horizontalDirection = false
override func viewDidLoad() {
super.viewDidLoad()
// Set up the image you want to scroll & zoom and add it to the scroll view
pageImages = [UIImage(named: "photo1.png")!,
UIImage(named: "photo2.png")!,
UIImage(named: "photo3.png")!,
UIImage(named: "photo4.png")!,
UIImage(named: "photo5.png")!]
let pageCount = pageImages.count
// Set up the page control
pageControl.currentPage = 0
pageControl.numberOfPages = pageCount
// Set up the array to hold the views for each page
for _ in 0..<pageCount {
pageViews.append(nil)
}
// Set up the content size of the scroll view
let pagesScrollViewSize = scrollView.frame.size
if horizontalDirection {
scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * CGFloat(pageImages.count), pagesScrollViewSize.height)
} else {
scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width, CGFloat(pageImages.count) * pagesScrollViewSize.height)
}
// Load the initial set of pages that are on screen
loadVisiblePages()
}
func loadVisiblePages() {
// First, determine which page is currently visible
var pageSide = scrollView.frame.size.width
var page = Int(floor((scrollView.contentOffset.x * 2.0 + pageSide) / (pageSide * 2.0)))
if !horizontalDirection {
pageSide = scrollView.frame.size.height
page = Int(floor((scrollView.contentOffset.y * 2.0 + pageSide) / (pageSide * 2.0)))
}
// Update the page control
pageControl.currentPage = page
// Work out which pages you want to load
let firstPage = page - 1
let lastPage = page + 1
// Purge anything before the first page
for var index = 0; index < firstPage; ++index {
purgePage(index)
}
// Load pages in our range
for index in firstPage...lastPage {
loadPage(index)
}
// Purge anything after the last page
for var index = lastPage+1; index < pageImages.count; ++index {
purgePage(index)
}
}
func loadPage(page: Int) {
if page < 0 || page >= pageImages.count {
// If it's outside the range of what you have to display, then do nothing
return
}
// Load an individual page, first checking if you've already loaded it
if let pageView = pageViews[page] {
// Do nothing. The view is already loaded.
} else {
var frame = scrollView.bounds
if horizontalDirection {
frame.origin.x = frame.size.width * CGFloat(page)
frame.origin.y = 0.0
frame = CGRectInset(frame, 10.0, 0.0)
} else {
frame.origin.x = 0.0
frame.origin.y = frame.size.height * CGFloat(page)
}
let newPageView = UIImageView(image: pageImages[page])
newPageView.contentMode = .ScaleAspectFit
newPageView.frame = frame
scrollView.addSubview(newPageView)
pageViews[page] = newPageView
}
}
func purgePage(page: Int) {
if page < 0 || page >= pageImages.count {
// If it's outside the range of what you have to display, then do nothing
return
}
// Remove a page from the scroll view and reset the container array
if let pageView = pageViews[page] {
pageView.removeFromSuperview()
pageViews[page] = nil
}
}
func scrollViewDidScroll(scrollView: UIScrollView!) {
// Load the pages that are now on screen
loadVisiblePages()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

Related

how to use a Custom ImageView ( class ) in a TableViewCell

am trying to get this in my UITableViewCell
an imageView which can hold an array of Images and can be scrollable
so i tried this :
class MostWantedImageView: UIImageView , UIScrollViewDelegate{
var pageImages:[UIImage] = [UIImage]()
var pageViews:[UIImageView?] = [UIImageView]()
var scrollView:UIScrollView = UIScrollView()
var pageControl:UIPageControl = UIPageControl()
var viewingPage = -1
func loadVisiblePages() {
// First, determine which page is currently visible
let pageWidth:CGFloat = self.frame.size.width;
let page = Int(floor((self.scrollView.contentOffset.x * 2.0 + pageWidth) / (pageWidth * 2.0)));
/*
Check that page have changed,
in case that user drag left in first page, or drag right in last page
a 'scrollViewDidEndDecelerating' is fired
*/
if viewingPage != page {
// Update the page control
self.pageControl.currentPage = page;
// Work out which pages we want to load
let firstPage = page - 1;
let lastPage = page + 1;
// Purge anything before the first page
for (var i=0; i<firstPage; i += 1) {
self.purgePage(i)
}
for (var i=firstPage; i<=lastPage; i += 1) {
self.loadPage(i)
}
for (var i = lastPage+1 ; i < self.pageImages.count ; i += 1) {
self.purgePage(i)
}
viewingPage = page
}
}
func loadPage(page:Int) {
if page < 0 || page >= self.pageImages.count {
// If it's outside the range of what we have to display, then do nothing
return;
}
// Load an individual page, first seeing if we've already loaded it
let pageView:UIImageView? = self.pageViews[page];
if pageView == nil {
var frame:CGRect = self.bounds;
//frame.origin.x = frame.size.width * CGFloat(page)
frame.origin.x = 320.0 * CGFloat(page)
frame.origin.y = 0.0
var newPageView:UIImageView = UIImageView(image: self.pageImages[page])
newPageView.contentMode = UIViewContentMode.ScaleAspectFit;
newPageView.frame = frame;
self.scrollView.addSubview(newPageView)
self.pageViews[page] = newPageView
}
}
func purgePage(page:Int) {
if page < 0 || page >= self.pageImages.count {
// If it's outside the range of what we have to display, then do nothing
return;
}
// Remove a page from the scroll view and reset the container array
let pageView:UIView? = self.pageViews[page];
if pageView != nil {
pageView?.removeFromSuperview()
self.pageViews[page] = nil
}
}
override init(frame: CGRect ) {
super.init(frame: frame )
self.backgroundColor = UIColor.blueColor()
// Set up the image we want to scroll & zoom and add it to the scroll view
self.pageImages.append(UIImage(named: "event1")!)
self.pageImages.append(UIImage(named: "event2")!)
self.pageImages.append(UIImage(named: "event3")!)
let pageCount = self.pageImages.count
self.scrollView.pagingEnabled = true
self.scrollView.delegate = self
self.scrollView.showsHorizontalScrollIndicator = false
self.scrollView.showsVerticalScrollIndicator = false
// Set up the page control
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = pageCount;
self.pageControl.frame = self.frame
self.scrollView.frame = self.frame
self.pageControl.translatesAutoresizingMaskIntoConstraints = false
self.scrollView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(self.pageControl)
self.addSubview(self.scrollView)
self.userInteractionEnabled = true
//Set layout
var viewsDict = Dictionary <String, UIView>()
viewsDict["control"] = self.pageControl;
viewsDict["scrollView"] = self.scrollView;
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[scrollView]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewsDict))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[control]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewsDict))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[scrollView(400)]-[control]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewsDict))
// Set up the array to hold the views for each page
for (var i = 0; i < pageCount; ++i) {
self.pageViews.append(nil)
}
// Set up the content size of the scroll view
let pagesScrollViewSize:CGSize = self.scrollView.frame.size;
self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * CGFloat(self.pageImages.count), pagesScrollViewSize.height);
// Load the initial set of pages that are on screen
self.loadVisiblePages()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
init() {
super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
}
func scrollViewDidEndDecelerating(scrollView: UIScrollView!) {
self.loadVisiblePages()
}
func ResizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
let size = image.size
let widthRatio = targetSize.width / image.size.width
let heightRatio = targetSize.height / image.size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSizeMake(size.width * heightRatio, size.height * heightRatio)
} else {
newSize = CGSizeMake(size.width * widthRatio, size.height * widthRatio)
}
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRectMake(0, 0, newSize.width, newSize.height)
// Actually do the resizing to the rect using the ImageContext stuff
//UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
image.drawInRect(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
its a ImageView where i putted scrollView and UIPageControll i can use this in my ViewController but have no idea how to use this in my TableViewCell , if somebody can give me some guidance in this then it'll be helpful for me
Please use a CollectionView instead. As the number of images will grow, your app will have performance issues.
You need to take a look at this-
putting-a-uicollectionview-in-a-uitableviewcell-in-swift
This will help you understand how to use collectionView inside a table cell.

Swift(iOS) inserting UIImage array to subview?

Swift(iOS) problem: how can I insert UIImage array to subview? I wanted to make a horizontal scroll view in view controller with very little experience with swift. Here is the code:
override func viewDidLoad() {
super.viewDidLoad()
configurePageControl()
var pictures:[UIImage] = [ ]
pictures.append(UIImage(named: "SOVERMENT1.jpg")!)
pictures.append(UIImage(named: "SOVERMENT2.jpg")!)
pictures.append(UIImage(named: "SOVERMENT3.jpg")!)
pictures.append(UIImage(named: "SOVERMENT4.jpg")!)
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
self.scrollView.pagingEnabled = true
var subView = UIView(frame: frame)
**subView.backgroundColor = [UIColor colorWithPatternImage : ]**
self.scrollView.addSubview(subView)
}
This is first problem. How can I insert pictures into subview.backgroundColor? I searched it for 1~2hours, but I couldn't find any answer.
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * 4, self.scrollView.frame.size.height)
pageControl.addTarget(self, action: Selector("changePage:"), forControlEvents: UIControlEvents.ValueChanged)
}
func configurePageControl() {
** self.pageControl.numberOfPages = pictures.count **
self.pageControl.currentPage = 0
And here. Why array pictures cannot be counted?
Unless these are repeatable pattern images, I think you want to use a UIImageView. I also don't think you need to use a UIPageControl, because you're only using one UIViewController. You can say something like:
override func viewDidLoad() {
super.viewDidLoad()
var pictures:[UIImage] = [ ]
pictures.append(UIImage(named: "SOVERMENT1.jpg")!)
pictures.append(UIImage(named: "SOVERMENT2.jpg")!)
pictures.append(UIImage(named: "SOVERMENT3.jpg")!)
pictures.append(UIImage(named: "SOVERMENT4.jpg")!)
self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * CGFloat(pictures.count), scrollView.frame.size.height)
for index in 0..<pictures.count {
var frame = CGRectZero
frame.origin.x = scrollView.frame.size.width * CGFloat(index)
frame.size = scrollView.frame.size
scrollView.pagingEnabled = true
var subView = UIImageView(frame: frame)
subView.image = pictures[index]
subView.contentMode = .ScaleAspectFit
self.scrollView.addSubview(subView)
}
}
You better use UICollectionView for such purposes
For setting the backgroundColor call the UIColor initializer:
for picture in pictures {
subView.backgroundColor = UIColor(patternImage: picture)
}

Zoom Images in Paged UIScrollView

I am creating a paging UIScrollView following this tutorial.
This is the Swift code which allow paging of images with UIScrollView. However, it has a limitation. I am unable to zoom the images.
class PagedScrollViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet var scrollView: UIScrollView!
#IBOutlet var pageControl: UIPageControl!
var pageImages: [UIImage] = []
var pageViews: [UIImageView?] = []
override func viewDidLoad() {
super.viewDidLoad()
// 1
pageImages = [UIImage(named:"photo1.png")!,
UIImage(named:"photo2.png")!,
UIImage(named:"photo3.png")!,
UIImage(named:"photo4.png")!,
UIImage(named:"photo5.png")!]
let pageCount = pageImages.count
// 2
pageControl.currentPage = 0
pageControl.numberOfPages = pageCount
// 3
for _ in 0..<pageCount {
pageViews.append(nil)
}
// 4
let pagesScrollViewSize = scrollView.frame.size
scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * CGFloat(pageImages.count), pagesScrollViewSize.height)
// 5
loadVisiblePages()
}
func loadPage(page: Int) {
if page < 0 || page >= pageImages.count {
// If it's outside the range of what you have to display, then do nothing
return
}
// 1
if let pageView = pageViews[page] {
// Do nothing. The view is already loaded.
} else {
// 2
var frame = scrollView.bounds
frame.origin.x = frame.size.width * CGFloat(page)
frame.origin.y = 0.0
// 3
let newPageView = UIImageView(image: pageImages[page])
newPageView.contentMode = .ScaleAspectFit
newPageView.frame = frame
scrollView.addSubview(newPageView)
// 4
pageViews[page] = newPageView
}
}
func purgePage(page: Int) {
if page < 0 || page >= pageImages.count {
// If it's outside the range of what you have to display, then do nothing
return
}
// Remove a page from the scroll view and reset the container array
if let pageView = pageViews[page] {
pageView.removeFromSuperview()
pageViews[page] = nil
}
}
func loadVisiblePages() {
// First, determine which page is currently visible
let pageWidth = scrollView.frame.size.width
let page = Int(floor((scrollView.contentOffset.x * 2.0 + pageWidth) / (pageWidth * 2.0)))
// Update the page control
pageControl.currentPage = page
// Work out which pages you want to load
let firstPage = page - 1
let lastPage = page + 1
// Purge anything before the first page
for var index = 0; index < firstPage; ++index {
purgePage(index)
}
// Load pages in our range
for var index = firstPage; index <= lastPage; ++index {
loadPage(index)
}
// Purge anything after the last page
for var index = lastPage+1; index < pageImages.count; ++index {
purgePage(index)
}
}
func scrollViewDidScroll(scrollView: UIScrollView!) {
// Load the pages that are now on screen
loadVisiblePages()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
How to make the images zoomable?
Problem solved using the code from
https://github.com/Charles-Hsu/ScrollViewDemo
You can create a custom class derived from UIScrollView named as ImageScrollView in which there is a UIImageView.
Create this using Interface Builder. Now in page views array you need to add ImageScrollView instead of UIImageView and you will achieve the zooming effect.

Start UIScrollView with an image of particular index from another view

I have a collectionView with multiple images. When tapping on one of them a new view is being opened - UIScrollView.
Now every time UIScrollView starts with the first image of the array from collectionView.
I am passing the index(imageNumber) of the image tapped to UIScrollView but i don't know how to make the first image shown to be the one with the index.
override func viewDidLoad() {
super.viewDidLoad()
var numberOfImagesPerALbum = data[albumNumber].count - 1
for index in 0...numberOfImagesPerALbum {
pageImages.append(UIImage(named: data[albumNumber][index]["image"]!)!)
}
var pageCount = pageImages.count
// 2
pageControl.currentPage = imageNumber
println(imageNumber)
pageControl.numberOfPages = pageCount
// 3
for _ in 0..<pageCount {
pageViews.append(nil)
}
}
override func viewDidLayoutSubviews() {
let pagesScrollViewSize = scrollView.frame.size
scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * CGFloat(pageImages.count), pagesScrollViewSize.height)
// 5
loadVisiblePages()
}
func loadPage(page: Int) {
if page < 0 || page >= pageImages.count {
// If it's outside the range of what you have to display, then do nothing
return
}
// 1
if let pageView = pageViews[page] {
// Do nothing. The view is already loaded.
} else {
// 2
var frame = scrollView.bounds
frame.origin.x = frame.size.width * CGFloat(page)
frame.origin.y = 0.0
3
let newPageView = UIImageView(image: pageImages[page])
newPageView.contentMode = .ScaleAspectFit
newPageView.frame = frame
scrollView.addSubview(newPageView)
// 4
pageViews[page] = newPageView
}
}
func purgePage(page: Int) {
if page < 0 || page >= pageImages.count {
// If it's outside the range of what you have to display, then do nothing
return
}
// Remove a page from the scroll view and reset the container array
if let pageView = pageViews[page] {
pageView.removeFromSuperview()
pageViews[page] = nil
}
}
func loadVisiblePages() {
// First, determine which page is currently visible
let pageWidth = scrollView.frame.size.width
let page = Int(floor((scrollView.contentOffset.x * 2.0 + pageWidth) / (pageWidth * 2.0)))
println("Page is \(page)")
imageTitleLabel.text = data[albumNumber][page]["title"]
imageDescriptionLabel.text = data[albumNumber][page]["text"]
// Update the page control
pageControl.currentPage = page
// Work out which pages you want to load
let firstPage = page - 1
let lastPage = page + 1
// Purge anything before the first page
for var index = 0; index < firstPage; ++index {
purgePage(index)
}
// Load pages in our range
for var index = firstPage; index <= lastPage; ++index {
loadPage(index)
}
// Purge anything after the last page
for var index = lastPage+1; index < pageImages.count; ++index {
purgePage(index)
}
}
func scrollViewDidScroll(scrollView: UIScrollView) {
// Load the pages that are now on screen
loadVisiblePages()
}
Consider using UICollectionView with UICollectionViewFlowLayout (set scrollDirection to UICollectionViewScrollDirectionHorizontal) instead of UIScrollView. Also set UICollectionView's pagingEnabled property to true.
This will save you a lot of unnecessary code and you will get the UICollectionView's - scrollToItemAtIndexPath:atScrollPosition:animated: method "for free". This should solve all your problems and make code cleaner. Good luck!

IOS image viewer in swift, programmatically

i am trying to make an imageViewer using this toturial
this toturial
i want to use the "PagedScrollViewController" example and make it using swift,
i am able to display images on screen, but i have issues with the scroll.
the scroll is not stoping between pages/photos, it scrolling freely, so that way loadVisiblePages is always called each pixel that i scroll.
probably i am missing something, can you help me with this please?
here is what i am doing :
thank you
import UIKit
class PagedScrollViewController:UIViewController,UIScrollViewDelegate {
var pageImages:[UIImage] = [UIImage]()
var pageViews:[UIView?] = [UIView]()
var scrollView:UIScrollView = UIScrollView()
var pageControl:UIPageControl = UIPageControl()
func loadVisiblePages() {
// First, determine which page is currently visible
var pageWidth:CGFloat = self.scrollView.frame.size.width;
var page = Int(floor((self.scrollView.contentOffset.x * 2.0 + pageWidth) / (pageWidth * 2.0)));
// Update the page control
self.pageControl.currentPage = page;
// Work out which pages we want to load
var firstPage = page - 1;
var lastPage = page + 1;
// Purge anything before the first page
for (var i=0; i<firstPage; i++) {
println("1) purge index \(i)")
self.purgePage(i)
}
for (var i=firstPage; i<=lastPage; i++) {
println("2) load index \(i)")
self.loadPage(i)
}
for (var i = lastPage+1 ; i < self.pageImages.count ; i++) {
println("3) purge index \(i)")
self.purgePage(i)
}
}
//
func loadPage(page:Int) {
if page < 0 || page >= self.pageImages.count {
// If it's outside the range of what we have to display, then do nothing
return;
}
// Load an individual page, first seeing if we've already loaded it
var pageView:UIView? = self.pageViews[page];
if pageView == nil {
var frame:CGRect = self.scrollView.bounds;
//frame.origin.x = frame.size.width * CGFloat(page)
frame.origin.x = 320.0 * CGFloat(page)
frame.origin.y = 0.0
var newPageView:UIImageView = UIImageView(image: self.pageImages[page])
newPageView.contentMode = UIViewContentMode.ScaleAspectFit;
newPageView.frame = frame;
self.scrollView.addSubview(newPageView)
self.pageViews[page] = newPageView
}
}
func purgePage(page:Int) {
if page < 0 || page >= self.pageImages.count {
// If it's outside the range of what we have to display, then do nothing
return;
}
// Remove a page from the scroll view and reset the container array
var pageView:UIView? = self.pageViews[page];
if pageView != nil {
pageView?.removeFromSuperview()
self.pageViews[page] = UIView()//nil
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Paged";
self.view.backgroundColor = UIColor.blueColor()
// Set up the image we want to scroll & zoom and add it to the scroll view
self.pageImages.append(UIImage(named: "first.png"))
self.pageImages.append(UIImage(named: "second.png"))
self.pageImages.append(UIImage(named: "first.png"))
self.pageImages.append(UIImage(named: "second.png"))
self.pageImages.append(UIImage(named: "first.png"))
var pageCount = self.pageImages.count
self.scrollView.delegate = self
//self.tableView.showsHorizontalScrollIndicator = false
//self.tableView.showsVerticalScrollIndicator = false
// Set up the page control
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = pageCount;
self.pageControl.setTranslatesAutoresizingMaskIntoConstraints(false)
self.scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(self.pageControl)
self.view.addSubview(self.scrollView)
//Set layout
var viewsDict = Dictionary <String, UIView>()
viewsDict["control"] = self.pageControl;
viewsDict["scrollView"] = self.scrollView;
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[scrollView]-0-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[control]-0-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[scrollView(400)]-[control]-0-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
// Set up the array to hold the views for each page
for (var i = 0; i < pageCount; ++i) {
self.pageViews.append(nil)
}
}
override func viewDidAppear(animated:Bool) {
super.viewDidAppear(animated)
// Set up the content size of the scroll view
var pagesScrollViewSize:CGSize = self.scrollView.frame.size;
self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * CGFloat(self.pageImages.count), pagesScrollViewSize.height);
// Load the initial set of pages that are on screen
self.loadVisiblePages()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// self.scrollView = nil
// self.pageControl = nil
// self.pageImages = nil
// self.pageViews = nil
}
func scrollViewDidScroll(scrollView:UIScrollView ) {
// Load the pages which are now on screen
self.loadVisiblePages()
println("scrollViewDidScroll")
}
}
the problem was i didn't set the 'self.scrollView.pagingEnabled' to true. still i am now to UIKit.
any way i made some performance improvement, and the layout is call only when needed now,
hope someone will find this usfull :)
thanks to http://www.raywenderlich.com
import UIKit
class PagedScrollViewController:UIViewController,UIScrollViewDelegate {
var pageImages:[UIImage] = [UIImage]()
var pageViews:[UIView?] = [UIView]()
var scrollView:UIScrollView = UIScrollView()
var pageControl:UIPageControl = UIPageControl()
var viewingPage = -1
func loadVisiblePages() {
// First, determine which page is currently visible
var pageWidth:CGFloat = self.scrollView.frame.size.width;
var page = Int(floor((self.scrollView.contentOffset.x * 2.0 + pageWidth) / (pageWidth * 2.0)));
/*
Check that page have changed,
in case that user drag left in first page, or drag right in last page
a 'scrollViewDidEndDecelerating' is fired
*/
if viewingPage != page {
// Update the page control
self.pageControl.currentPage = page;
// Work out which pages we want to load
var firstPage = page - 1;
var lastPage = page + 1;
// Purge anything before the first page
for (var i=0; i<firstPage; i++) {
self.purgePage(i)
}
for (var i=firstPage; i<=lastPage; i++) {
self.loadPage(i)
}
for (var i = lastPage+1 ; i < self.pageImages.count ; i++) {
self.purgePage(i)
}
viewingPage = page
}
}
func loadPage(page:Int) {
if page < 0 || page >= self.pageImages.count {
// If it's outside the range of what we have to display, then do nothing
return;
}
// Load an individual page, first seeing if we've already loaded it
var pageView:UIView? = self.pageViews[page];
if pageView == nil {
var frame:CGRect = self.scrollView.bounds;
//frame.origin.x = frame.size.width * CGFloat(page)
frame.origin.x = 320.0 * CGFloat(page)
frame.origin.y = 0.0
var newPageView:UIImageView = UIImageView(image: self.pageImages[page])
newPageView.contentMode = UIViewContentMode.ScaleAspectFit;
newPageView.frame = frame;
self.scrollView.addSubview(newPageView)
self.pageViews[page] = newPageView
}
}
func purgePage(page:Int) {
if page < 0 || page >= self.pageImages.count {
// If it's outside the range of what we have to display, then do nothing
return;
}
// Remove a page from the scroll view and reset the container array
var pageView:UIView? = self.pageViews[page];
if pageView != nil {
pageView?.removeFromSuperview()
self.pageViews[page] = nil
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Image viewer";
self.view.backgroundColor = UIColor.blueColor()
// Set up the image we want to scroll & zoom and add it to the scroll view
self.pageImages.append(UIImage(named: "message_full.png"))
self.pageImages.append(UIImage(named: "heart_full"))
self.pageImages.append(UIImage(named: "star_full.png"))
self.pageImages.append(UIImage(named: "second.png"))
self.pageImages.append(UIImage(named: "first.png"))
var pageCount = self.pageImages.count
self.scrollView.pagingEnabled = true
self.scrollView.delegate = self
self.scrollView.showsHorizontalScrollIndicator = false
self.scrollView.showsVerticalScrollIndicator = false
// Set up the page control
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = pageCount;
self.pageControl.setTranslatesAutoresizingMaskIntoConstraints(false)
self.scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(self.pageControl)
self.view.addSubview(self.scrollView)
//Set layout
var viewsDict = Dictionary <String, UIView>()
viewsDict["control"] = self.pageControl;
viewsDict["scrollView"] = self.scrollView;
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[scrollView]-0-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[control]-0-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[scrollView(400)]-[control]-0-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
// Set up the array to hold the views for each page
for (var i = 0; i < pageCount; ++i) {
self.pageViews.append(nil)
}
}
override func viewDidAppear(animated:Bool) {
super.viewDidAppear(animated)
// Set up the content size of the scroll view
var pagesScrollViewSize:CGSize = self.scrollView.frame.size;
self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * CGFloat(self.pageImages.count), pagesScrollViewSize.height);
// Load the initial set of pages that are on screen
self.loadVisiblePages()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
//TODO make cleaning
// self.scrollView = nil
// self.pageControl = nil
// self.pageImages = nil
// self.pageViews = nil
}
func scrollViewDidEndDecelerating(scrollView: UIScrollView!) {
self.loadVisiblePages()
}
}

Resources