I am trying to create a UIScrollView programatically. I have a scrollView for that ViewController. Here is how I instantiate it in loadView:
CGRect fullScreenRect = [[UIScreen mainScreen] applicationFrame];
self.scrollView = [[UIScrollView alloc] initWithFrame:fullScreenRect];
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);
I then some items onto it, and then add it to view in loadView as follows:
[self.scrollView addSubview:self.searchBar];
[self.scrollView addSubview:button];
[self.view addSubview:self.scrollView];
So far everything should be fine. However, in other functions, I will be adding ImageViews and then I will need to set the scrollview's content size. The way I do it is just use [self.scrollView addToSubView:image] and when I want to edit the content size of the scrollview, I do it as follows:
// Calculate scroll view size
float sizeOfContent = 0;
for (int i = 0; i < [self.scrollView.subviews count]; i++) {
UIImageView *view =[self.scrollView.subviews objectAtIndex:i];
sizeOfContent += view.frame.size.height;
[view release];
}
// Set content size for scroll view
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width, sizeOfContent);
I keep getting an EXC_BAD_ACCESS error in the main.m class.
I suspect that the problem is with retaining the actual scrollView since I think scrollView is not retaining the same object that is a subview of view.
Any suggestions? Thanks in advance!
If you have defined self.scrollView as #property(nonatomic, retain) then first wrong thing is the line;
self.scrollView = [[UIScrollView alloc] initWithFrame:fullScreenRect];
It sets the retain count of scrollView to 2, which is not what you expect. alloc retained properties like this,
scrollView = [[UIScrollView alloc] initWithFrame:fullScreenRect];
I think your BAD_ACCESS error comes from here;
for (int i = 0; i < [self.scrollView.subviews count]; i++) {
UIImageView *view =[self.scrollView.subviews objectAtIndex:i];
sizeOfContent += view.frame.size.height;
[view release];
}
Why are you releasing view? You did not alloc it, so there is no reason to release it. Remove the [view release] line and check again.
Related
I want to implement paging concept for two views,I implemented it and it is working fine, but in that given views, First view should have 2views,and 2 buttons in the navigation bar, if I select one button it will show one view, and for second button it should show second view, I am using Xib to add scroll view, and adding views in that.
Now the issue is i didn't get secondview while selecting the second button in the firstView.
Please guide me to solve this issue.
I am using this code to getting Views in scrollview.
NSArray *views = [NSArray arrayWithObjects:maleCircleView,femaleCircleView, nil];
for (int i = 0; i < views.count; i++)
{
UIView *subview = [views objectAtIndex:i];
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i+10;
frame.origin.y = subview.frame.origin.y-30;
frame.size = self.scrollView.frame.size;
[titleLabel setHidden:YES];
subview.frame = frame;
if(i==0)
{
UIView *femaleView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];
[femaleView setBackgroundColor:[UIColor redColor]];
[femaleView setTag:subview.tag+11];
UIImageView *sample = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"save.png"]];
sample.frame = CGRectMake(250, 50, 50, 50);
[femaleView addSubview:sample];
NSLog(#"femaleView:%#",femaleCircleView);
[self.scrollView addSubview:femaleView];
[femaleView addSubview:maleCircleView];
// [femaleView setHidden:YES];
}
NSLog(#"subview:%#",subview);
[self.scrollView addSubview:femaleCircleView];
}
Use bringSubviewToFront method.
[self.view bringSubviewToFront:yourSelectedView];
I think it will be helpful to you.
I'm trying to make an application that uses a UIScrollView to page between an indeterminate number of dynamically generated custom view controllers. Unfortunately, when I try the code shown below, all I get is a blank screen. Additionally, the nslog statement that I put right after the subview is supposedly added to the UIScrollView always says that the UIScrollView has zero subviews. I'm totally baffled by this problem and would greatly appreciate any help.
- (void)loadView
{
[super loadView];
scrollView.pagingEnabled = YES;
viewControllers = [[NSMutableArray alloc] init];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
CGFloat width = screenBounds.size.width * screenScale;
CGFloat height = screenBounds.size.height * screenScale;
scrollView.contentSize = CGSizeMake(width * [routes count], height);
for( int i = 0; i < [arrayWithDataForViewControllers count]; i++)
{
ViewController *controller = [[ViewController alloc] init];
controller.view.frame = CGRectMake(width*i, 20, width, height);
[scrollView addSubview:controller.view];
NSLog(#"SUBVIEWS %d", [[scrollView subviews] count]);
[viewControllers addObject:controller];
}
}
Check your ViewController's view outside of the scrollview - chances are that it's view property is nil.
I have a scrollview of images, I will like to tab them and will pushed to another view.
once i tab on the image, the whole view should push to another view.
From this View to another view
Detail view
Sorry for not asking the question clearly.
my scrollview
-(void)pictureScrolling
{
//init scrollview in location on screen
scrollview = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 100, 320, 290)];
scrollview.backgroundColor = [UIColor redColor];
//pass image filenames
NSMutableArray *fileNames = nearbyFrog.imageFiles; //[[[NSMutableArray alloc] init] autorelease];
//setup the array of uiimageviews
NSMutableArray *imgArray = [[NSMutableArray alloc] init];
UIImageView *imageView;
//loop through the array imgNames to add file names to imgArray
for (NSString *imageName in fileNames) {
imageView = [[UIImageView alloc] init];
imageView.image = [UIImage imageNamed:imageName];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[imgArray addObject:imageView];
[imageView release];
}
CGSize pageSize = scrollview.frame.size;
NSUInteger page = 0;
for (UIView *viewForScrollView in imgArray) {
[scrollview addSubview:viewForScrollView];
viewForScrollView.frame = CGRectMake(pageSize.width * page++ +10, 0, pageSize.width -20 , pageSize.height);
// making use of the scrollView's frame size (pageSize) so we need to;
// +10 to left offset of image pos (1/2 the gap)
// -20 for UIImageView's width (to leave 10 gap at left and right)
}
//add scroll view to view
[self.view addSubview:scrollview];
scrollview.contentSize = CGSizeMake(pageSize.width * [imgArray count], pageSize.height);
//scrollview.contentSize = CGSizeMake(320 *viewcount + 20, 290 );
scrollview.showsHorizontalScrollIndicator =NO;
[scrollview setPagingEnabled:YES];
scrollview.delegate =self;
//paging function for scrollview
CGRect frame = [[UIScreen mainScreen] applicationFrame];
self.pageControl = [[[UIPageControl alloc] initWithFrame:CGRectMake(0, 100, 100, 50)] autorelease];
self.pageControl.center = CGPointMake(frame.size.width/2, frame.size.height-60);
self.pageControl.numberOfPages = [fileNames count];
[self.view addSubview:self.pageControl];
//handle Touch Even
[pageControl addTarget:self action:#selector(changePage:) forControlEvents:UIControlEventValueChanged];
[imgArray release];
}
anybody knows how to do it or can show me a tutorial?
Thanks
I think this is the best way to implement it
Create your own Custom UIImageView class. This is required to store an additional property which will help you identify which image for clicked.
Create a delegate for that class which is called with the single tap event is raised in the UIImageView
Add the Images inside the scrollview using this custom class. The delegate of this class will tell you which image was tapped. You can use this to push a new view controller passing the image details (if necessary).
You can find some sample code in the ThumbImageView class in the scrollviewSuite sample
http://developer.apple.com/library/ios/#samplecode/ScrollViewSuite/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008904-Intro-DontLinkElementID_2
Hi, I have a big image and small image over it at a specific location...
I added them all under ScrollView, but it didn't work properly?
I want to zoom in, all together each in its place
Here is my code:
myScrollView.contentSize = CGSizeMake(imageView.frame.size.width, imageView.frame.size.height);
myScrollView.maximumZoomScale = 3.0;
myScrollView.minimumZoomScale = 1.0;
myScrollView.clipsToBounds = YES;
myScrollView.delegate = self;
[myScrollView addSubview:imageView];
thanks
Hi, mackworth; I did it, but if I didn't maximize the image, I can't move the scroll view anywhere, but if I zoomed it, I can see the rest.. I don't know why I tried changing it, but it work. Can you please look at the following code?
- (void)viewDidLoad{
[super viewDidLoad];
UIImage *image = [UIImage imageNamed:#"ucd.png"];
//creating a view for UCD image
ucdView = [[UIImageView alloc] initWithImage:image];
//setting the frame for the ucdView as the same size of ucd image
[ucdView setFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
//for the red pin to display in specific loc
UIImageView *Health = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"redPin.png"]];
[Health setCenter:CGPointMake(310,135)];
//adding helathView to ucdview
[ucdView addSubview:Health];
//everything for scroll view
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, ucdView.frame.size.width, ucdView.frame.size.height)];
[scrollView setMinimumZoomScale:1.0];
[scrollView setMaximumZoomScale:3.0];
scrollView.clipsToBounds = YES;
[scrollView setContentSize:CGSizeMake(image.size.width, image.size.height)];
[scrollView setDelegate:self];
[scrollView addSubview:ucdView];//adding ucd view to scroll view
[self.view addSubview:scrollView]; // adding scrollview to self.view main view
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {//apply zooming for scrollview
return scrollView;
}
Did you implement:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
Also, you know that by setting the scrollView's contentSize to your imageSize, it can't grow any bigger than that, right? It'll zoom in place, cropping the outer pixels accordingly. As an aside, if that is your plan, why not just set it directly?
myScrollView.contentSize = imageView.frame.size;
=====Further answer, responding to additional source
Well, the main thing I notice is that you need to return the imageView ucdView in viewForZoomingInScrollView, not the scrollView. It looks like you already created ucdView as a property (so that it lives as long as your view does), but just in case...
1) In your .h file:
UIImageView * ucdView;
#property (nonatomic, retain) UIImageView * ucdView;
2) In your .m file;
#synthesize ucdView;
3) change your line:
ucdView = [[UIImageView alloc] initWithImage:image];
to just
self.ucdView = [[UIImageView alloc] initWithImage:image];
4) change the line
return scrollView
to:
return self.ucdView;
5) Add the following to your dealloc routine:
self.ucdView = nil;
Also, did you add <UIScrollViewDelegate> protocol to your ViewController definition (in .h file)?
Finally, you have a leak of scrollview and Health; add [scrollView release]; and [Health release] at end of viewDidLoad
Its a familiar topic Im creating a graphic novel using UIScrollview. The plan is to be able to page along the novel with a top level uiscrollview. Within this are a series of nested uiscrollviews which have a uimageview embedded within each. The idea is that large images can be panned around and zoomed into but still paged along. I have most of this working but I cant get the zoom working. I have implemented the zoom delegate method but to no avail, zooming just pans the image around. I suspect this is something due to embedded nature of the nested scrollviews but I cant see what im missing. I had a look at the Apple scrollview suite example but couldnt find an answer.
This is what I have working so far:
- (void)viewDidLoad
{
[super viewDidLoad];
UIScrollView *scrollview = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height)];
scrollview.pagingEnabled = YES;
scrollview.scrollEnabled =YES;
scrollview.clipsToBounds = NO;
scrollview.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollview.showsHorizontalScrollIndicator = YES;
scrollview.backgroundColor = [UIColor blackColor];
NSInteger viewcount=4;
NSArray *images = [NSArray arrayWithObjects:[UIImage imageNamed:#"mars.png"],[UIImage imageNamed:#"mercury.png"],[UIImage imageNamed:#"neptune.png"],[UIImage imageNamed:#"venus.png"],nil];
for (int i = 0; i <viewcount; i++)
{
CGFloat x = i * self.view.frame.size.width;
subView = [[UIScrollView alloc]initWithFrame:CGRectMake(x, 0, self.view.frame.size.width, self.view.frame.size.height)];
[subView setBackgroundColor:[UIColor blackColor]];
[subView setCanCancelContentTouches:NO];
subView.clipsToBounds = NO; // default is NO, we want to restrict drawing within our scrollview
subView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
aImageView = [[UIImageView alloc ] initWithImage:[images objectAtIndex:i]];
[self.aImageView setTag:ZOOM_VIEW_TAG];
[subView addSubview:aImageView];
[subView setContentSize:CGSizeMake(aImageView.frame.size.width, subView.frame.size.height)];
subView.minimumZoomScale = 1;
subView.maximumZoomScale = 3;
subView.delegate = self;
[subView setScrollEnabled:YES];
subView.contentSize = aImageView.frame.size;
[scrollview addSubview:subView];
[subView release];
}
[self.view addSubview:scrollview];
}
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView {
NSLog (#"test");
UIView * view = nil;
view = [subView viewWithTag:ZOOM_VIEW_TAG];
return view;
}
Worked this out, for anyone else trying to do this.
One thing I missed a line of code out on the post above which is quite fundamental!, in the viewdidLoad method
just above [self.view addSubview:scrollview]; there should be the following which calculates the width of all of the subviews
scrollview.contentSize = CGSizeMake(self.view.frame.size.width*viewcount,self.view.frame.size.height);
The code in the -(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView {
method should be:
return [scrollView.subviews objectAtIndex:0];
This allows you to zoom and pan around images and also page along a set of images very nicely. Just got to work out how to zoom back to the original size automagically when moving on to the next image as its stays zoomed upon paging along..