How to enable zoom for two different UIScrollview in single UIView? - ios

I am displaying two images on single view where both images must have zoom functionality.My page height is around 1000 pixels and images must be display on top and bottom of page. For that I have added two different scroll view and added image views on scroll views.
Now Zoom is working properly for second image .But first image is getting displayed in top left corner of scroll view once zoomed out. It seems there are two images.
Here is the delegate method i am using:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return [[scrollView subviews] objectAtIndex:0];
}
Is there anything i am missing ? or is this not really possible to enable zoom when there are two scroll views for single page.

Here is the code its working for enable zoom when there are two scroll views for single page.
//Create First ImageView
image1 =[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 220)];
image1.image = [UIImage imageNamed:#"image1.png"];
image1.contentMode = UIViewContentModeScaleToFill;
//Create and Set Values for Scrollview 1
scroll1 =[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 220)];
scroll1.contentSize = image1.frame.size;
[scroll1 setMinimumZoomScale:1.0];
[scroll1 setMaximumZoomScale:4.0];
scroll1.delegate = self;
scroll1.clipsToBounds = YES;
scroll1.tag =0;
[scroll1 addSubview:image1];
image1.userInteractionEnabled =YES;
scroll1.zoomScale = 1;
[self.view addSubview:scroll1];
Second Scrollview and ImageView
// Create Second ImageView
image2 =[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 260)];
image2.image = [UIImage imageNamed:#"image2.png"];
image2.contentMode = UIViewContentModeScaleToFill;
// Create Second ScrollView
scroll2 =[[UIScrollView alloc] initWithFrame:CGRectMake(0, 220, 320, 260)];
scroll2.contentSize = image2.frame.size;
[scroll2 setMinimumZoomScale:1.0];
[scroll2 setMaximumZoomScale:4.0];
scroll2.delegate = self;
scroll2.clipsToBounds = YES;
scroll2.tag =1;
[scroll2 addSubview:image2];
image2.userInteractionEnabled =YES;
scroll2.zoomScale = 1;
[self.view addSubview:scroll2];
This will help you, since it is already working for me.
Delegate method as follow:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
if (scrollView.tag ==0) {
return image1;
}
else return image2;
}

Related

How to create slideshow of images within scrollview with autolayout?

I have a collectionview that loads a series of cells. Some of the cells will have static images (which works well), but some might have multiple images that will need to be swipeable.
The UICollectionViewCell is the base view, the UIScrollView is within it (pinned to the top, left, bottom, and right of its superview).
Adding a UIImageView to the scrollview, I want to pin it to the top and left of the scrollview, but have its width and height be the same as the collection view cell, not the content size of the scrollview.
Then I'd like two additional images to be pinned to the top of the collection view cell, and the left closest view (in this case, the prior UIImageView).
The Storyboard would look something like this:
(with the other images off-screen and not displayed).
I decided to add the images via code:
There's a parent view, and a scrollview (attached to an IBOutlet).
The CollectionViewCell subclass contains:
#synthesize lbl, sv, pageControl;
- (void) awakeFromNib {
sv.userInteractionEnabled = NO;
sv.delegate = self;
pageControl.userInteractionEnabled = NO;
[self.contentView addGestureRecognizer:sv.panGestureRecognizer];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageWidth = sv.frame.size.width;
float fractionalPage = sv.contentOffset.x / pageWidth;
NSInteger page = lround(fractionalPage);
self.pageControl.currentPage = page;
}
Then, within the View Controller's collectionView:cellForItemAtIndexPath method, I manually add images like so:
UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[myArray objectAtIndex:indexPath.row]]];
img.frame = (CGRect) { 0, 0, cell.frame.size.width, cell.frame.size.height};
[cell.sv addSubview:img];
img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[myArray objectAtIndex:indexPath.row + 1]]];
img.frame = (CGRect) { cell.frame.size.width, 0, cell.frame.size.width, cell.frame.size.height };
[cell.sv addSubview:img];
img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[myArray objectAtIndex:indexPath.row + 2]]];
img.frame = (CGRect) { cell.frame.size.width * 2, 0, cell.frame.size.width, cell.frame.size.height };
[cell.sv addSubview:img];
[cell.sv setContentSize:CGSizeMake(cell.frame.size.width * 3.0, cell.frame.size.height)];
I would have preferred a StoryBoard/Interface Builder way of doing this, but for now, this will suffice.

