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.
}