I am trying to use this PDFScroller code http://dl.dropbox.com/u/5391413/PDFScroller.zip (thanks jbm). I would like to display a pdf from a list (a tableview) thanks to a navigationController. I init a PhotoViewControler with a pdf file name and display it correctly. The problem is that after I have loaded a file once, I don't manage to clean the pdfDoc ref and this causes a crash after coming back to the view list and loading another file.
I tried to release the pdfDoc ref, or set to nil in the PhotoViewController dealloc method but it does not work.
One more thing: the viewDidUnload method of the PhotoViewController is not called when popping the viewController out of the navigationcontroller stack... is that normal?
thanks
G.
here is how I launch a PhotoViewController from he root viewController:
PhotoViewController *detailViewController = [[PhotoViewController alloc] initWithNibName:#"PhotoViewController" bundle:nil pdfName:tmpName];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
tmpName contains the name of the pdf file, I set a property in the PhotoViewController.Here is the PhotoViewController implementation (little different from the original sample code):
- (void)loadView
{
// Step 1: make the outer paging scroll view
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor blackColor];
pagingScrollView.showsVerticalScrollIndicator = NO;
pagingScrollView.showsHorizontalScrollIndicator = NO;
pagingScrollView.contentSize = CGSizeMake(pagingScrollViewFrame.size.width * [self pdfPageCount],
pagingScrollViewFrame.size.height);
pagingScrollView.delegate = self;
self.view = pagingScrollView;
// Step 2: prepare to tile content
recycledPages = [[NSMutableSet alloc] init];
visiblePages = [[NSMutableSet alloc] init];
[self tilePages];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[pdfName release];
pdfName = nil;
[pagingScrollView release];
pagingScrollView = nil;
//CGPDFDocumentRelease(__pdfDoc);
//__pdfDoc = nil;
[recycledPages release];
recycledPages = nil;
[visiblePages release];
visiblePages = nil;
}
- (void)dealloc
{
NSLog(#"dealloc");
[pdfName release];
[pagingScrollView release];
[super dealloc];
}
- (void)tilePages
{
// Calculate which pages are visible
CGRect visibleBounds = pagingScrollView.bounds;
int firstNeededPageIndex = floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds));
int lastNeededPageIndex = floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds));
firstNeededPageIndex = MAX(firstNeededPageIndex, 0);
lastNeededPageIndex = MIN(lastNeededPageIndex, [self pdfPageCount] - 1);
// Recycle no-longer-visible pages
for (ImageScrollView *page in visiblePages) {
if (page.index < firstNeededPageIndex || page.index > lastNeededPageIndex) {
[recycledPages addObject:page];
[page removeFromSuperview];
}
}
[visiblePages minusSet:recycledPages];
// add missing pages
for (int index = firstNeededPageIndex; index <= lastNeededPageIndex; index++) {
if (![self isDisplayingPageForIndex:index]) {
ImageScrollView *page = [self dequeueRecycledPage];
if (page == nil) {
page = [[[ImageScrollView alloc] init] autorelease];
}
[self configurePage:page forIndex:index];
[pagingScrollView addSubview:page];
[visiblePages addObject:page];
}
}
}
- (void)configurePage:(ImageScrollView *)page forIndex:(NSUInteger)index
{
page.index = index;
page.frame = [self frameForPageAtIndex:index];
// Use tiled images
[page displayTiledImageNamed: [self pdfPage: index]
size: [self pdfSize: index]];
}
static CGPDFDocumentRef __pdfDoc = nil;
- (CGPDFPageRef) pdfPage: (NSInteger) index {
if( ! __pdfDoc ) {
NSString *pdfPath = [[NSBundle mainBundle] pathForResource: pdfName ofType:nil];
CFURLRef url = CFURLCreateWithFileSystemPath( NULL, (CFStringRef)pdfPath,
kCFURLPOSIXPathStyle, NO );
__pdfDoc = CGPDFDocumentCreateWithURL( url );
}
if( __pdfDoc ) {
size_t pdfPageCount = CGPDFDocumentGetNumberOfPages( __pdfDoc );
index++; // incoming param is zero-based, CGPDF calls are 1-based
if( index < 1 )
index = 1;
if( index > pdfPageCount )
index = pdfPageCount;
CGPDFPageRef page = CGPDFDocumentGetPage( __pdfDoc, index );
return page;
}
return nil;
}
-(IBAction)backToListView{
[self.navigationController popViewControllerAnimated:YES];
}
The problem is: in the - (CGPDFPageRef) pdfPage: (NSInteger) index method, __pdfDoc remains the same even after the PhotoViewController was popped off the navigationController stack, and this causes a crash. I don't where to clean it correctly.
thanks
Guillaume
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?)
I implemented an app Images in full screen are displayed fine.
After few seconds the navigation bar and status bar are hidden, now if i close the app and again open it, the navigation bar is displaced at the top of the screen where status bar overlaps on navigation bar
I guess i have to change something about the CGRect frame
Please help me
#import "KTPhotoScrollViewController.h"
#import "KTPhotoBrowserDataSource.h"
#import "KTPhotoBrowserGlobal.h"
#import "KTPhotoView.h"
const CGFloat ktkDefaultPortraitToolbarHeight = 44;
const CGFloat ktkDefaultLandscapeToolbarHeight = 33;
const CGFloat ktkDefaultToolbarHeight = 44;
#define BUTTON_DELETEPHOTO 0
#define BUTTON_CANCEL 1
#interface KTPhotoScrollViewController (KTPrivate)
- (void)setCurrentIndex:(NSInteger)newIndex;
- (void)toggleChrome:(BOOL)hide;
- (void)startChromeDisplayTimer;
- (void)cancelChromeDisplayTimer;
- (void)hideChrome;
- (void)showChrome;
- (void)swapCurrentAndNextPhotos;
- (void)nextPhoto;
- (void)previousPhoto;
- (void)toggleNavButtons;
- (CGRect)frameForPagingScrollView;
- (CGRect)frameForPageAtIndex:(NSUInteger)index;
- (void)loadPhoto:(NSInteger)index;
- (void)unloadPhoto:(NSInteger)index;
- (void)trashPhoto;
- (void)exportPhoto;
#end
#implementation KTPhotoScrollViewController
#synthesize statusBarStyle = statusBarStyle_;
#synthesize statusbarHidden = statusbarHidden_;
#synthesize my_img, imgURL;
- (void)dealloc
{
[nextButton_ release], nextButton_ = nil;
[previousButton_ release], previousButton_ = nil;
[scrollView_ release], scrollView_ = nil;
[toolbar_ release], toolbar_ = nil;
[photoViews_ release], photoViews_ = nil;
[dataSource_ release], dataSource_ = nil;
[super dealloc];
}
- (id)initWithDataSource:(id <KTPhotoBrowserDataSource>)dataSource andStartWithPhotoAtIndex:(NSUInteger)index
{
if (self = [super init]) {
startWithIndex_ = index;
dataSource_ = [dataSource retain];
// Make sure to set wantsFullScreenLayout or the photo
// will not display behind the status bar.
[self setWantsFullScreenLayout:YES];
BOOL isStatusbarHidden = [[UIApplication sharedApplication] isStatusBarHidden];
[self setStatusbarHidden:isStatusbarHidden];
self.hidesBottomBarWhenPushed = YES;
}
return self;
}
- (void)loadView
{
[super loadView];
CGRect scrollFrame = [self frameForPagingScrollView];
UIScrollView *newView = [[UIScrollView alloc] initWithFrame:scrollFrame];
[newView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
[newView setDelegate:self];
UIColor *backgroundColor = [dataSource_ respondsToSelector:#selector(imageBackgroundColor)] ?
[dataSource_ imageBackgroundColor] : [UIColor blackColor];
[newView setBackgroundColor:backgroundColor];
[newView setAutoresizesSubviews:YES];
[newView setPagingEnabled:YES];
[newView setShowsVerticalScrollIndicator:NO];
[newView setShowsHorizontalScrollIndicator:NO];
[[self view] addSubview:newView];
scrollView_ = [newView retain];
[newView release];
nextButton_ = [[UIBarButtonItem alloc]
initWithImage:[UIImage imageNamed:#"nextIcon.png"]
style:UIBarButtonItemStylePlain
target:self
action:#selector(nextPhoto)];
previousButton_ = [[UIBarButtonItem alloc]
initWithImage:[UIImage imageNamed:#"previousIcon.png"]
style:UIBarButtonItemStylePlain
target:self
action:#selector(previousPhoto)];
UIBarButtonItem *msgButton = nil;
UIBarButtonItem *exportButton = nil;
exportButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction
target:self
action:#selector(exportPhoto)];
msgButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks
target:self
action:#selector(msgPhoto)];
// UIImage *image = [UIImage imageNamed:#"Icon-Small"];
// UIButton *myMuteButton = [UIButton buttonWithType:UIButtonTypeCustom];
// myMuteButton.bounds = CGRectMake( 0, 0, image.size.width, image.size.height );
// [myMuteButton setImage:image forState:UIControlStateNormal];
// [myMuteButton addTarget:self action:#selector(trashPhoto) forControlEvents:UIControlEventTouchUpInside];
// UIBarButtonItem *myMuteBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:myMuteButton];
UIBarItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
NSMutableArray *toolbarItems = [[NSMutableArray alloc] initWithCapacity:7];
if (exportButton) [toolbarItems addObject:exportButton];
[toolbarItems addObject:space];
[toolbarItems addObject:previousButton_];
[toolbarItems addObject:space];
[toolbarItems addObject:nextButton_];
[toolbarItems addObject:space];
if (msgButton) [toolbarItems addObject:msgButton];
// [toolbarItems addObject:myMuteBarButtonItem];
// [myMuteBarButtonItem release];
CGRect screenFrame = [[UIScreen mainScreen] bounds];
CGRect toolbarFrame = CGRectMake(0,
screenFrame.size.height - ktkDefaultToolbarHeight,
screenFrame.size.width,
ktkDefaultToolbarHeight);
toolbar_ = [[UIToolbar alloc] initWithFrame:toolbarFrame];
[toolbar_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin];
[toolbar_ setBarStyle:UIBarStyleBlackTranslucent];
[toolbar_ setItems:toolbarItems];
[[self view] addSubview:toolbar_];
if (msgButton) [msgButton release];
if (exportButton) [exportButton release];
[toolbarItems release];
[space release];
}
- (void) ShowAlert:(NSString*)title MyMsg:(NSString*)msg{
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
[alert autorelease];
}
- (void)setTitleWithCurrentPhotoIndex
{
NSString *formatString = NSLocalizedString(#"%1$i of %2$i", #"Picture X out of Y total.");
NSString *title = [NSString stringWithFormat:formatString, currentIndex_ + 1, photoCount_, nil];
[self setTitle:title];
}
- (void)scrollToIndex:(NSInteger)index
{
CGRect frame = scrollView_.frame;
frame.origin.x = frame.size.width * index;
frame.origin.y = 0;
[scrollView_ scrollRectToVisible:frame animated:NO];
}
- (void)setScrollViewContentSize
{
NSInteger pageCount = photoCount_;
if (pageCount == 0) {
pageCount = 1;
}
CGSize size = CGSizeMake(scrollView_.frame.size.width * pageCount,
scrollView_.frame.size.height / 2); // Cut in half to prevent horizontal scrolling.
[scrollView_ setContentSize:size];
}
- (void)viewDidLoad
{
[super viewDidLoad];
photoCount_ = [dataSource_ numberOfPhotos];
[self setScrollViewContentSize];
// Setup our photo view cache. We only keep 3 views in
// memory. NSNull is used as a placeholder for the other
// elements in the view cache array.
photoViews_ = [[NSMutableArray alloc] initWithCapacity:photoCount_];
for (int i=0; i < photoCount_; i++) {
[photoViews_ addObject:[NSNull null]];
}
}
- (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)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// The first time the view appears, store away the previous controller's values so we can reset on pop.
UINavigationBar *navbar = [[self navigationController] navigationBar];
if (!viewDidAppearOnce_) {
viewDidAppearOnce_ = YES;
navbarWasTranslucent_ = [navbar isTranslucent];
statusBarStyle_ = [[UIApplication sharedApplication] statusBarStyle];
}
// Then ensure translucency. Without it, the view will appear below rather than under it.
[navbar setTranslucent:YES];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES];
// Set the scroll view's content size, auto-scroll to the stating photo,
// and setup the other display elements.
[self setScrollViewContentSize];
[self setCurrentIndex:startWithIndex_];
[self scrollToIndex:startWithIndex_];
[self setTitleWithCurrentPhotoIndex];
[self toggleNavButtons];
[self startChromeDisplayTimer];
}
- (void)viewWillDisappear:(BOOL)animated
{
// Reset nav bar translucency and status bar style to whatever it was before.
UINavigationBar *navbar = [[self navigationController] navigationBar];
[navbar setTranslucent:navbarWasTranslucent_];
[[UIApplication sharedApplication] setStatusBarStyle:statusBarStyle_ animated:YES];
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[self cancelChromeDisplayTimer];
[super viewDidDisappear:animated];
}
- (void)deleteCurrentPhoto
{
if (dataSource_) {
// TODO: Animate the deletion of the current photo.
NSInteger photoIndexToDelete = currentIndex_;
[self unloadPhoto:photoIndexToDelete];
[dataSource_ deleteImageAtIndex:photoIndexToDelete];
photoCount_ -= 1;
if (photoCount_ == 0) {
[self showChrome];
[[self navigationController] popViewControllerAnimated:YES];
} else {
NSInteger nextIndex = photoIndexToDelete;
if (nextIndex == photoCount_) {
nextIndex -= 1;
}
[self setCurrentIndex:nextIndex];
[self setScrollViewContentSize];
}
}
}
- (void)toggleNavButtons
{
[previousButton_ setEnabled:(currentIndex_ > 0)];
[nextButton_ setEnabled:(currentIndex_ < photoCount_ - 1)];
}
#pragma mark -
#pragma mark Frame calculations
#define PADDING 20
- (CGRect)frameForPagingScrollView
{
CGRect frame = [[UIScreen mainScreen] bounds];
frame.origin.x -= PADDING;
frame.size.width += (2 * PADDING);
return frame;
}
- (CGRect)frameForPageAtIndex:(NSUInteger)index
{
CGRect bounds = [scrollView_ bounds];
CGRect pageFrame = bounds;
pageFrame.size.width -= (2 * PADDING);
pageFrame.origin.x = (bounds.size.width * index) + PADDING;
return pageFrame;
}
#pragma mark -
#pragma mark Photo (Page) Management
- (void)loadPhoto:(NSInteger)index
{
if (index < 0 || index >= photoCount_) {
return;
}
id currentPhotoView = [photoViews_ objectAtIndex:index];
if (NO == [currentPhotoView isKindOfClass:[KTPhotoView class]]) {
// Load the photo view.
CGRect frame = [self frameForPageAtIndex:index];
KTPhotoView *photoView = [[KTPhotoView alloc] initWithFrame:frame];
[photoView setScroller:self];
[photoView setIndex:index];
[photoView setBackgroundColor:[UIColor clearColor]];
// Set the photo image.
if (dataSource_) {
if ([dataSource_ respondsToSelector:#selector(imageAtIndex:photoView:)] == NO) {
UIImage *image = [dataSource_ imageAtIndex:index];
[photoView setImage:image];
} else {
[dataSource_ imageAtIndex:index photoView:photoView];
}
}
[scrollView_ addSubview:photoView];
[photoViews_ replaceObjectAtIndex:index withObject:photoView];
[photoView release];
} else {
// Turn off zooming.
[currentPhotoView turnOffZoom];
}
}
- (void)unloadPhoto:(NSInteger)index
{
if (index < 0 || index >= photoCount_) {
return;
}
id currentPhotoView = [photoViews_ objectAtIndex:index];
if ([currentPhotoView isKindOfClass:[KTPhotoView class]]) {
[currentPhotoView removeFromSuperview];
[photoViews_ replaceObjectAtIndex:index withObject:[NSNull null]];
}
}
- (void)setCurrentIndex:(NSInteger)newIndex
{
currentIndex_ = newIndex;
if(newIndex>=0){
myUrl = [dataSource_ imageURLAtIndex:currentIndex_ photoView:[photoViews_ objectAtIndex:currentIndex_]];
myDescr = [dataSource_ imageDESCRAtIndex:currentIndex_ photoView:[photoViews_ objectAtIndex:currentIndex_]];
img_Title =[dataSource_ imageimg_TitleAtIndex:currentIndex_ photoView:[photoViews_ objectAtIndex:currentIndex_]];
}
[self loadPhoto:currentIndex_];
[self loadPhoto:currentIndex_ + 1];
[self loadPhoto:currentIndex_ - 1];
[self unloadPhoto:currentIndex_ + 2];
[self unloadPhoto:currentIndex_ - 2];
[self setTitleWithCurrentPhotoIndex];
[self toggleNavButtons];
}
#pragma mark -
#pragma mark Rotation Magic
- (void)updateToolbarWithOrientation:(UIInterfaceOrientation)interfaceOrientation
{
CGRect toolbarFrame = toolbar_.frame;
if ((interfaceOrientation) == UIInterfaceOrientationPortrait || (interfaceOrientation) == UIInterfaceOrientationPortraitUpsideDown) {
toolbarFrame.size.height = ktkDefaultPortraitToolbarHeight;
} else {
toolbarFrame.size.height = ktkDefaultLandscapeToolbarHeight+1;
}
toolbarFrame.size.width = self.view.frame.size.width;
toolbarFrame.origin.y = self.view.frame.size.height - toolbarFrame.size.height;
toolbar_.frame = toolbarFrame;
}
- (void)layoutScrollViewSubviews
{
[self setScrollViewContentSize];
NSArray *subviews = [scrollView_ subviews];
for (KTPhotoView *photoView in subviews) {
CGPoint restorePoint = [photoView pointToCenterAfterRotation];
CGFloat restoreScale = [photoView scaleToRestoreAfterRotation];
[photoView setFrame:[self frameForPageAtIndex:[photoView index]]];
[photoView setMaxMinZoomScalesForCurrentBounds];
[photoView restoreCenterPoint:restorePoint scale:restoreScale];
}
// adjust contentOffset to preserve page location based on values collected prior to location
CGFloat pageWidth = scrollView_.bounds.size.width;
CGFloat newOffset = (firstVisiblePageIndexBeforeRotation_ * pageWidth) + (percentScrolledIntoFirstVisiblePage_ * pageWidth);
scrollView_.contentOffset = CGPointMake(newOffset, 0);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
// here, our pagingScrollView bounds have not yet been updated for the new interface orientation. So this is a good
// place to calculate the content offset that we will need in the new orientation
CGFloat offset = scrollView_.contentOffset.x;
CGFloat pageWidth = scrollView_.bounds.size.width;
if (offset >= 0) {
firstVisiblePageIndexBeforeRotation_ = floorf(offset / pageWidth);
percentScrolledIntoFirstVisiblePage_ = (offset - (firstVisiblePageIndexBeforeRotation_ * pageWidth)) / pageWidth;
} else {
firstVisiblePageIndexBeforeRotation_ = 0;
percentScrolledIntoFirstVisiblePage_ = offset / pageWidth;
}
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
[self layoutScrollViewSubviews];
// Rotate the toolbar.
[self updateToolbarWithOrientation:toInterfaceOrientation];
// Adjust navigation bar if needed.
if (isChromeHidden_ && statusbarHidden_ == NO) {
UINavigationBar *navbar = [[self navigationController] navigationBar];
CGRect frame = [navbar frame];
frame.origin.y = 20;
[navbar setFrame:frame];
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[self startChromeDisplayTimer];
}
- (UIView *)rotatingFooterView
{
return toolbar_;
}
#pragma mark -
#pragma mark Chrome Helpers
- (void)toggleChromeDisplay
{
[self toggleChrome:!isChromeHidden_];
}
- (void)toggleChrome:(BOOL)hide
{
isChromeHidden_ = hide;
if (hide) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4];
}
if ( ! [self isStatusbarHidden] ) {
if ([[UIApplication sharedApplication] respondsToSelector:#selector(setStatusBarHidden:withAnimation:)]) {
[[UIApplication sharedApplication] setStatusBarHidden:hide withAnimation:NO];
} else { // Deprecated in iOS 3.2+.
id sharedApp = [UIApplication sharedApplication]; // Get around deprecation warnings.
[sharedApp setStatusBarHidden:hide animated:NO];
}
}
CGFloat alpha = hide ? 0.0 : 1.0;
// Must set the navigation bar's alpha, otherwise the photo
// view will be pushed until the navigation bar.
UINavigationBar *navbar = [[self navigationController] navigationBar];
[navbar setAlpha:alpha];
[toolbar_ setAlpha:alpha];
if (hide) {
[UIView commitAnimations];
}
if ( ! isChromeHidden_ ) {
[self startChromeDisplayTimer];
}
}
- (void)hideChrome
{
if (chromeHideTimer_ && [chromeHideTimer_ isValid]) {
[chromeHideTimer_ invalidate];
chromeHideTimer_ = nil;
}
[self toggleChrome:YES];
}
- (void)showChrome
{
[self toggleChrome:NO];
}
- (void)startChromeDisplayTimer
{
[self cancelChromeDisplayTimer];
chromeHideTimer_ = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:#selector(hideChrome)
userInfo:nil
repeats:NO];
}
- (void)cancelChromeDisplayTimer
{
if (chromeHideTimer_) {
[chromeHideTimer_ invalidate];
chromeHideTimer_ = nil;
}
}
#pragma mark -
#pragma mark UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat pageWidth = scrollView.frame.size.width;
float fractionalPage = scrollView.contentOffset.x / pageWidth;
NSInteger page = floor(fractionalPage);
if (page != currentIndex_) {
[self setCurrentIndex:page];
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[self hideChrome];
}
#pragma mark -
#pragma mark Toolbar Actions
- (void)nextPhoto
{
[self scrollToIndex:currentIndex_ + 1];
[self startChromeDisplayTimer];
}
- (void)previousPhoto
{
[self scrollToIndex:currentIndex_ - 1];
[self startChromeDisplayTimer];
}
- (void)msgPhoto
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:img_Title message:myDescr delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
NSString *message;
NSString *title;
if (!error) {
title = #"Done";
message = #"image copied to your local gallery";
} else {
title = #"Error";
message = [error description];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {
//save to gallery
UIImage *imageB = [UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString: myUrl]]];
UIImageWriteToSavedPhotosAlbum(imageB, self, #selector(imageSavedToPhotosAlbum: didFinishSavingWithError: contextInfo:), nil);
} else if (buttonIndex == 1) {
//email
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
mailComposer.toolbar.barStyle = UIBarStyleBlack;
mailComposer.title = #"Your title here";
[[mailComposer navigationBar] setTintColor:[UIColor colorWithRed:124.0/255 green:17.0/255 blue:92.0/255 alpha:1]];
if ([MFMailComposeViewController canSendMail]) {
[mailComposer setSubject:#"Look at a great image"];
[mailComposer setMessageBody:[NSString stringWithFormat:#"%#",myUrl] isHTML:NO];
UIImage *imageB = [UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString: myUrl]]];
NSData *exportData = UIImageJPEGRepresentation(imageB ,1.0);
[mailComposer addAttachmentData:exportData mimeType:#"image/jpeg" fileName:img_Title];
[self presentModalViewController:mailComposer animated:YES];
}
//release the mailComposer as it is now being managed as the UIViewControllers modalViewController.
[mailComposer release];
} else if (buttonIndex == 2) {
//cancel
}
[self startChromeDisplayTimer];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
[self dismissModalViewControllerAnimated:YES];
if (result == MFMailComposeResultFailed) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to send message" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
- (void) exportPhoto
{
if ([dataSource_ respondsToSelector:#selector(exportImageAtIndex:)])
[dataSource_ exportImageAtIndex:currentIndex_];
[self startChromeDisplayTimer];
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Actions"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Save to gallery", #"Email",nil];
[actionSheet showInView:[self view]];
[actionSheet release];
}
#end
First of all, tel me if you want to show Status Bar or not.
If you dont want to show then, in nib of controller's, you can select its view, and under its properties set StatusBar to NONE, thar time it wont show status bar... and you can set vew size to (320*480) or else with status bar it will be (320*460) and 20 pixels will be reserved for status bar.
Other ways to do (without using above method)
Can hide StatusBar from info.plist also, by setting property UIStatusBarHidden property to YES. (To hide the status bar when the app launches)
Programmatically can be done, add line to appDelegate's applicationDidFinishLaunching method,
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];
I have UIScrollView in stage and paging functionality enabled to move back/next.
I have added 10 subviews in UIScrollView. When I have modify the content inside the subviews, then it is not reflected in UIScrollView.
Book.m
- (void) initializeWithXML:(NSString *)XMLURLString {
NSData *xmlData;
NSString *url;
if ( ![applicationData getMode] ) {
resourceRootURL = [[applicationData getAssetsPath] stringByAppendingPathComponent:#"phone/"];
} else {
resourceRootURL = [applicationData getAssetsPath];
}
url = [resourceRootURL stringByAppendingPathComponent:XMLURLString];
//NSLog(#"Root URL...%#", url);
if ([url rangeOfString:#"http"].location != NSNotFound) {
xmlData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
} else {
xmlData = [NSData dataWithContentsOfFile:url];
}
bookContentArray = [self grabXML:xmlData andQuery:#"//page"];
// view controllers are created lazily
// in the meantime, load the array with placeholders which will be replaced on demand
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < kNumberOfPages; i++) {
[controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
for(int i = 0; i < [bookContentArray count]; i++) {
[viewControllers addObject:[NSNull null]];
}
if ( isTwoPage ) {
kNumberOfPages = [bookContentArray count];
} else {
kNumberOfPages = [bookContentArray count]/2;
}
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
scrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
scrollView.pagingEnabled = YES;
scrollView.backgroundColor = [UIColor blackColor];
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.contentSize = [self contentSizeForPagingScrollView];
scrollView.contentSize = CGSizeMake(scrollView.contentSize.width,scrollView.frame.size.height);
scrollView.delegate = self;
self.view = scrollView;
kNumberOfPages = [bookContentArray count];
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 loadPage:0];
}
- (void) loadPage:(int)number {
// Calculate which pages are visible
int firstNeededPageIndex = MAX(number-1, 0);
int lastNeededPageIndex = MIN(number+1, [viewControllers count] - 1);
//NSLog(#"%d,%d",firstNeededPageIndex,lastNeededPageIndex);
// Recycle no-longer-visible pages
for(int i = 0; i < [viewControllers count]; i++) {
ImageScrollView *page = [viewControllers objectAtIndex:i];
if ((NSNull *)page != [NSNull null]) {
if (page.index < firstNeededPageIndex || page.index > lastNeededPageIndex) {
//NSLog(#"removed page %d", page.index);
[page removeImages];
[page removeFromSuperview];
page = nil;
[viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
}
}
}
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
if ( number == 0 ) {
[self loadScrollViewWithPage:number];
[self loadScrollViewWithPage:number+1];
} else if ( number == [bookContentArray count]-1) {
[self loadScrollViewWithPage:number-1];
[self loadScrollViewWithPage:number];
} else {
[self loadScrollViewWithPage:number-1];
[self loadScrollViewWithPage:number];
[self loadScrollViewWithPage:number+1];
}
}
- (void)loadScrollViewWithPage:(int)page {
ImageScrollView *pageController = [[ImageScrollView alloc] initWithFrame:CGRectMake(0, 0, 768, 1024)];
pageController.index = page;
pageController.myDelegate = self;
pageNumber = pageControl.currentPage;
pageController.isTwoPage = isTwoPage;
if ( pageNumber == page ) {
pageController.isCurrentPage = YES;
} else {
pageController.isCurrentPage = NO;
}
[controller setImageURL:leftURL andRightURL:rightURL andPriority:0];
[scrollView addSubview:controller];
}
ImageScrollView.m
- (void) setImageURL:(NSString *)leftURL andRightURL:(NSString *)rightURL andPriority:(int)priority {
[imageView removeFromSuperview];
[imageView release];
imageView = nil;
if ( !isTwoPage ) {
imageView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 768, 1024)];
} else {
imageView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
}
if ( isTwoPage ) {
leftImage = [[FBEPage alloc] initWithNibName:#"FBEPage" bundle:nil];
leftImage.view.frame = CGRectMake(0, 43, 512, 682);
rightImage = [[FBEPage alloc] initWithNibName:#"FBEPage" bundle:nil];
rightImage.view.frame = CGRectMake(512, 43, 512, 682);
} else {
leftImage = [[FBEPage alloc] initWithNibName:#"FBEPage" bundle:nil];
leftImage.view.frame = imageView.frame;
rightImage = [[FBEPage alloc] initWithNibName:#"FBEPage" bundle:nil];
rightImage.view.frame = imageView.frame;
}
leftImage.delegate = self;
rightImage.delegate = self;
if ( isFirstPage ) {
[leftImage.view setHidden:YES];
[rightImage.view setHidden:NO];
} else if ( isLastPage ) {
[leftImage.view setHidden:NO];
[rightImage.view setHidden:YES];
} else if ( !isTwoPage ) {
[leftImage.view setHidden:NO];
[rightImage.view setHidden:YES];
} else {
[leftImage.view setHidden:NO];
[rightImage.view setHidden:NO];
}
imageView.backgroundColor = [UIColor whiteColor];
[self addSubview:imageView];
[leftImage setImageURL:leftURL];
[rightImage setImageURL:rightURL];
[imageView addSubview:leftImage.view];
[imageView addSubview:rightImage.view];
}
FBPage.m
- (void) setImageURL:(NSString *)url {
imageView = [[UIImageView alloc] init];
imageView.frame = CGRectMake(0, 0, 768, 1024);
imageView.center = self.view.center;
imageView.userInteractionEnabled = TRUE;
[container addSubview:imageView];
[activityIndicator setHidden:YES];
if ([url rangeOfString:#"http"].location != NSNotFound) {
SDWebImageManager *manager = [SDWebImageManager sharedManager];
UIImage *cachedImage = [manager imageWithURL:[NSURL URLWithString:url]];
if (cachedImage) {
[imageView setImage:cachedImage];
isImageLoaded = YES;
[self addScrollView];
} else {
[activityIndicator setHidden:NO];
[activityIndicator startAnimating];
[manager downloadWithURL:[NSURL URLWithString:url] delegate:self options:0 success:^(UIImage *image){
[activityIndicator stopAnimating];
[activityIndicator setHidden:YES];
[imageView setImage:image];
isImageLoaded = YES;
[self addScrollView];
} failure:nil];
}
imageURL = url;
} else {
imageView.image = [UIImage imageWithContentsOfFile:url];
isImageLoaded = YES;
[self addScrollView];
}
}
- (void) setHotspotURL:(NSString *)URL {
[hotspot.view removeFromSuperview];
[hotspot release];
hotspot = nil;
hotspot = [[FBHotspot alloc] initWithNibName:#"FBHotspot" bundle:nil];
hotspot.view.frame = CGRectMake(0, 0, 768, 1024);
hotspot.delegate = self;
[hotspot setURL:URL];
[container addSubview:hotspot.view];
}
**When I am calling setHotspotURL and it’s not updating to the scrollview.**
Make sure you inserted your content at the correct position within the scroll view. Set the contentSize accordingly. Try to call layoutSubviews of the UIScrollView instance
How do I access a previous view controller while in a subview? Because I'm able to perform actions but I'm just not able to use self.[my main view controller].
This is my code, for testing purposes:
PhotoViewController.m
-(IBAction)likeButton:(UIButton *)sender
{
//this part works
NSString *num = #"2";
self.label.text = [NSString stringWithFormat:#"%# + %#",
self.label.text,
num];
//this part doesn't work
//switch over to the third view to see if it worked
self.tabBarController.selectedIndex = 0;
}
I have a UITabBarController and one of its view controllers has a UIScrollView. Inside of the UIScrollView is a PhotoViewController object.
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch
MyTabBarViewController *vc2 = [[MyTabBarViewController alloc] init];
SecondViewController *vc3 = [[SecondViewController alloc] init];
controller = [[DemoAppViewController alloc] init];
controller.view.frame = CGRectMake(0, 20, 320, 460);
controller.title = #"Intro Screen";
vc2.title = #"Explore";
vc3.title = #"Send a Pic";
UITabBarController *tbc = [[UITabBarController alloc] init];
tbc.viewControllers = [NSArray arrayWithObjects:controller, vc2, vc3, nil];
[controller release];
[vc2 release];
[vc3 release];
[self.window addSubview:tbc.view];
[self.window makeKeyAndVisible];
return YES;
}
Also, my TabBarViewController.m //not my actual UITabBarController though, wording is confusing
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
arrayCount = [array count];
scroller.delegate=self;
scroller.pagingEnabled=YES;
scroller.directionalLockEnabled=YES;
scroller.showsHorizontalScrollIndicator=NO;
scroller.showsVerticalScrollIndicator=NO;
//should have an array of photo objects and the number of objects, correct?
scrollWidth = 0;
scroller.contentSize=CGSizeMake(arrayCount*scroller.frame.size.width, scroller.frame.size.height);
for (int i = 0; i < arrayCount;i++) {
PhotoViewController *pvc = [[PhotoViewController alloc] initWithNibName:#"PhotoViewController" bundle:nil];
UIImageView *scrollImageView = [[UIImageView alloc] initWithFrame:CGRectOffset(scroller.bounds, scrollWidth, 0)];
CGRect rect = scrollImageView.frame;
pvc.view.frame = rect;
pvc.label.textColor = [UIColor whiteColor];
id individualPhoto = [array objectAtIndex:i];
NSLog(#"%#",individualPhoto);
NSArray *keys=[individualPhoto allKeys];
NSLog(#"%#",keys);
NSString *imageURL=[individualPhoto objectForKey:#"source"];
NSURL *url = [NSURL URLWithString:imageURL];
NSData *data = [NSData dataWithContentsOfURL:url];
pvc.imageView.image = [[UIImage alloc] initWithData:data];
pvc.label.text = [individualPhoto objectForKey:#"id"];
[scroller addSubview:pvc.view];
[scrollImageView release];
//[pvc release];
scrollWidth += scroller.frame.size.width;
}
if (arrayCount > 3) {
pageControl.numberOfPages=3;
} else {
pageControl.numberOfPages=arrayCount;
}
pageControl.currentPage=0;
}
If a UIView subclass needs to message a controller above itself, a common (and often recommended?) way to do this is to have the view subclass implement the delegate protocol (a weak linked instance variable pointing to the view controller that you want to use). The view controller should then set itself as the delegate of the view when that view is being initialize.
Try defining this method in your PhotoViewController:
+ (YOURTABBARCONTROLLER*)parentTabBarController:(UIResponder*)view {
id nextResponder = nil;
id v = view;
while (nextResponder = [v nextResponder]) {
NSLog(#"Found Responder: %#", nextResponder); //-- ADDED THIS
if ([nextResponder isKindOfClass:[YOURTABBARCONTROLLER class]])
return nextResponder;
v = nextResponder;
}
return nil;
}
it will traverse the responder chain and return the first controller of a given type that is found. Replace YOURTABBARCONTROLLER with your actual tab bar controller class and you should be able to have:
-(IBAction)likeButton:(UIButton *)sender
{
//this part works
NSString *num = #"2";
self.label.text = [NSString stringWithFormat:#"%# + %#",
self.label.text,
num];
[PhotoViewController parentTabBarController:self.view].selectedIndex = 0;
// self.tabBarController.selectedIndex = 0;
}
Updated
-(IBAction)likeCommentButton:(UIButton *)sender
{
//code goes here
TypeSomethingViewController *typeSomethingViewController = [[TypeSomethingViewController alloc] init];
typeSomethingViewController.delegate = self;
[self presentModalViewController:typeSomethingViewController animated:YES];
[typeSomethingViewController release];
}
-(void)typeSomethingViewController:(TypeSomethingViewController *)controller didTypeSomething:(NSString *)text
{
//NSLog(#"response: %#", controller);
NSString *commentID = self.label.text;
for(UIViewController *controller in [PhotoViewController parentTabBarController:self.parentViewController.view].viewControllers)
{
if([controller isKindOfClass:[DemoAppViewController class]])
{
DemoAppViewController *davc = (DemoAppViewController *)controller;
//[davc commentPicture:commentID :message];
[davc likePicture:commentID];
}
}
[PhotoViewController parentTabBarController:self.view].selectedIndex = 0;
[self dismissModalViewControllerAnimated:YES];
}
Try this out to switch to the first controller.
self.tabBarController.selectedViewController
= [self.tabBarController.viewControllers objectAtIndex:0];
Change the index value to switch to whichever controller you want to switch to.
The tabBarController should be a property of the app delegate.
Try accessing it with :
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication]
delegate];
appDelegate.tabBarController.selectedIndex = 0;
Unless you declare the same property in PhotoViewController, you won't be able to access it this way.
Try importing the app delegate header in PhotoViewController.h like so :
#import "MyAppDelegate"
then try this code above replacing tabBarController by tbc which, as the example suggests is the name given to this property.
I want to create scrollView with pagecontrol programmatically. How can i do that?
#pragma mark -
#pragma mark loadGalleryView
-(void) loadGalleryView{
galleryArr = [memberDic objectForKey:#"arrKey"];
if ([galleryArr count]%5 != 0)
{
noOfPages = ([galleryArr count]/5)+1;
}
else
{
noOfPages = [galleryArr count]/5;
}
viewControllers = [[NSMutableArray alloc] init];
for (int i=0; i<noOfPages; i++)
{
[viewControllers addObject:[NSNull null]];
}
[galleryScrollView setPagingEnabled:TRUE];
[galleryScrollView setContentSize:CGSizeMake(self.view.frame.size.width* noOfPages,69.0f)];
[galleryScrollView setShowsHorizontalScrollIndicator:FALSE];
[galleryScrollView setShowsVerticalScrollIndicator:FALSE];
[galleryScrollView setScrollsToTop:FALSE];
[galleryScrollView setDelegate:self];
[pageControl setNumberOfPages:noOfPages];
[pageControl setCurrentPage:0];
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
}
//-----------------Load scroll View----------------------------------
-(void) loadScrollViewWithPage:(int) page{
if (page < 0)
{
return;
}
if (page >= noOfPages)
{
return;
}
GalleryViewController *givc = [viewControllers objectAtIndex:page];
if ((NSNull *)givc == [NSNull null])
{
givc = [[GalleryViewController alloc] initWithPageNumber:page];
givc.imageArr = [galleryArr retain];
[viewControllers replaceObjectAtIndex:page withObject:givc];
[givc release];
}
if (nil == givc.view.superview)
{
CGRect frame = self.view.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0.0f;
givc.view.frame = frame;
[galleryScrollView addSubview:givc.view];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
// We don't want a "feedback loop" between the UIPageControl and the scroll delegate in
// which a scroll event generated from the user hitting the page control triggers updates from
// the delegate method. We use a boolean to disable the delegate logic when the page control is used.
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = galleryScrollView.frame.size.width;
int page = floor((galleryScrollView.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
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
isPageControlUsed = NO;
}
in gallary View Controller in .m file
- (void)viewDidLoad {
[super viewDidLoad];
float x = 7.0f;
for (int i = (pageNumber*5); i<(pageNumber+1)*5; i++)
{
if (i<[imageArr count])
{
NSString *url = [imageArr objectAtIndex:i];
MyImageView *imgView = [[MyImageView alloc] initWithFrame:CGRectMake(x, 7.5f, 55.0f, 55.0f)];
[imgView addImageFrom:url];
[self.view addSubview:imgView];
[imgView release];
x = x+62.5f;
}
}
}
-(id)initWithPageNumber:(int) page{
if (self = [super initWithNibName:#"GalleryViewController" bundle:nil])
{
pageNumber = page;
}
return self;
}