Page control on subview

I am creating a view with a subview for a tutorial screen.
I want the gray subview to be swipeable using the page control
I have implemented the example of http://www.appcoda.com/uipageviewcontroller-tutorial-intro/ but this works with whole ViewControllers and I want it to work with only the subview...
Does anyone have any idea how to implement the PageControl with the swipe gesture so that only the gray subview changes? Any good tutorial?
The grey area must be a UIScrollView with a content view containing each page of the tutorial. Set pagingEnabled to YES on your scroll view so that it will snap to each page when you scroll.
Then you need to attach an action to the page control using addTarget:action:forControlEvents: and pass UIControlEventValueChanged as the event. Then the action must be a method that tells the scroll view to move forward or back a page depending on whether the value of the page control increased or decreased. You can do this by changing the scroll view's content offset, or by telling it to scroll so that a particular rect is visible.
Finally, implement the delegate of the UIScrollView, and use the methods that tell when the scroll view stopped scrolling (you'll need a combination of the did end decelerating, did end dragging and possibly did end scrolling animation), and update the page control's value when the scroll view changes pages.
And that's all there is to it. If you need more details, read the documentation for UIScrollView, UIScrollViewDelegate and UIPageControl.
use UIView instead of ViewController
Here is a solution that works for me:
1) Create a scrollView and pageControl in your NIB or Storyboard
2) scrollView in ViewDidLoad
self.scrollView.backgroundColor = [UIColor clearColor];
self.scrollView.indicatorStyle = UIScrollViewIndicatorStyleBlack; //Scroll bar style
self.scrollView.showsHorizontalScrollIndicator = NO;
//dont forget to set delegate in .h file
[self.scrollView setDelegate:self];
self.scrollView.showsVerticalScrollIndicator = YES; //Close vertical scroll bar
self.scrollView.bounces = YES; //Cancel rebound effect
self.scrollView.pagingEnabled = YES; //Flat screen
self.scrollView.contentSize = CGSizeMake(640, 30);
3) create your views you want in the scrollView and add them in an Array
//For instance, you want 3 views
UIView *ViewOne = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)];
[ViewOne setBackgroundColor:[UIColor redColor]];
UIView *ViewTwo = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width+1, self.scrollView.frame.size.height)];
[ViewTwo setBackgroundColor:[UIColor greenColor]];
UIView *ViewThree = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width+2, self.scrollView.frame.size.height)];
[ViewThree setBackgroundColor:[UIColor blueColor]];
//add all views to array
NSMutableArray *viewsArray = [[NSMutableArray alloc] initWithObjects:ViewOne, ViewTwo, ViewThree, nil];
4) pageControl in ViewDidLoad
self.pageControl.numberOfPages = viewsArray.count;
self.pageControl.currentPage = 0;
self.pageControl.backgroundColor = [UIColor clearColor];
[self.pageControl setTintColor:[UIColor whiteColor]];
5) Add it all up
for(int i = 0; i < viewsArray.count; i++)
{
CGRect frame;
frame.origin.x = (self.scrollView.frame.size.width *i) + 10;
frame.origin.y = 0;
frame.size = CGSizeMake(self.scrollView.frame.size.width - 20, self.scrollView.frame.size.height);
NSLog(#"array: %#", [viewsArray objectAtIndex:i]);
UIView *view = [[UIView alloc] initWithFrame:frame];
view = [viewsArray objectAtIndex:i];
[self.scrollView addSubview:view];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width*viewsArray.count, self.scrollView.frame.size.height);
}
6) Track the scrollView and update the pageControl (DONT FORGET THE SCROLLVIEW DELEGATE)
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
CGFloat pageWidth = scrollView.frame.size.width;
//int page = floor((scrollView.contentOffset.x - pageWidth*0.3) / pageWidth) + 1);
self.pageControl.currentPage = (int)scrollView.contentOffset.x / (int)pageWidth;
NSLog(#"CURRENT PAGE %d", self.pageControl.currentPage);
}
This should do the trick.
PS. Sorry for all the magic numbers.

