UIscrollview if imagesview how to add zoom? - iphone

Hello everyone i need to add zoom in uiscrollview containing several uiimageviews. Here is my code how I am doing it but its not working properly
- (void)setupPage
{
scrollView.delegate = self;
[self.scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
NSUInteger nimages = 0;
CGFloat cx = 0;
for (; ; nimages++) {
//Maquette final_Print 2.png
NSString *imageName = [NSString stringWithFormat:#"rint %d.png", (nimages + 1)];
UIImage *image = [UIImage imageNamed:imageName];
if (image == nil) {
break;
}
imageView = [[UIImageView alloc] initWithImage:image];
[imageView setContentMode:UIViewContentModeScaleToFill];
CGRect rect = imageView.frame;
rect.size.height = 1004;
rect.size.width = 768;
rect.origin.x = ((scrollView.frame.size.width - 768) / 2) + cx;
rect.origin.y = ((scrollView.frame.size.height - 1004) / 2);
imageView.frame = rect;
[scrollView addSubview:imageView];
[imageView release];
cx += scrollView.frame.size.width;
}
[scrollView setContentSize:CGSizeMake(cx, 1004)];
scrollView.minimumZoomScale = scrollView.frame.size.width / 768;
scrollView.maximumZoomScale = 2.0;
[scrollView setZoomScale:scrollView.minimumZoomScale];
}
// Code for handling zooming :
#pragma mark -
#pragma mark UIScrollView ZOOM
//- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
// imageView.frame = [self centeredFrameForScrollView:scrollView andUIView:imageView];;
//}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return imageView;
}
- (CGRect)centeredFrameForScrollView:(UIScrollView *)scroll andUIView:(UIView *)rView {
CGSize boundsSize = scroll.bounds.size;
CGRect frameToCenter = rView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width) {
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
}
else {
frameToCenter.origin.x = 0;
}
// center vertically
if (frameToCenter.size.height < boundsSize.height) {
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
}
else {
frameToCenter.origin.y = 0;
}
return frameToCenter;
}
When I am trying to zoom its not working as expected. And also i cannot swipe left or right...

.m File
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.theImageView;
}
- (CGRect)centeredFrameForScrollView:(UIScrollView *)scroll andUIView:(UIView *)rView {
CGSize boundsSize = scroll.bounds.size;
CGRect frameToCenter = rView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width) {
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
}
else {
frameToCenter.origin.x = 0;
}
// center vertically
if (frameToCenter.size.height < boundsSize.height) {
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
}
else {
frameToCenter.origin.y = 0;
}
return frameToCenter;
}
-(void)scrollViewDidZoom:(UIScrollView *)scrollView
{
self.theImageView.frame = [self centeredFrameForScrollView:self.theScrollView andUIView:self.theImageView];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.resourceData setLength:0];
self.filesize = [NSNumber numberWithLongLong:[response expectedContentLength]];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.resourceData appendData:data];
NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[self.resourceData length]];
self.progressBar.progress = [resourceLength floatValue] / [self.filesize floatValue];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
self.theImage = [[UIImage alloc]initWithData:resourceData];
self.theImageView.frame = CGRectMake(0, 0, self.theImage.size.width, self.theImage.size.height);
self.theImageView.image = self.theImage;
self.theScrollView.minimumZoomScale = self.theScrollView.frame.size.width / self.theImageView.frame.size.width;
self.theScrollView.maximumZoomScale = 2.0;
[self.theScrollView setZoomScale:self.theScrollView.minimumZoomScale];
self.theScrollView.contentSize = self.theImageView.frame.size;
self.theLabel.hidden = YES;
self.progressBar.hidden = YES;
}
-(void)setImageInImageView
{
NSURLRequest *req = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:self.imageLink]];
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:req delegate:self];
if (conn)
{
self.resourceData = [NSMutableData data];
}
else
{
NSLog(#"Connection failed: IMageViewerViewController");
}
}
-(void)loadView
{
self.filesize = [[NSNumber alloc]init];
self.progressBar = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];
self.progressBar.frame = CGRectMake(20, 240, 280, 40);
[self.progressBar setProgress:0.0];
self.theImageView = [[[UIImageView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame]]autorelease];
self.theScrollView = [[[UIScrollView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame]]autorelease];
self.theScrollView.delegate = self;
[self.theScrollView addSubview:self.theImageView];
self.view = self.theScrollView;
self.theLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 200, 320, 40)];
self.theLabel.font = [UIFont boldSystemFontOfSize:15.0f];
self.theLabel.text = #"Please wait, file is being downloaded";
self.theLabel.textAlignment = UITextAlignmentCenter;
self.theLabel.hidden = NO;
[self.view addSubview:self.progressBar];
[self.view bringSubviewToFront:self.progressBar];
[self.view addSubview:self.theLabel];
[self.view bringSubviewToFront:self. theLabel];
[self performSelectorOnMainThread:#selector(setImageInImageView) withObject:nil waitUntilDone:NO];
}
.h File
#interface ImageViewerViewController : UIViewController<UIScrollViewDelegate, NSURLConnectionDelegate, NSURLConnectionDataDelegate>
#property (nonatomic, retain) IBOutlet UIImageView *theImageView;
#property (nonatomic, retain) IBOutlet UIScrollView *theScrollView;
#property (nonatomic, retain) NSString *imageLink;
#property (nonatomic, retain) UIImage *theImage;
#property (nonatomic, retain) UILabel *theLabel;
#property (nonatomic, retain) UIProgressView *progressBar;
#property (nonatomic, retain) NSMutableData *resourceData;
#property (nonatomic, retain) NSNumber *filesize;
#end

