Everything I've read on supporting UIScrollView on iOS 5+ states that I should be able to use the autosizing feature within Xcode's Size Inspector to auto resize my views.
Using Storyboards, I have a TabBarViewController of which one of my tabs has a UIScrollView and a Page Control.
Behind the scenes I have setup programmatically a handling of the pages in a UIView (I don't know if it's necessary to post the code, but I'm going to do it anyway for clarity).
When switching from the iPhone 3.5inch to the iPhone 4inch the auto resize is not working whatsoever. I'd like to have the UIScrollView AND the Page control visible when using the 3.5 inch screen.
I should note that the iPad version (see code below) doesn't snap properly in my subview. (That may be a different question, altogether).
4 Inch Screen
3.5 Inch Screen
Just in case, here's my .m file:
#import "TutorialViewController.h"
#interface TutorialViewController ()
#property (nonatomic, strong) NSArray *pageImages;
#property (nonatomic, strong) NSMutableArray *pageViews;
- (void)loadVisiblePages;
- (void)loadPage:(NSInteger)page;
- (void)purgePage:(NSInteger)page;
#ifdef UI_USER_INTERFACE_IDIOM
#define IS_IPAD() (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define IS_IPAD() (false)
#endif
#end
#implementation TutorialViewController
#synthesize scrollView = _scrollView;
#synthesize pageControl = _pageControl;
#synthesize pageImages = _pageImages;
#synthesize pageViews = _pageViews;
- (void)loadPage:(NSInteger)page {
if (page < 0 || page >= self.pageImages.count) {
// If it's outside the range of what you have to display, then do nothing
return;
}
// 1
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView == [NSNull null]) {
// 2
CGRect frame = self.scrollView.bounds;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0.0f;
// 3
UIImageView *newPageView = [[UIImageView alloc] initWithImage:[self.pageImages objectAtIndex:page]];
newPageView.contentMode = UIViewContentModeScaleAspectFill;
newPageView.frame = frame;
[self.scrollView addSubview:newPageView];
// 4
[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 you have to display, then do nothing
return;
}
// Remove a page from the scroll view and reset the container array
UIView *pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*)pageView != [NSNull null]) {
[pageView removeFromSuperview];
[self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];
}
}
- (void)loadVisiblePages {
// First, determine which page is currently visible
CGFloat pageWidth = self.scrollView.frame.size.width;
NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth) / (pageWidth * 2.0f));
// Update the page control
self.pageControl.currentPage = page;
// Work out which pages you want to load
NSInteger firstPage = page - 1;
NSInteger lastPage = page + 1;
// Purge anything before the first page
for (NSInteger i=0; i<firstPage; i++) {
[self purgePage:i];
}
// Load pages in our range
for (NSInteger i=firstPage; i<=lastPage; i++) {
[self loadPage:i];
}
// Purge anything after the last page
for (NSInteger i=lastPage+1; i<self.pageImages.count; i++) {
[self purgePage:i];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// Load the pages that are now on screen
[self loadVisiblePages];
// NSLog(#"Scroll View Did Scroll");
}
- (void)viewDidLoad {
[super viewDidLoad];
// Step 1
if (IS_IPAD())
{
self.pageImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"1536x2048 tutorial_1.png"],
[UIImage imageNamed:#"1536x2048 tutorial_2.png"],
[UIImage imageNamed:#"1536x2048 tutorial_3.png"],
[UIImage imageNamed:#"1536x2048 tutorial_4.png"],
nil];
}
else
{
self.pageImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"640x960 tutorial_1.png"],
[UIImage imageNamed:#"640x960 tutorial_2.png"],
[UIImage imageNamed:#"640x960 tutorial_3.png"],
[UIImage imageNamed:#"640x960 tutorial_4.png"],
nil];
}
NSInteger pageCount = self.pageImages.count;
// Step 2
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = pageCount;
// Step 3
self.pageViews = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < pageCount; ++i) {
[self.pageViews addObject:[NSNull null]];
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Step 4
// 3.5in height = 388
// 4in height = 476
CGSize pagesScrollViewSize = self.scrollView.frame.size;
self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * self.pageImages.count, pagesScrollViewSize.height);
// Step 5
[self loadVisiblePages];
}
#end
use like this
or
like this your problem will solve
or write single line code in your .m file
scrollview.frame = CGRectMake(x, y, 320, self.view.bounds.size.height);
Just check if the view in which you have added the scroll view has enabled AutoResizeSubviews. If not it will not adjust the scrollview according to the screen size.
Secondly, adjust your scroll view according to 3.5 inch screen and AutoResizing will adjust it for 4 inch screen. Don't do it vice-versa.
For page control, Do it this way. It will always be at the bottom of your view.
select yourappname.pch in the Supporting Files folder and add this line right before the last #endif at the bottom of the file
to Check, for device....
#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES)
then write this in your ViewWillAppear()
if (IS_IPHONE5)
{
scrollView.contentSize = CGSizeMake(width,height );
}
Related
I have a UIScrollView to pan some photos. After loading the view, when I touch the page (anywhere within) it makes my insideview (UIImageView) to goes up.
Here is the photo when it loads (the green is the inside UIView, the black the UIScrollView).
Fist load view:
After the touch:
Here is the code that generates it:
Adding the view to the scrollview:
- (void)loadPage:(NSInteger)page {
CGRect frame = self.scrollView.bounds;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
// 3
NSURL *eventImageURL = [NSURL URLWithString:[[self.pageImages objectAtIndex:page] imageURL]];
UIImageView *newPageView = [[UIImageView alloc]init];
[newPageView setImageWithURL:eventImageURL placeholderImage:nil usingActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
newPageView.contentMode = UIViewContentModeScaleAspectFit;
newPageView.frame=frame;
newPageView.tag=page;
newPageView.userInteractionEnabled=NO;
newPageView.backgroundColor=[UIColor greenColor];
newPageView.clipsToBounds=YES;
[self.scrollView addSubview:newPageView];
}
The scroll view setup:
- (void)viewDidLoad {
[super viewDidLoad];
CGSize scrollableSize = CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);
[self.scrollView setContentSize:scrollableSize];
// Do any additional setup after loading the view from its nib.
// 1
NSInteger pageCount = self.pageImages.count;
// 2
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = pageCount;
// 3
self.pageViews = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < pageCount; ++i) {
[self.pageViews addObject:[NSNull null]];
}
self.scrollView.minimumZoomScale=1.0;
self.scrollView.maximumZoomScale=2.0;
self.scrollView.clipsToBounds=YES;
self.scrollView.contentSize=CGSizeMake(1280, 960);
self.scrollView.tag=10;
[self.scrollView setUserInteractionEnabled:YES];
[self.scrollView setMultipleTouchEnabled:YES];
}
Found it.
On viewdidload I set:
self.automaticallyAdjustsScrollViewInsets = NO;
And everything works fine.
I'm loading images on the UIImageView through a string and i want horizontal scrolling to view the images on a UIImageView.
In my xib file I have a scroll view over which there is a image view. I'm using this code but my page is not scrolling and only the first image in the string is loaded.Can anyone please help.
Code:
-(void)viewDidLoad
{
count=1;
// imagesName = [[NSMutableArray alloc]initWithObjects :#"election_band_base.jpg", #"ElectionBoxAPPA-Hindi(1).jpg", #"photos.png", #"business.png", #"health.png", nil];
imagesName1 = [NSString stringWithFormat :#"election_band_base.jpg", #"ElectionBoxAPPA-Hindi(1).jpg", #"photos.png", #"business.png", #"health.png", nil];
[imagesName addObject:imagesName1];
items = [[NSMutableArray alloc]init];
// [_imageView1.image setImage=imagesName1];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// _imageView1.image=[UIImage animatedImageWithImages:imagesName duration:0];
_imageView1.image=[UIImage imageNamed:imagesName1 ];
[self loadScrollView];
}
-(void)loadScrollView
{
scrollView.contentSize = CGSizeMake(0, scrollView.frame.size.height);
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < [imagesName count]; i++) {
[controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
count=1;
// a page is the width of the scroll view
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * [imagesName count], scrollView.frame.size.height);
//scrollView.contentSize = CGSizeMake(900,80);
scrollView.showsHorizontalScrollIndicator =YES;
scrollView.showsVerticalScrollIndicator = YES;
scrollView.scrollsToTop = NO;
scrollView.delegate = self;
pageControl.numberOfPages = [imagesName count];
pageControl.currentPage = 0;
// pages are created on demand
// load the visible page
// load the page on either side to avoid flashes when the user starts scrolling
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
}
- (void)loadScrollViewWithPage:(int)page {
if (page < 0) return;
if (page >= [imagesName count])
return;
// replace the placeholder if necessary
controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
NSString *deviceType = [UIDevice currentDevice].model;
if([deviceType isEqualToString:#"iPhone"])
{
controller = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
}
else{
controller = [[MyViewController alloc] initWithNibName:#"MyViewController_ipad" bundle:nil];
}
[controller initWithPageNumber:page];
[controller setArrData:imagesName];
[viewControllers replaceObjectAtIndex:page withObject:controller];
}
// add the controller's view to the scroll view
if (nil == controller.view.superview) {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
- (void)unloadScrollViewWithPage:(int)page {
if (page < 0) return;
if (page >= [imagesName count]) return;
controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller != [NSNull null]) {
if (nil != controller.view.superview)
[controller.view removeFromSuperview];
[viewControllers replaceObjectAtIndex:page withObject:[NSNull null]];
}
}
- (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.
if (pageControlUsed) {
// do nothing - the scroll was initiated from the page control, not the user dragging
return;
}
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = page;
// NSLog(#"current page %d",page);
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self unloadScrollViewWithPage:page - 2];
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
[self unloadScrollViewWithPage:page + 2];
count=page+1;
// A possible optimization would be to unload the views+controllers which are no longer visible
}
// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollViewLoc
{
CGFloat pageWidth = scrollViewLoc.frame.size.width;
CGPoint translation = [scrollViewLoc.panGestureRecognizer translationInView:scrollViewLoc.superview];
int page = floor((scrollViewLoc.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
}
// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControlUsed = NO;
}
- (IBAction)changePage:(id)sender
{
int page = pageControl.currentPage;
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
// update the scroll view to the appropriate page
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
// Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above.
pageControlUsed = YES;
}
So, you want to built the gallery view:
For this implement the following steps:
Add the UIScrollView to the view of your view controller.
In viewDidLoad method: Load the name of the images in the "ImageArray". (I assume all your images have names as "img1.png", "img2.png", "img3.png", ....)
ImageArray=[[NSMutableArray alloc]init];
for (int i=0; i<19; i++) {
NSString *imgtext=[[NSString alloc]initWithFormat:#"img%d",i+1];
[ImageArray addObject:imgtext];
}
In the viewWillAppear method, add the following code:
for (int i = 0; i < ImageArray.count; i++) {
CGRect frame;
frame.origin.x = self.scrollview.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollview.frame.size;
UIView *subview = [[UIView alloc] initWithFrame:frame];
UIImage *image = [UIImage imageNamed: [NSString stringWithFormat:#"%#.png",[ImageArray objectAtIndex:i]]];
UIImageView *imageView = [[UIImageView alloc] initWithImage: image];
[imageView setFrame:CGRectMake(0, 0, frame.size.width,frame.size.height )];
[subview addSubview:imageView];
[self.scrollview addSubview:subview];
}
self.scrollview.contentSize = CGSizeMake(self.scrollview.frame.size.width * ImageArray.count, self.scrollview.frame.size.height);
self.scrollview.contentOffset=CGPointMake (self.scrollview.frame.size.width, 0);
Hope it helps.
I have made a scroll view in my app in which I have added multiple images with horizontal scrolling. Below is the function which may help you..
- (void)makeFriendsScrollView{
int friendsCount = 10;
float xPos = 10;
for (int i = 0; i < friendsCount; i++) {
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(xPos,25 , 54, 54)];
imgView.image = [UIImage imageNamed:#"user_default.png"];
[imgView.layer setCornerRadius:27.0];
imgView.clipsToBounds = YES;
[scrollViewFriends addSubview:imgView];
xPos = xPos + 64;
}
scrollViewFriends.contentSize = CGSizeMake(friendsCount*65, 90);
[scrollViewFriends.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[scrollViewFriends.layer setBorderWidth:0.5f];
}
i simply did this in view controller check it out...and change according to your requirement..try this in viewWillAppear method
self.arraname=[NSArray arrayWithObjects:#"1.jpg",#"2.jpg",#"3.jpg", nil];
// int friendsCount = 10;
float xPos = 160;
float x1=0;
float y=60;
for (int i = 0; i < [self.arraname count]; i++)
{
x1=xPos+(260*i);
_imgView = [[UIImageView alloc] initWithFrame:CGRectMake(x1, y, 54, 54)];
_imgView.image = [UIImage imageNamed:[self.arraname objectAtIndex:i]];
[_imgView.layer setCornerRadius:27.0];
_imgView.clipsToBounds = YES;
[self.scroll addSubview:_imgView];
}
NSLog(#"%f",x1);
self.scroll.contentSize=CGSizeMake(x1+200, 0);
self.scroll.showsHorizontalScrollIndicator = YES;
self.scroll.showsVerticalScrollIndicator=NO;
self.scroll.pagingEnabled = YES;
I'm making a select level with 3 levels that get scrolled horizontally - the scroll controls three views "View 1" "view 2" and "View 3", I need to make an illusion to the user, Ive placed 3 buttons on each view and half a button on each side of the UIview with 2 labels one writes "lev" the other "el 2"...
When the user moves to View 2 I'd like the label to be set to "el 2" and as soon as the scroll has settled on level 2 i'd like the label to write "el 1" - This would make an illusion and it would be so fast that the user wouldn't notice.
heres the code:
This:
[_elone setText:[NSString stringWithFormat:#"Level 2"]];
But I don't know where to put it,
Should I make an outlet, an action a statement?
#interface PagerViewController ()
#property (assign) BOOL pageControlUsed;
#property (assign) NSUInteger page;
#property (assign) BOOL rotating;
- (void)loadScrollViewWithPage:(int)page;
#end
#implementation PagerViewController
#synthesize scrollViewTwo;
#synthesize pageControlTwo;
#synthesize pageControlUsed = _pageControlUsed;
#synthesize page = _page;
#synthesize rotating = _rotating;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.scrollViewTwo setPagingEnabled:YES];
[self.scrollViewTwo setScrollEnabled:YES];
[self.scrollViewTwo setShowsHorizontalScrollIndicator:NO];
[self.scrollViewTwo setShowsVerticalScrollIndicator:NO];
[self.scrollViewTwo setDelegate:self];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
for (NSUInteger i =0; i < [self.childViewControllers count]; i++) {
[self loadScrollViewWithPage:i];
}
self.pageControlTwo.currentPage = 0;
_page = 0;
[self.pageControlTwo setNumberOfPages:[self.childViewControllers count]];
UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControlTwo.currentPage];
if (viewController.view.superview != nil) {
[viewController viewWillAppear:animated];
}
self.scrollViewTwo.contentSize = CGSizeMake(scrollViewTwo.frame.size.width * [self.childViewControllers count], scrollViewTwo.frame.size.height);
}
- (void)loadScrollViewWithPage:(int)page {
if (page < 0)
return;
if (page >= [self.childViewControllers count])
return;
// replace the placeholder if necessary
UIViewController *controller = [self.childViewControllers objectAtIndex:page];
if (controller == nil) {
return;
}
// add the controller's view to the scroll view
if (controller.view.superview == nil) {
CGRect frame = self.scrollViewTwo.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[self.scrollViewTwo addSubview:controller.view];
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
_pageControlUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
_pageControlUsed = NO;
}
- (IBAction) changePage :(id) sender {
}
How is this done?
// Implement the UIScrollview Delegate method
-(void)scrollViewDidScroll:(UIScrollView *)sender
{
CGFloat pageWidth = yourScrollView.frame.size.width;
int currentPage = floor((yourScrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
if (currentPage != featureVenPageControll.currentPage)
{
[_elone setText:[NSString stringWithFormat:#"Level 2"]];
}
}
I am making a handbook table cell in my app and i have 7 pages which each are the images and I'm using uiscrollview with page control but when i run the app it says Received memory warning.
and then the app freezes and automatically shuts down, what should i do and this is my code.
#interface HS_HandbookViewController ()
#property (nonatomic, strong) NSArray *pageImages;
#property (nonatomic, strong) NSMutableArray *pageViews;
- (void)loadVisiblePages;
- (void)loadPage:(NSInteger)page;
- (void)purgePage:(NSInteger)page;
#end
#implementation HS_HandbookViewController
#synthesize scrollView = _scrollView;
#synthesize pageControl = _pageControl;
#synthesize pageImages = _pageImages;
#synthesize pageViews = _pageViews;
#pragma mark -
- (void)loadVisiblePages {
// First, determine which page is currently visible
CGFloat pageWidth = self.scrollView.frame.size.width;
NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth) / (pageWidth * 2.0f));
// Update the page control
self.pageControl.currentPage = page;
// 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];
}
}
- (UIImage *)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
- (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 = frame;
[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]];
}
}
#pragma mark -
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Student Handbook";
// Set up the image we want to scroll & zoom and add it to the scroll view
self.pageImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"page 1 handbook.png"],
[UIImage imageNamed:#"page 2 handbook.png"],
[UIImage imageNamed:#"page 3 hand book.png"],
[UIImage imageNamed:#"page 4 handbook.png"],
[UIImage imageNamed:#"page 5 handbook.png"],
[UIImage imageNamed:#"page 6 handbook.png"],
[UIImage imageNamed:#"page 7 handbook.png"],
nil];
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];
// Set up the content size of the scroll view
CGSize pagesScrollViewSize = self.scrollView.frame.size;
self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * self.pageImages.count, pagesScrollViewSize.height);
// Load the initial set of pages that are on screen
[self loadVisiblePages];
}
- (void)viewDidUnload {
[super viewDidUnload];
self.scrollView = nil;
self.pageControl = nil;
self.pageImages = nil;
self.pageViews = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// Load the pages which are now on screen
[self loadVisiblePages];
}
#end
First of all make sure you have not another apps running ( double tap on home button and flick all running apps to close ). May be images are big and there is not enough memory in your device. If you able to run your app after it try to figure out if you have not memory leaks. Swipe few times and follow your memory.
If you use ARC than assign nil to your vars since you are not going to use them.
I have a UIScrollView that shows a gallery of images from a plist file.
I also have a function to delete an image from the gallery image list that basically deletes an object in the plist file and then reload the images in the ScrollView.
The issue is I am not able to release the images of the UIScrollView before to reload it with the new content when I use the method - (IBAction)deleteimage:(id)sender. The new content is loaded but over the older content and then the images are still behind the new one.
What I should do to release images before to reload the scrollview content?
The code I am using is :
#import "ImageScrollViewController.h"
#interface ImageScrollViewController ()
#end
#implementation ImageScrollViewController
#synthesize images,scrollView,pageControl,subview;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
scrollView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
[self setupthescroll];
self.pageControl.currentPage = 0;
}
- (void)setupthescroll{
//Get the images of the Array
NSUserDefaults *success = [NSUserDefaults standardUserDefaults];
images = [success mutableArrayValueForKey:#"imagelist"];
NSLog(#"list of images%#",images);
pageControlBeingUsed = NO;
for (int i = 0; i < images.count; i++) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
subview = [[UIImageView alloc] initWithFrame:frame];
NSString *str4 = [images objectAtIndex:i];
subview.image = [[[UIImage alloc] initWithContentsOfFile:str4] autorelease];
self.subview.contentMode = UIViewContentModeScaleAspectFit;
[self.scrollView addSubview:subview];
[subview release];
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * images.count, self.scrollView.frame.size.height);
self.pageControl.numberOfPages = images.count;
//Get the number of the images
int page;
page = self.pageControl.currentPage;
printf("Current Page: %d", page);
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
if (!pageControlBeingUsed) {
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (IBAction)changePage {
// Update the scroll view to the appropriate page
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlBeingUsed = YES;
}
- (IBAction)deleteimage:(id)sender{
//Get the number of the image
int page;
page = self.pageControl.currentPage;
printf("Current Page: %d", page);
//Remove the images of the Array
NSUserDefaults *success = [NSUserDefaults standardUserDefaults];
images = [success mutableArrayValueForKey:#"imagelist"];
[images removeObjectAtIndex:page];
NSLog(#"list of images%#",images);
//Update the Array
NSUserDefaults *arrayofimages = [NSUserDefaults standardUserDefaults];
[arrayofimages setObject:images forKey:#"imagelist"];
//Refresh the ScrollView
[self setupthescroll];
//post the notification than images have been updated
NSUserDefaults *deleted = [NSUserDefaults standardUserDefaults];
[deleted setObject:#"deleted" forKey:#"deletedimages"];
}
- (IBAction)closepage:(id)sender{
[self dismissModalViewControllerAnimated:YES];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)dealloc {
[pageControl release];
[scrollView release];
//[images release];
[super dealloc];
}
#end
If you are reloading the entire scrollview (i.e. adding all the images back), you first need to remove the existing images.
Use UIView's removeFromSuperview method to remove views from the scrollview.
So a code snippet to remove all image views from the scrollview would look something like this
NSArray *imgViews = [scrollView subviews];
for(id aView in imgViews){
if([aView isKindOfClass:[UIImageView class]]){
[aView removeFromSuperview]; //remove only if its an imageview
}
}
If you already have reference to the image views, you can directly call the method on them without iterating through all subviews of the scrollview.
You should remove all the UIImageView within the scrollView.
something like
NSArray* subviews = [[scrollview subviews] copy];
for (UIView* v in subviews) {
[v removeFromSuperview];
}
[subviews release];
You forgot to remove the previous image views from the scrollView subviews. A brutal method to to this (at least for testing the hypothesis) would be to add the following line at the beginning of setupthescroll:
[self.scrollView.subviews makeObjectsPerfomSelector:#selector(removeFromSuperview)];
The problem with this would be that the scrollview's private subviews ( scrollers, for instance ) would be removed too.
So in practice you should keep track of the subviews you created in an ivar array, and perform the above line on this array instead of the subviews array, and clear the array afterwards.
Alternatively, a much cleaner method would be to delete only the subview corresponding to the deleted image, and to update the frames of the remaining image views, instead of deleting and recreating everything. You could use a dictionary or the subviews tag property to keep track of wich view is associated to which image.