I am trying to make practice app where i can scroll images with page control. I am able to scroll images and able to include the page control. But the problem i face is i am not able to interlink the two. Meaning to say when I scroll the images, the page control is not affected and when i change the page control, the scrolling of the images is unaffected.
I am referring to this website: http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIScrollViewDelegate>
#property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
#property (nonatomic, strong) IBOutlet UIPageControl *pageControl;
#property (nonatomic, strong) NSArray *pageImages;
#property (nonatomic, strong) NSMutableArray *pageViews;
- (void)loadVisiblePages;
- (void)loadPage:(NSInteger)page;
- (void)purgePage:(NSInteger)page;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize scrollView = _scrollView;
#synthesize pageControl = _pageControl;
#synthesize pageImages = _pageImages;
#synthesize pageViews = _pageViews;
- (void)loadPage:(NSInteger)page {
if (page < 0 || page >= self.pageImages.count) {
// If it's outside the range of what you have to display, then do nothing
return;
}
// 1
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView == [NSNull null]) {
// 2
CGRect frame = self.scrollView.bounds;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0.0f;
// 3
UIImageView *newPageView = [[UIImageView alloc] initWithImage:[self.pageImages objectAtIndex:page]];
newPageView.contentMode = UIViewContentModeScaleAspectFit;
newPageView.frame = frame;
[self.scrollView addSubview:newPageView];
// 4
[self.pageViews replaceObjectAtIndex:page withObject:newPageView];
}
}
- (void)loadVisiblePages {
// First, determine which page is currently visible
CGFloat pageWidth = self.scrollView.frame.size.width;
NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth) / (pageWidth * 2.0f));
// Update the page control
self.pageControl.currentPage = page;
// Work out which pages you want to load
NSInteger firstPage = page - 1;
NSInteger lastPage = page + 1;
// Purge anything before the first page
for (NSInteger i=0; i<firstPage; i++) {
[self purgePage:i];
}
// Load pages in our range
for (NSInteger i=firstPage; i<=lastPage; i++) {
[self loadPage:i];
}
// Purge anything after the last page
for (NSInteger i=lastPage+1; i<self.pageImages.count; i++) {
[self purgePage:i];
}
}
- (void)purgePage:(NSInteger)page {
if (page < 0 || page >= self.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
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView != [NSNull null]) {
[pageView removeFromSuperview];
[self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// Load the pages that are now on screen
[self loadVisiblePages];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// 1
self.pageImages = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"1.jpeg"],
[UIImage imageNamed:#"2.jpeg"],
[UIImage imageNamed:#"3.jpeg"],
nil];
NSInteger pageCount = self.pageImages.count;
// 2
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = pageCount;
// 3
self.pageViews = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < pageCount; ++i) {
[self.pageViews addObject:[NSNull null]];
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// 4
CGSize pagesScrollViewSize = self.scrollView.frame.size;
self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * self.pageImages.count, pagesScrollViewSize.height);
// 5
[self loadVisiblePages];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The third image is not appearing and still not able to link the pagecontrol and the scrolling of the images. Need some guidance on this...
In loadVisiblePages , change this line:
NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth) / (pageWidth * 2.0f));
with this line:
NSInteger page = self.scrollView.contentOffset.x / self.scrollView.frame.size.width;
Hope this helps.
Cheers!
EDIT: I think you haven't set [scrollView setDelegate:self]; in viewDidLoad
Related
My main motive is to create a screen just like the iPad image gallery. Images are coming from a server and can be in numbers like5 or 50 or 100. i have followed Ray Wenderlich's tutorial and gone through it step by step (http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content) but still facing the issue.
I have a main scroll view (the outer) in which I want to have these images, so that I can zoom in / out each image with scrolling (and paging) feature and also when I double tap the image it should zoom to 2x and and second time double it should return to normal.
For that I have an inner scroll view which will hold an UIImageview for each image. So that each image can zoom in / out. But when I load the image I can only see the first image and other images are not displayed. when I set background color of each scroll view and the image view too I got to know that problem is with them but I can't figure out what it is:
Where is the problem in my code, I have searched a lot on internet but could not figure out, and I have tried many other samples.
Below is my code
.h file
#import <UIKit/UIKit.h>
#interface SliderViewController : UIViewController<UIScrollViewDelegate,MFMailComposeViewControllerDelegate,UIPrintInteractionControllerDelegate,UIAlertViewDelegate,UIPopoverControllerDelegate,ButtonPressedDelegate>
{
NSMutableArray *thumbsArray;
int index;
int count;
UIView *containerView;
bool isEmpty;
NSString *firstName;
NSString *lastName;
NSMutableArray *annotatedThumbsArray;
}
#property(nonatomic,retain) NSMutableArray *thumbsArray;
#property(nonatomic, assign) int index;
#property(nonatomic, assign) int count;
#property(nonatomic,retain) NSString *firstName;
#property(nonatomic,retain) NSString *lastName;
#property(nonatomic,retain) NSMutableArray *annotatedThumbsArray;
#property(nonatomic,retain) UIPopoverController *popover_controller;
#property(nonatomic,retain) IBOutlet UIScrollView *scrollView;
#property(nonatomic,retain) IBOutlet UIPageControl *pageControl;
#end
.m file:
#import "SliderViewController.h"
#import "AppDelegate.h"
#define VIEW_FOR_ZOOM_TAG (10)
#interface SliderViewController ()
{
UITapGestureRecognizer *singleFingerTap;
CGRect rect;
}
#property (nonatomic, strong) NSMutableArray *pageImages;
#property (nonatomic, strong) NSMutableArray *pageViews;
- (void)loadVisiblePages;
- (void)loadPage:(NSInteger)page;
- (void)purgePage:(NSInteger)page;
#end
implementation SliderViewController
#synthesize pageImages,pageControl,libid,libname,thumbsArray,index,count,imageNameLabel,imageNameView,footerView,navBar,firstName,lastName,annotatedThumbsArray;
#synthesize drawingViewController,popover_controller;
#synthesize pageViews = _pageViews;
#synthesize scrollView = _scrollView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
#pragma mark - view cycle
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"THUMBSSSSS%#",thumbsArray);
pageImages = [[NSMutableArray alloc]init];
isEmpty = false;
self.scrollView.backgroundColor = [UIColor greenColor];
NSInteger pageCount = self.thumbsArray.count;
// Set up the page control
self.pageControl.currentPage = index;
self.pageControl.numberOfPages = pageCount;
// Set up the array to hold the views for each page
_pageViews = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < pageCount; ++i)
{
[_pageViews addObject:[NSNull null]];
}
self.navBar.topItem.title = [NSString stringWithFormat:#"%# %#",self.firstName,self.lastName];
singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(viewTapped:)];
[self.view addGestureRecognizer:singleFingerTap];
rect = CGRectZero;
}
- (void)centerScrollViewContents
{
CGSize boundsSize = self.scrollView.bounds.size;
CGRect contentsFrame = [self.scrollView viewWithTag:202].frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
} else {
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height)
{
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
}
else
{
contentsFrame.origin.y = 0.0f;
}
[self.scrollView viewWithTag:202].frame = contentsFrame;
}
-(void)setViewContents
{
// Set up the content size of the scroll view
CGSize pagesScrollViewSize = self.scrollView.frame.size;
self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * self.thumbsArray.count, pagesScrollViewSize.height);
[self.scrollView setContentOffset:CGPointMake(index*pagesScrollViewSize.width, 0.0f)];
self.scrollView.delegate = self;
self.navBar.topItem.title = [NSString stringWithFormat:#"%# %#",firstName,lastName];
// Load the initial set of pages that are on screen
[self loadVisiblePages];
[self centerScrollViewContents];
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self setViewContents];
[self performSelectorOnMainThread:#selector(showHeaderFooterViews) withObject:nil waitUntilDone:YES];
}
- (void)loadVisiblePages
{
// First, determine which page is currently visible
CGFloat pageWidth = self.scrollView.frame.size.width;
NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth) / (pageWidth * 2.0f));
// Update the page control
self.pageControl.currentPage = page;
// Work out which pages you want to load
isEmpty = false;
NSInteger firstPage = page - 1;
NSInteger lastPage = page + 1;
// Purge anything before the first page
for (NSInteger i=0; i<firstPage; i++) {
[self purgePage:i];
}
for (NSInteger i=firstPage; i<=lastPage; i++) {
[self loadPage:i];
}
for (NSInteger i=lastPage+1; i<self.thumbsArray.count; i++) {
[self purgePage:i];
}
thumbnail *tempThumb = [[thumbnail alloc]init];
tempThumb = [thumbsArray objectAtIndex:page];
NSString *image_name = [[NSString alloc]initWithFormat:#"%#",tempThumb.name];
tempThumb = nil;
[self.imageNameLabel setText:[NSString stringWithFormat:#"%#(%d/%d)",image_name,pageControl.currentPage+1,pageControl.numberOfPages]];
}
-(void)purgePage:(NSInteger)page
{
if(page < 0 || page >= self.thumbsArray.count+self.annotatedThumbsArray.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
UIView *pageView = [_pageViews objectAtIndex:page];
if ((NSNull*)pageView != [NSNull null])
{
[pageView removeFromSuperview];
[_pageViews replaceObjectAtIndex:page withObject:[NSNull null]];
}
}
- (void)loadPage:(NSInteger)page
{
#try
{
if (page < 0 || page >= self.thumbsArray.count)
{
// If it's outside the range of what we have to display, then do nothing
return;
}
// Load an individual page, first checking if you've already loaded it
UIView *pageView = [_pageViews objectAtIndex:page]; // page views holds
if ((NSNull*)pageView == [NSNull null] || isEmpty)
{
CGRect frame = self.scrollView.bounds;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0.0f;
frame = CGRectInset(frame, 10.0f, 0.0f);
thumbnail *tempThumb = [[thumbnail alloc]init];
tempThumb = [thumbsArray objectAtIndex:page];
NSString *image_name = [[NSString alloc]initWithFormat:#"%#",tempThumb.name];
tempThumb = nil;
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentDir = [path objectAtIndex:0];
NSString *docsPath = [documentDir stringByAppendingPathComponent:[NSString stringWithFormat:#"downloaded/%#",libid]];
UIImage *fullImage = [[UIImage alloc]init];
NSString *imagePath;
if(page<(thumbsArray.count-annotatedThumbsArray.count))
{
imagePath = [docsPath stringByAppendingPathComponent:image_name];
}
else
{
documentDir = [documentDir stringByAppendingPathComponent:libid];
imagePath = [documentDir stringByAppendingPathComponent:image_name];
}
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:imagePath];
if(fileExists)
{
NSLog(#"file NAMEEEE: - %#",image_name);
fullImage = [UIImage imageWithContentsOfFile:imagePath];
}
else
{
NSLog(#"FILE NOT FOUND");
fullImage = [UIImage imageNamed:#"noimage.jpg"];
isEmpty = true;
}
UIImageView *newPageView = [[UIImageView alloc] initWithImage:fullImage];
[newPageView setUserInteractionEnabled:YES];
newPageView.contentMode = UIViewContentModeScaleAspectFit;
newPageView.frame = frame;
newPageView.backgroundColor = [UIColor blueColor];
newPageView.tag = VIEW_FOR_ZOOM_TAG;
// ******* add each image view into a scroll view so that it can be zoomed and also can be swiped
UIScrollView *pageScrollView = [[UIScrollView alloc] initWithFrame:frame];
pageScrollView.tag = 202;
pageScrollView.minimumZoomScale = 1.0f;
pageScrollView.maximumZoomScale = 2.0f;
pageScrollView.zoomScale = 1.0f;
// pageScrollView.contentSize = newPageView.bounds.size;
pageScrollView.delegate = self;
pageScrollView.showsHorizontalScrollIndicator = NO;
pageScrollView.showsVerticalScrollIndicator = NO;
pageScrollView.backgroundColor = [UIColor yellowColor];
[self.scrollView addSubview:pageScrollView];
[pageScrollView addSubview:newPageView];
[self.scrollView bringSubviewToFront:pageScrollView];
NSLog(#"frame --> %f", frame.origin.x);
NSLog(#"frame --> %f", newPageView.frame.origin.x);
NSLog(#"frame --> %f", pageScrollView.frame.origin.x);
[self.pageViews replaceObjectAtIndex:page withObject:newPageView];
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(viewDoubleTapped:)];
doubleTapRecognizer.numberOfTapsRequired = 2;
doubleTapRecognizer.numberOfTouchesRequired = 1;
[newPageView addGestureRecognizer:doubleTapRecognizer];
}
}
#catch (NSException *exception)
{
NSLog(#"crash in - loadPage = %#", exception);
}
#finally {
// NSLog(#"finally-");
}
}
#pragma mark - double tapped
-(void)viewDoubleTapped:(UITapGestureRecognizer*)recognizer
{
//TODO: code for 2x zooming in / out
}
#pragma mrak - view tapped
-(void) viewTapped:(UITapGestureRecognizer*)recognizer
{
if([self.footerView isHidden])
{
[self performSelectorOnMainThread:#selector(showHeaderFooterViews) withObject:nil waitUntilDone:YES];
}
}
- (void)showHeaderFooterViews
{
[self.imageNameView setHidden:NO];
[self.footerView setHidden:NO];
[self performSelector:#selector(hideHeaderFooterViews) withObject:nil afterDelay:5.0];
}
- (void)hideHeaderFooterViews
{
NSLog(#"hide header footer called ");
[self.imageNameView setHidden:YES];
[self.footerView setHidden:YES];
}
#pragma mark - back button (cross button ) pressed
- (IBAction)backButtonPressed:(id)sender
{
#try
{
AppDelegate* myAppDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
int l = [[[myAppDelegate window].rootViewController childViewControllers] count];// to access the previous controller
FolderViewController *parentVC = (FolderViewController *)((UITabBarController *)[[[myAppDelegate window].rootViewController childViewControllers] objectAtIndex:l-2]); // accessing FolderviewC
[parentVC loadThumbnails];
[self.view removeFromSuperview];
[self removeFromParentViewController];
}
#catch (NSException *exception) {
NSLog(#"crash in SliderVC: backButtonPressed - %#", exception);
}
#finally {
}
}
#pragma mark - scroll view delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// Load the pages that are now on screen
[self loadVisiblePages];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
if(scrollView.tag == 202)
return [scrollView viewWithTag:VIEW_FOR_ZOOM_TAG];
return nil;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
NSLog(#"view zoomed");
[self centerScrollViewContents ];
}
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
NSLog(#"Beginning zooming");
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale{
NSLog(#"Zooming Did End");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)swipeRight:(id)sender
{
if (!((self.scrollView.contentOffset.x+self.scrollView.frame.size.width) >= self.scrollView.contentSize.width))
{
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x+self.scrollView.frame.size.width, self.scrollView.contentOffset.y)];
[self loadVisiblePages];
}
}
- (IBAction)swipeLeft:(id)sender
{
if (!((self.scrollView.contentOffset.x-self.scrollView.frame.size.width) < 0))
{
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x-self.scrollView.frame.size.width, self.scrollView.contentOffset.y)];
[self loadVisiblePages];
}
}
NOTE: I have saved my images which I am getting from server in Documents directory and accessing back them from my loadPage: method (is this the right place to access these images?)
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am using a view controller that consists of a horizontal scroll view and page controller to display a number of images in a carrousel fashion. The controller is passed an array of images and displays them starting with the first image. I obtained the code snippet from a third party tutorial and have spent the last day trying to understand it and change its functionality. I have been trying to make the carrousel start at the middle of the array of images, (i.e. if there are nine images start at image five and allow for scrolling both ways) but have had no luck in modifying the existing code. I have played around with the loadPage and loadVisiblePages methods but have had little luck. Here are the .m and .h files.
PeekPagedScrollViewController.m
#import "PeekPagedScrollViewController.h"
#interface PeekPagedScrollViewController ()
#property (nonatomic, strong) NSMutableArray *pageViews;
- (void)loadVisiblePages;
- (void)loadPage:(NSInteger)page;
- (void)purgePage:(NSInteger)page;
#end
#implementation PeekPagedScrollViewController
#synthesize scrollView = _scrollView;
#synthesize pageControl = _pageControl;
#synthesize gallaryType = _gallaryType;
#synthesize pageImages = _pageImages;
#synthesize pageViews = _pageViews;
#synthesize startPoint = _startPoint;
#pragma mark -
- (void)loadVisiblePages
{
// First, determine which page is currently visible
CGFloat pageWidth = self.scrollView.frame.size.width;
NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth) / (pageWidth * 2.0f));
// Work out which pages we want to load
NSInteger firstPage = page - 1;
NSInteger lastPage = page + 1;
// Purge anything before the first page
for (NSInteger i=0; i<firstPage; i++) {
[self purgePage:i];
}
for (NSInteger i=firstPage; i<=lastPage; i++) {
[self loadPage:i];
}
for (NSInteger i=lastPage+1; i<self.pageImages.count; i++) {
[self purgePage:i];
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)loadPage:(NSInteger)page
{
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
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView == [NSNull null])
{
CGRect frame = self.scrollView.bounds;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0.0f;
frame = CGRectInset(frame, 10.0f, 0.0f);
UIImageView *newPageView = [[UIImageView alloc] initWithImage:[self.pageImages objectAtIndex:page]];
newPageView.contentMode = UIViewContentModeScaleAspectFit;
newPageView.frame = frame;
[self addTapHandler:newPageView actionSelector:#selector(handleSingleTap:)];
[self.scrollView addSubview:newPageView];
[self.pageViews replaceObjectAtIndex:page withObject:newPageView];
}
}
- (void)purgePage:(NSInteger)page
{
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
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView != [NSNull null])
{
[pageView removeFromSuperview];
[self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];
}
}
- (void)addTapHandler:(UIView *)pageView actionSelector:(SEL)actionSelector
{
[pageView setUserInteractionEnabled:YES];
UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:actionSelector];
[pageView addGestureRecognizer:tapper];
}
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
if (_gallaryType == 0)
{
NSString *messageString = #"Use as profile image?";
UIAlertView *imageAlertView = [[UIAlertView alloc] initWithTitle:#"Select Image" message:messageString delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[imageAlertView show];
}
else if (_gallaryType == 1)
{
NSString *messageString = #"Use as cover photo?";
UIAlertView *imageAlertView = [[UIAlertView alloc] initWithTitle:#"Select Image" message:messageString delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[imageAlertView show];
}
}
-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1)
{
// add yes button text here
}
}
#pragma mark -
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setTranslatesAutoresizingMaskIntoConstraints:YES];
self.title = #"Paged";
NSInteger pageCount = self.pageImages.count;
// Set up the array to hold the views for each page
self.pageViews = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < pageCount; ++i)
{
[self.pageViews addObject:[NSNull null]];
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Set up the content size of the scroll view
CGSize pagesScrollViewSize = self.scrollView.frame.size;
self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * self.pageImages.count, pagesScrollViewSize.height);
// Load the initial set of pages that are on screen
[self loadVisiblePages];
}
- (IBAction)back:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.scrollView = nil;
self.pageControl = nil;
self.pageImages = nil;
self.pageViews = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// Load the pages which are now on screen
[self loadVisiblePages];
}
#end
PeekPagedScrollViewController.h
#import <UIKit/UIKit.h>
#interface PeekPagedScrollViewController : UIViewController <UIScrollViewDelegate, UIAlertViewDelegate>
#property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
#property (nonatomic, strong) IBOutlet UIPageControl *pageControl;
#property (nonatomic, strong) NSArray *pageImages;
#property (nonatomic) NSInteger *gallaryType;
#property (nonatomic) NSInteger *startPoint;
- (IBAction)back:(id)sender;
#end
Thanks
just take scroll view
set its content size/// that is how much it is going to scroll
scrollView.contentSize = CGSizeMake(scrollView.bounds.size.width*imageArray.count,scrollView.frame.size.height);
// and then set the starting point
scrollView.contentOffset = CGPointMake(currentpage * scrollView.bounds.size.width, 0);
I think you only need to scroll to a particular page. The rest of the thing will automatically happens. Try like this
CGRect frame = self.scrollView.frame;
frame.origin.x = (frame.size.width * page);
frame.origin.y = 0;
[self.scrollView scrollRectToVisible:frame animated:YES];
Here page is the page number(eg 5)
There are a few threads out there related to this issues, but could not find a solid solution. Any help would be appreciated. This code works great if you give it one image. Zooms in perfect. You give it two images it scrolls threws the images fine but when you go to zoom in it always zooms into the first image? Not sure why the viewForZoomingInScrollView method doesn't figure out which view you are on. Code posted below
PagedScrollViewController.h
#import <UIKit/UIKit.h>
#interface PagedScrollViewController : UIViewController <UIScrollViewDelegate>
#property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
#property (nonatomic, strong) IBOutlet UIPageControl *pageControl;
#property (nonatomic, strong) IBOutlet UIButton *cancelButtonClicked;
#property (nonatomic, strong) IBOutlet UILabel *headerTitle;
#property (nonatomic, strong) IBOutlet NSString *headerTitleS;
#property (nonatomic, strong) IBOutlet NSMutableArray *pageImages;
#property (nonatomic, strong) IBOutlet UITextView *caption;
#property (weak, nonatomic) IBOutlet UINavigationBar *navigationBar;
#property (nonatomic, strong) NSMutableArray *captionArray;
-(IBAction)cancelButtonClicked:(id)sender;
#end
PagedScrollViewController.m
#interface PagedScrollViewController ()
#property (nonatomic, strong) NSMutableArray *pageViews;
- (void)loadVisiblePages;
- (void)loadPage:(NSInteger)page;
- (void)purgePage:(NSInteger)page;
#end
#implementation PagedScrollViewController
#synthesize scrollView = _scrollView;
#synthesize pageControl = _pageControl;
#synthesize pageImages = _pageImages;
#synthesize pageViews = _pageViews;
#synthesize cancelButtonClicked = _cancelButtonClicked;
#synthesize headerTitle = _headerTitle;
#synthesize headerTitleS = _headerTitleS;
#synthesize caption = _caption;
#synthesize captionArray = _captionArray;
- (void)loadVisiblePages {
// First, determine which page is currently visible
CGFloat pageWidth = self.scrollView.frame.size.width;
NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth)
/ (pageWidth * 2.0f));
// Update the page control
self.pageControl.currentPage = page;
NSObject *captionObject = [self.captionArray objectAtIndex:page];
NSString *captionString = [NSString stringWithFormat:#"%#", [captionObject
valueForKey:#"caption"]];
self.caption.text = captionString;
// Work out which pages we want to load
NSInteger firstPage = page - 1;
NSInteger lastPage = page + 1;
// Purge anything before the first page
for (NSInteger i=0; i<firstPage; i++) {
[self purgePage:i];
}
for (NSInteger i=firstPage; i<=lastPage; i++) {
[self loadPage:i];
}
for (NSInteger i=lastPage+1; i<self.pageImages.count; i++) {
[self purgePage:i];
}
}
- (void)loadPage:(NSInteger)page {
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
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView == [NSNull null]) {
CGRect frame = self.scrollView.bounds;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0.0f;
UIImageView *newPageView = [[UIImageView alloc] initWithImage:[self.pageImages
objectAtIndex:page]];
newPageView.contentMode = UIViewContentModeScaleAspectFit;
newPageView.frame = CGRectMake((page*320), 0, 310, 320);
self.scrollView.maximumZoomScale = 1.3;
self.scrollView.contentSize = CGSizeMake(320*[self.pageImages count],389);
self.scrollView.frame = CGRectMake(320*(self.pageControl.currentPage), 44, 310,
370);
[self.scrollView addSubview:newPageView];
[self.pageViews replaceObjectAtIndex:page withObject:newPageView];
}
}
- (void)purgePage:(NSInteger)page {
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
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView != [NSNull null]) {
[pageView removeFromSuperview];
[self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];
}
}
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView {
self.scrollView.contentSize = CGSizeMake(320*[self.pageImages count],389);
return [self.scrollView.subviews objectAtIndex:self.pageControl.currentPage];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView.delegate = self;
self.headerTitle.text = self.headerTitleS;
// Set up the image we want to scroll & zoom and add it to the scroll view
NSInteger pageCount = self.pageImages.count;
// Set up the page control
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = pageCount;
// Set up the array to hold the views for each page
self.pageViews = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < pageCount; ++i) {
[self.pageViews addObject:[NSNull null]];
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Load the initial set of pages that are on screen
[self loadVisiblePages];
}
- (void)viewDidUnload {
[super viewDidUnload];
self.scrollView = nil;
self.pageControl = nil;
self.pageImages = nil;
self.pageViews = nil;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
[self loadVisiblePages];
}
-(IBAction)cancelButtonClicked:(id)sender{
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
This is what I found to work. Supports multiple images with paging and zooming. Enjoy!
#define VIEW_FOR_ZOOM_TAG (1)
#implementation SVViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIScrollView *mainScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
mainScrollView.pagingEnabled = YES;
mainScrollView.showsHorizontalScrollIndicator = NO;
mainScrollView.showsVerticalScrollIndicator = NO;
CGRect innerScrollFrame = mainScrollView.bounds;
for (NSInteger i = 0; i < 3; i++) {
UIImageView *imageForZooming = [[UIImageView alloc] initWithImage:[UIImage imageNamed:
[NSString stringWithFormat:#"page%d", i + 1]]];
imageForZooming.tag = VIEW_FOR_ZOOM_TAG;
UIScrollView *pageScrollView = [[UIScrollView alloc] initWithFrame:innerScrollFrame];
pageScrollView.minimumZoomScale = 1.0f;
pageScrollView.maximumZoomScale = 2.0f;
pageScrollView.zoomScale = 1.0f;
pageScrollView.contentSize = imageForZooming.bounds.size;
pageScrollView.delegate = self;
pageScrollView.showsHorizontalScrollIndicator = NO;
pageScrollView.showsVerticalScrollIndicator = NO;
[pageScrollView addSubview:imageForZooming];
[mainScrollView addSubview:pageScrollView];
if (i < 2) {
innerScrollFrame.origin.x += innerScrollFrame.size.width;
}
}
mainScrollView.contentSize = CGSizeMake(innerScrollFrame.origin.x +
innerScrollFrame.size.width, mainScrollView.bounds.size.height);
[self.view addSubview:mainScrollView];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return [scrollView viewWithTag:VIEW_FOR_ZOOM_TAG];
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate {
return NO;
}
#end
I am trying to make practice app where i can scroll images with page control. I am able to scroll images and able to include the page control. But the problem i face is i am not able to interlink the two. Meaning to say when I scroll the images, the page control is not affected and when i change the page control, the scrolling of the images is unaffected.
I have referred to this: http://www.iosdevnotes.com/2011/03/uiscrollview-paging/ for the scrolling with page control.
Viewcontroller.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIScrollViewDelegate>{
UIScrollView *scrollView;
UIPageControl *pageControl;
BOOL pageControlBeingUsed;
}
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
#property (nonatomic, retain) IBOutlet UIPageControl *pageControl;
- (IBAction)changePage;
#end
Viewcontroller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize scrollView,pageControl;
- (void)scrollViewDidScroll:(UIScrollView *)sender {
if (!pageControlBeingUsed) {
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *images = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"1.jpeg"],[UIImage imageNamed:#"2.jpeg"],[UIImage imageNamed:#"3.jpeg" ], nil];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * images.count, self.scrollView.frame.size.height);
for (int i = 0; i < images.count; i++) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
UIImageView* imgView = [[UIImageView alloc] init];
imgView.image = [images objectAtIndex:i];
imgView.frame = frame;
[scrollView addSubview:imgView];
}
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = images.count;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.scrollView = nil;
self.pageControl = nil;
}
- (IBAction)changePage{
// update the scroll view to the appropriate page
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlBeingUsed = YES;
}
#end
Need some guidance on this... Thanks..
I learned page control and scrollView from this tutorial, its very clearly written, hope it helps you http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content
Check whether you have set the delegate of the scroll view to the ViewController
And you have just set the pageControlBeingUsed to YES or NO and you have not used it anywhere in the ViewController
I have this code, modified version of Apple's PageScrollView sample. Here the differnce is that m using ViewControllers instead of UIView.
MyClass.h
#interface MyClass : UIViewController {
UIScrollView *scrollView;
UIPageControl *pageControl;
NSMutableArray *viewControllers;
BOOL pageControlUsed;
}
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
#property (nonatomic, retain) IBOutlet UIPageControl *pageControl;
#property (nonatomic, retain) NSMutableArray *viewControllers;
- (IBAction)changePage:(id)sender;
#end
MyClass.m
#import "MyClass.h"
#import "MyViewController.h"
#import "MyViewControllerZero.h"
#import "MyViewControllerOne.h"
#import "MyViewControllerTwo.h"
static NSUInteger kNumberOfPages = 3;
#interface MyClass (PrivateMethods)
- (void)loadScrollViewWithPage:(int)page;
- (void)scrollViewDidScroll:(UIScrollView *)sender;
#end
#implementation MyClass
#synthesize scrollView, pageControl, viewControllers;
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
}
return self;
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < kNumberOfPages; i++) {
[controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
// a page is the width of the scroll view
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height);
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.scrollsToTop = NO;
scrollView.delegate = self;
pageControl.numberOfPages = kNumberOfPages;
pageControl.currentPage = 0;
// pages are created on demand
// load the visible page
// load the page on either side to avoid flashes when the user starts scrolling
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
}
- (void)loadScrollViewWithPage:(int)page {
// if (page < 0) return;
// if (page >= kNumberOfPages) return;
if(page==0)
{
MyViewControllerZero *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{ controller = [[MyViewControllerZero alloc] init];
[viewControllers replaceObjectAtIndex:page withObject:controller];
if (nil == controller.view.superview) {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
}
if(page==1)
{
MyViewControllerOne *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{ controller = [[MyViewControllerOne alloc] init];
[viewControllers replaceObjectAtIndex:page withObject:controller];
if (nil == controller.view.superview) {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
}
if(page==2)
{
MyViewControllerTwo *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{ controller = [[MyViewControllerTwo alloc] init];
[viewControllers replaceObjectAtIndex:page withObject:controller];
if (nil == controller.view.superview) {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
}
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
if (pageControlUsed) {
return;
}
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = page;
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
// A possible optimization would be to unload the views+controllers which are no longer visible
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
pageControlUsed = NO;
}
// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControlUsed = NO;
}
- (IBAction)changePage:(id)sender {
int page = pageControl.currentPage;
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
// update the scroll view to the appropriate page
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
// Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above.
pageControlUsed = YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[viewControllers release];
[scrollView release];
[pageControl release];
[super dealloc];
}
#end
The Above code works absolutely fine in the potrait mode. But when i change the orientation,the whole paging gets screwed up.. :((
please help me to resolve this problem..
Apple didn't design UIViewController to work at any point in a view hierarchy. The views that you're adding to your UIScrollView are managed by view controllers, but I think you'll find that the view controllers for those views don't receive rotation events.
You could try to manually forward all events from the scroll view's controller to the child view controllers, but I think you'll find that to be tedious and error prone. I'd suggest instead that you simply use a single view controller for the scroll view and its child views.