All you need to do is add your UIImageView (or any view you want to zoom) inside your UIScrollView.
Set your maxZoomScale on your UIScrollView to any value higher than 1.0f.
Set yourself as the delegate of your UIScrollView and return the UIImageView in the viewForZooming delegate method.
That's it. No pinch gesture needed, no nothing. UIScrollView handles pinch zooming for you.

Related

Zooming in UIscrollview makes images subviews disappear

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?)

iOS Multiple Images Paging and Zooming Issues

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

Changing page using pagecontroller

I need some help to implement the function that change the page on pagecontroller. I have a UIPageController , the number of pages is variable.
Here is my code :
.h**
#property (nonatomic, retain) IBOutlet UIScrollView *vosvehiculeScrollView;
#property (nonatomic, retain) IBOutlet UIPageControl *pageControlVehiculePossedee;
- (IBAction) changePage:(id) sender;
- (void) loadScrollViewWithPage: (int) page;
.m*
- (void)viewDidLoad
{
[super viewDidLoad];
[self getVehicules];
vosvehiculeScrollView.pagingEnabled = YES;
vosvehiculeScrollView.showsHorizontalScrollIndicator = NO;
vosvehiculeScrollView.showsVerticalScrollIndicator = NO;
vosvehiculeScrollView.scrollsToTop = NO;
pageControlVehiculePossedee.numberOfPages=[vehiculesPossede count];
pageControlVehiculePossedee.currentPage=0;
[self loadScrollViewWithPage:0];
votreVehiculeLabel.text=#"Votre véhicule";
vehiculesPossedesArray = [[NSMutableArray alloc] initWithObjects:#"Annee modele", #"Transmission",#"Carburant", nil];
}
- (void) loadScrollViewWithPage: (int) page {
if (page < 0) return;
if (page >= [vehiculesPossede count]) return;
tableViewVehiculesPossedes=[[UITableView alloc] initWithFrame:CGRectMake(3, 80, 315, 171) style:UITableViewStyleGrouped];
tableViewVehiculesPossedes.bounces=NO;
tableViewVehiculesPossedes.backgroundColor=[UIColor clearColor];
[tableViewVehiculesPossedes setDelegate:self];
[tableViewVehiculesPossedes setDataSource:self];
[self.vosvehiculeScrollView addSubview:tableViewVehiculesPossedes];
nameVehiculeLabel.text=[[vehiculesPossede objectAtIndex:page] valueForKey:#"modele"];
self.transmissionString=[[vehiculesPossede objectAtIndex:page]valueForKey:#"transmision"];
self.carburantString=[[vehiculesPossede objectAtIndex:page] valueForKey:#"carburant"];
self.anneeModelString=[[vehiculesPossede objectAtIndex:page] valueForKey:#"modele_annee"];
self.anneeString=[[vehiculesPossede objectAtIndex:page]valueForKey:#"annee"];
if(page==0){
NSLog(#"0");
}
else NSLog(#"1");
}
- (IBAction) changePage:(id) sender
{
NSLog(#"page changed");
/* CGRect frame;
frame.origin.x = self.vosvehiculeScrollView.frame.size.width * self.pageControlVehiculePossedee.currentPage;
frame.origin.y = 0;
frame.size = self.vosvehiculeScrollView.frame.size;
NSLog(#"current page %d",pageControlVehiculePossedee.currentPage);
[self.vosvehiculeScrollView scrollRectToVisible:frame animated:YES];*/
[self loadScrollViewWithPage:1];
pageControlUsed = YES;
}
and I get Program received signal: “EXC_BAD_ACCESS”. How should I implement the changePage method to make it ok? Please help..
Thanks in advance...
I did as follow
- (IBAction)actionBtnNext:(id)sender
{
if (pageNumber == kNumberOfPages-2) {
pageNumber = kNumberOfPages-2;
}
else {
pageNumber++;
}
CGFloat pageWidth = scrollView.frame.size.width*pageNumber;
[scrollView setContentOffset:CGPointMake(pageWidth,0.0) animated:YES];
}
Let me know if you do have any questions.
Regards

iOS - CAKeyFrameAnimation - Not Playing

I have looked at a few guides for CAKeyFrameAnimation and I am failing to see how to trigger them. The only thing I can think of is that I have to use it as a return, but that doesn't make much sense to me.
-H File-
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface ImageSequenceViewController : UIViewController
<UIGestureRecognizerDelegate>{
UISwipeGestureRecognizer *swipeLeftRecognizer;
NSMutableArray *myImages;
IBOutlet UIImageView *imageView;
IBOutlet UIImageView *bView;
IBOutlet UISegmentedControl *segmentedControl;
}
#property (nonatomic, retain) UISwipeGestureRecognizer *swipeLeftRecognizer;
#property (nonatomic, retain) UIImageView *imageView;
#property (nonatomic, retain) IBOutlet UISegmentedControl *segmentedControl;
-(IBAction)takeLeftSwipeRecognitionEnabledFrom:(UISegmentedControl *)aSegmentedControl;
-(IBAction)ButtonPressed1: (id)sender;
#end
-M File-
#import "ImageSequenceViewController.h"
#implementation ImageSequenceViewController
#synthesize swipeLeftRecognizer;
#synthesize imageView;
#synthesize segmentedControl;
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
//CUSTOM CODE
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
-(void)loadLeft {
//aView = [[UIImageView alloc] initWithFrame:self.view.frame];
CALayer *layer = [CALayer layer];
[layer setFrame:CGRectMake(0.0,
0.0,
[[self view] frame].size.height,
[[self view] frame].size.width)];
myImages = [[NSMutableArray alloc] init];
for(NSUInteger count=0; count<100; count++){
NSString *fileName;
if (count < 10)
{
fileName = [NSString stringWithFormat:#"trailerRotation_000%d", count];
}
else if (10 <= count < 100)
{
fileName = [NSString stringWithFormat:#"trailerRotation_00%d", count];
}
else
{
fileName = [NSString stringWithFormat:#"trailerRotation_0%d", count];
}
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:#"jpg"];
//UIImage *image = [[UIImage alloc] initWithContentsOfFile:fileName];
//[myImages addObject:image];
[myImages addObject:[UIImage imageWithContentsOfFile:path]];
}
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:#"Contents"];
[anim setDuration:0.10];
[anim setCalculationMode:kCAAnimationDiscrete];
[anim setRepeatCount:1];
[anim setValues:myImages];
[self.view.layer addSublayer:layer];
[layer addAnimation:anim forKey:#"images"];
//aView.animationImages = myImages;
//aView.animationDuration = 10.00;
//aView.animationRepeatCount = 1;
}
-(void)loadRight {
bView = [[UIImageView alloc] initWithFrame:self.view.frame];
myImages = [[NSMutableArray alloc] init];
for(NSUInteger count=99; count>0; count--){
NSString *countString;
if (count < 10)
{
countString = #"000";
countString = [countString stringByAppendingFormat:#"%d", count];
}
else if (10 <= count < 100)
{
countString = #"00";
countString = [countString stringByAppendingFormat:#"%d", count];
}
else if (100 <= count < 1000)
{
countString = #"00";
countString = [countString stringByAppendingFormat:#"%d", count];
}
NSLog(#"%d", count);
NSString *fileName = #"trailerRotation_";
fileName = [fileName stringByAppendingFormat:countString];
fileName = [fileName stringByAppendingFormat:#".jpg"];
[myImages addObject:[UIImage imageNamed:fileName]];
}
bView.animationImages = myImages;
bView.animationDuration = 10.00;
bView.animationRepeatCount = 1;
}
- (void)viewDidLoad {
[super viewDidLoad];
imageView = [[UIImageView alloc] initWithFrame:self.view.frame];
[imageView setImage:[UIImage imageNamed:#"trailerRotation_0000.jpg"]];
//[self.view addSubview:imageView];
[self loadLeft];
[self loadRight];
UIGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[self.view addGestureRecognizer:recognizer];
[recognizer release];
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
self.swipeLeftRecognizer = (UISwipeGestureRecognizer *) recognizer;
swipeLeftRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
if ([segmentedControl selectedSegmentIndex] == 0) {
[self.view addGestureRecognizer:swipeLeftRecognizer];
}
self.swipeLeftRecognizer = (UISwipeGestureRecognizer *) recognizer;
[recognizer release];
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.segmentedControl = nil;
self.swipeLeftRecognizer = nil;
self.imageView = nil;
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)viewDidAppear:(BOOL)animated {
[self becomeFirstResponder];
}
-(void)startItLeft {
NSLog(#"Left");
//[aView startAnimating];
//[self.view addSubview:aView];
//[aView release];
[bView release];
}
-(void)startItRight {
NSLog(#"Right");
[bView startAnimating];
[self.view addSubview:bView];
//[aView release];
[bView release];
}
//- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
//}
//- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
//}
//- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {
//}
-(IBAction)ButtonPressed1:(id)sender
{
NSLog(#"Button");
//[aView stopAnimating];
[bView stopAnimating];
//[self loadLeft];
[self loadRight];
}
-(IBAction)takeLeftSwipeRecognitionEnabledFrom:(UISegmentedControl *) aSegmentControl {
if ([aSegmentControl selectedSegmentIndex] == 0) {
[self.view addGestureRecognizer:swipeLeftRecognizer];
}
else {
[self.view removeGestureRecognizer:swipeLeftRecognizer];
}
}
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *) recognizer {
//CGPoint location = [recognizer locationInView:self.view];
//[self showImageWithText:#"swipe" atPoint:location];
if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft) {
//[self startItLeft];
}
else {
[self startItRight];
}
}
//CUSTOM CODE
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return 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)dealloc {
[super dealloc];
}
#end
I'm rather new to iOS development so any advice is helpful.
Thanks.
Try:
[myImages addObject:(id)[UIImage imageWithContentsOfFile:path].CGImage];
Since the CAKeyFrameAnimation expects CGImageRef objects.
It looks like you're trying to load up 100 images and cycle them all within the space of 0.1 second. Not only is that pretty ridiculous (that's 1000fps right there, and CoreAnimation is capped at 60fps), but it's likely to take longer than 0.1 seconds for CoreAnimation to copy all the images before it even starts, which means that it will have finished before it started (and therefore no animation will occur).
I'll admit it was a PEBKAC error.
Thanks all for your help.

UIPageControl bug: showing one bullet first and then showing everything

I have some strange behavior using a UIPageControl:
First it appears showing only one bullet, then when I move the scroll view all the bullets appear correctly. Is there something I'm missing before I add it as a subview?
Here is my code imageScrollView.h :
#interface ImageScrollView : UIView <UIScrollViewDelegate> {
NSMutableDictionary *photos;
BOOL *pageControlIsChangingPage;
UIPageControl *pageControl;
}
#property (nonatomic, copy) NSMutableDictionary *photos;
#property (nonatomic, copy) UIPageControl *pageControl;
#end
Here is the code for imageScrollView.m:
#import "ImageScrollView.h"
#implementation ImageScrollView
#synthesize photos, pageControl;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
}
return self;
}
- (void) drawRect:(CGRect)rect
{
[self removeAllSubviews];
UIScrollView *scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,self.frame.size.width,self.frame.size.height)];
[scroller setDelegate:self];
[scroller setBackgroundColor:[UIColor grayColor]];
[scroller setShowsHorizontalScrollIndicator:NO];
[scroller setPagingEnabled:YES];
NSUInteger nimages = 0;
CGFloat cx= 0;
for (NSDictionary *myDictionaryObject in photos)
{
if (![myDictionaryObject isKindOfClass:[NSNull class]]) {
NSString *photo =[NSString stringWithFormat:#"http://www.techbase.com.mx/blog/%#",[myDictionaryObject objectForKey:#"filepath"]];
NSDictionary *data = [myDictionaryObject objectForKey:#"data"];
UIView *imageContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height - 30)];
TTImageView *imageView = [[TTImageView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height - 30)];
imageView.urlPath=photo;
[imageContainer addSubview:imageView];
UILabel *caption = [[UILabel alloc] initWithFrame:CGRectMake(0,imageView.frame.size.height,imageView.frame.size.width,10)];
[caption setText:[NSString stringWithFormat:#"%#",[data objectForKey:#"description"]]];
[caption setBackgroundColor:[UIColor grayColor]];
[caption setTextColor:[UIColor whiteColor]];
[caption setLineBreakMode:UILineBreakModeWordWrap];
[caption setNumberOfLines:0];
[caption sizeToFit];
[caption setFont:[UIFont fontWithName:#"Georgia" size:10.0]];
[imageContainer addSubview:caption];
CGRect rect = imageContainer.frame;
rect.size.height = imageContainer.size.height;
rect.size.width = imageContainer.size.width;
rect.origin.x = ((scroller.frame.size.width - scroller.size.width) / 2) + cx;
rect.origin.y = ((scroller.frame.size.height - scroller.size.height) / 2);
imageContainer.frame=rect;
[scroller addSubview:imageContainer];
[imageView release];
[imageContainer release];
[caption release];
nimages++;
cx +=scroller.frame.size.width;
}
}
[scroller setContentSize:CGSizeMake(nimages * self.frame.size.width, self.frame.size.height)];
[self addSubview:scroller];
pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(self.frame.size.width/2, self.frame.size.height -20, (self.frame.size.width/nimages)/2, 20)];
pageControl.numberOfPages=nimages;
[self addSubview:pageControl];
[scroller release];
}
-(void)dealloc {
[pageControl release];
[super dealloc];
}
-(void)scrollViewDidScroll:(UIScrollView *)_scrollView{
if(pageControlIsChangingPage){
return;
}
CGFloat pageWidth = _scrollView.frame.size.width;
int page = floor((_scrollView.contentOffset.x - pageWidth /2) / pageWidth) + 1;
pageControl.currentPage = page;
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)_scrollView{
pageControlIsChangingPage = NO;
}
#end
Since you're drawing the UIPageControl in the drawRect method, you need to call the setNeedsLayout method of this control after you initialize it. Otherwise it won't render itself properly until an event that forces this redrawing is called.
pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(self.frame.size.width/2, self.frame.size.height -20, (self.frame.size.width/nimages)/2, 20)];
pageControl.numberOfPages=nimages;
[pageControl setNeedsLayout];
[self addSubview:pageControl];