Zooming in UIScrollView - Unable to zoom beyond single image and scroll

I have an array of images loading from the NSURL to scroll in and pinch zoom. I was able to implement the scroll part but when I try to zoom any image beyond the first one, the scroll is stuck and so is the scale on the image. Here is my code:
scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 100, SCREEN_WIDTH, self.view.bounds.size.height)];
scrollView.showsHorizontalScrollIndicator = FALSE;
scrollView.maximumZoomScale = 4.0;
scrollView.minimumZoomScale = 1.0;
scrollView.delegate = self;
[self.view addSubview:scrollView];
for (int i=0; i<[listOfImagesZoom count]; i++) {
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(leftMargin, self.scrollView.bounds.origin.y-100, SCREEN_WIDTH, self.view.bounds.size.height-100)];
// [imageView setImage:[UIImage imageNamed:#"img_def.png"]];
NSString *urlImage1 = (NSString*)[listOfImagesZoom objectAtIndex:i];
NSString *productImageURL1 = [urlImage1 stringByReplacingOccurrencesOfString:#"~" withString:#""];
NSString *productImageURL2 = [productImageURL1 stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSString* urlImage = [NSString stringWithFormat:#"http://sagana-ideas.azurewebsites.net%#", productImageURL2];
NSURL *imgURL=[NSURL URLWithString:urlImage];
[imageView setImageWithURL:imgURL placeholderImage:[UIImage imageNamed:#"ex_product.png"]];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[scrollView addSubview:imageView];
[imageView setUserInteractionEnabled:NO];
imageView.tag = i;
leftMargin += SCREEN_WIDTH;
}
[scrollView setContentSize:CGSizeMake(leftMargin, 0)];
[scrollView setPagingEnabled:YES];
scrollView.delegate = self;
I have even implemented the
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageView;
}
It works if there is only single image to load, but is stuck when there is more than 1 image.
You need a ScrollView to display list of your images. Each image was displayed a scrollView(a subclass scrollview) to perform zoom in/out.
Try to look at this: MWPhotoBrowser
You can create a UIView inside scrollview in which you may add your all images and then return that view from, - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView method.

Start ScrollView Somewhere Else Besides First Image

Hi I am looking to see if I can take my scroll view which I have created below and start the scroll view on the 3rd or 4th image rather than start the scroll view from the beginning. Basically I dont want it to start on the first image but still be able to scroll backwards to get to them. Is this possible? Thank you!
int PageCount = 34;
NSMutableArray *arrImageName =[[NSMutableArray alloc]initWithObjects:#"4miley.png",#"4BP1-2.png",#"S2-4.png",#"D3-4.png",#"4BP1-1.png",#"F2-4.png",#"B6-4.png",#"D6-4.png",#"4BP1-3.png",#"S1-4.png",#"B7-4.png", #"D2-4.png",#"F7-4.png",#"B1-4.png",#"F3-4.png",#"4BP1-4.png",#"D5-4.png",#"S3-4.png",#"B2-4.png",#"F5-4.png",#"D4-4.png",#"S7-4.png",#"F1-4.png",#"B3-4.png",#"S4-4.png",#"F6-4.png",#"D1-4.png",#"4BP1-5.png",#"B4-4.png",#"S5-4.png",#"F4-4.png",#"D7-4.png",#"S6-4.png",#"B5-4.png",nil];
scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
scroller.scrollEnabled=YES;
scroller.backgroundColor = [UIColor clearColor];
[scroller setShowsHorizontalScrollIndicator:NO];
scroller.pagingEnabled = YES;
scroller.bounces = NO;
scroller.delegate = self;
[self.view addSubview:scroller];
width=scroller.frame.size.width;
xPos=0;
for (int i=0; i<PageCount; i++)
{
ImgView = [[UIImageView alloc]initWithFrame:CGRectMake(xPos, 0, scroller.frame.size.width, scroller.frame.size.height)];
[ImgView setImage:[UIImage imageNamed:[arrImageName objectAtIndex:i]]];
[scroller addSubview:ImgView];
scroller.contentSize = CGSizeMake(width, 0);
width +=scroller.frame.size.width;
xPos +=scroller.frame.size.width;
}
After initializing images in scrollview , You can use scrollRectToVisible method to display 3rd and 4th image, set the frame of 3rd image in this method.
[scroller scrollRectToVisible:frame animated:YES];
//frame = your 3rd image
Once you have calculated the x pos & y pos of your 3rd or 4th image, you can use
[scrollView setContentOffset:CGPointMake(x, y) animated:YES];
or
[scrollView scrollRectToVisible:rect animated:YES];//put the rect of your image
After initializing images in scrollview , You can use setContentOffset:animated: method to display 3rd or 4th image
[scroller setContentOffset:CGPointMake(3*320, 0) animated:YES];

Stick a UILable to UIView or UIImageView

I have a subview in my app that contains a UIImageView. The user can touch this subview and move it around. I have some UILabels that I want to "stick" or group with the subview so that they move along with it. I wonder how to do that?
Here is where I add the Labels to the subview:
- (void)viewDidLoad
{
[super viewDidLoad];
//Decrease the site of root CALayer of the view and give it round corners
self.view.layer.backgroundColor = [UIColor orangeColor].CGColor;
self.view.layer.cornerRadius = 10.0;
self.view.layer.masksToBounds = YES;
self.view.layer.frame = CGRectInset(self.view.layer.frame, 40, 40);
//check if the background is from the photo library and create a sublayer for the semi transparent white badge and a textsublayer for the countdown labels. Also hide the regular view labels
NSString *path = [_occasion imagePath];
if (path != nil && [path hasPrefix:#"ass"])
{
//Make a subview with a UIImageView inside for the badge
CGRect badgeRect = CGRectMake(32, 13, 236, 222);
UIView *badge = [[UIView alloc] initWithFrame:badgeRect];
imageView = [[UIImageView alloc]initWithFrame:[badge frame]];
[imageView setImage:[UIImage imageNamed:#"badge.png"]];
[badge addSubview:imageView];
[self.view addSubview:badge];
/*[self.view bringSubviewToFront:countDownLabel];
[self.view bringSubviewToFront:daysLabel];
[self.view bringSubviewToFront:hoursLabel];
[self.view bringSubviewToFront:minutesLabel];
[self.view bringSubviewToFront:secondsLabel];
[self.view bringSubviewToFront:daysName];
[self.view bringSubviewToFront:hoursName];
[self.view bringSubviewToFront:minutesName];
[self.view bringSubviewToFront:secondsName];*/
[badge addSubview:countDownLabel];
[badge addSubview:daysLabel];
[badge addSubview:hoursLabel];
[badge addSubview:minutesLabel];
[badge addSubview:secondsLabel];
[badge addSubview:daysName];
[badge addSubview:hoursName];
[badge addSubview:minutesName];
[badge addSubview:secondsName];
//more code for recognizing the touches on the subview
Just put them on the UIImageView and they'll move along with it.
You can get the position of your subview and change the position of you labels according to that.

Resources