I have a UIScrollView containing 5 images. I want to add a UIPageControl at the bottom of my scroll view so that the user can see what page they are on.
Here is my code for the scroll view:
self.helpScrollView.contentSize = CGSizeMake(320 * 5, 436);
UIImageView *image1 = [[UIImageView alloc] initWithFrame:CGRectMake(320 * 0, 0, 320, 436)];
image1.image = [UIImage imageNamed:[NSString stringWithFormat:
#"Guide Page One.png"]];
[self.helpScrollView addSubview:image1];
UIImageView *image2 = [[UIImageView alloc] initWithFrame:CGRectMake(320 * 1, 0, 320, 436)];
image2.image = [UIImage imageNamed:[NSString stringWithFormat:
#"Guide Page Two.png"]];
[self.helpScrollView addSubview:image2];
UIImageView *image3 = [[UIImageView alloc] initWithFrame:CGRectMake(320 * 2, 0, 320, 436)];
image3.image = [UIImage imageNamed:[NSString stringWithFormat:
#"Guide Page Three.png"]];
[self.helpScrollView addSubview:image3];
UIImageView *image4 = [[UIImageView alloc] initWithFrame:CGRectMake(320 * 3, 0, 320, 436)];
image4.image = [UIImage imageNamed:[NSString stringWithFormat:
#"Guide Page Four.png"]];
[self.helpScrollView addSubview:image4];
UIImageView *image5 = [[UIImageView alloc] initWithFrame:CGRectMake(320 * 4, 0, 320, 436)];
image5.image = [UIImage imageNamed:[NSString stringWithFormat:
#"Guide Page Five.png"]];
[self.helpScrollView addSubview:image5];
self.helpScrollView.pagingEnabled = true;
self.helpScrollView.showsHorizontalScrollIndicator = NO;
I have dragged a UIPageControl onto my scrollview in my xib file, but I don't know how to link them. How do I do this?
You don't want to add the UIPageControl to the scroll view itself because you don't want it to scroll with the content.
With that said, take a look at the UIScrollViewDelegate protocol, specifically scrollViewDidEndDecelerating: which will be called when your scroll view stops moving (a good time to update your UIPageControl).
Your calculation is going to be something like..
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
self.pageControl.currentPage = floorf(scrollView.contentOffSet.x/320);
}
Re: I have two scroll views within one view controller, so does this specify which one I'm using?
The scrollView instance passed in can be used to negotiate which scroll view did end decelerating. If you set the delegate property for both of your scroll views this will get called when either of those end decelerating so you'll need to verify which instance ended decelerating.
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView == self.helpScrollView) {
self.pageControl.currentPage = floorf(scrollView.contentOffset.x/scrollView.frame.size.width);
}
}
Related
I have an UIImageView and I want to implement fling feature, when users flings on the screen the page can go up or down quickly.
Now my thinks is add two UISwipeGesturesRecognizers, but I don't know how to do next, should I use an animation to do this, and how to calculate the animation distance and time?
Also I find other answers said no need gesture recognizer can use scroll view, I am totally confused, are there any sample I can learn?
You can do it like that :
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[scrollView setPagingEnabled:YES];
[scrollView setAlwaysBounceVertical:YES];
NSArray *imagesArray = [NSArray arrayWithObjects:#"img1.png", #"img2.png", #"img3.png", nil];
for (int i = 0; i < [imagesArray count]; i++)
{
CGFloat xOrigin = i * scrollView.frame.size.width;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(xOrigin, 0, scrollView.frame.size.width, scrollView.frame.size.height)];
[imageView setImage:[UIImage imageNamed:[imagesArray objectAtIndex:i]]];
[imageView setContentMode:UIViewContentModeScaleAspectFit];
[scrollView addSubview:imageView];
}
[scrollView setContentSize:CGSizeMake(scrollView.frame.size.width, scrollView.frame.size.height*[imagesArray count])];
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.
I am trying to display images in a horizontal row using pages,with each page containing 4 images probably separated by a little space of one line or without space. As the user scrolls horizontally, next four images are displayed in the center of view. But using this code:
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, screenHeight/4, screenWidth, screenHeight/4)];
scroll.showsHorizontalScrollIndicator = YES;
scroll.showsVerticalScrollIndicator=NO;
scroll.pagingEnabled = YES;
NSInteger numberOfViews = 3;
int k=1;
for (int i = 0; i < numberOfViews; i++) {
CGFloat xOrigin = i * self.view.frame.size.width;
UIView *awesomeView = [[UIView alloc] initWithFrame:CGRectMake(xOrigin, 0, self.view.frame.size.width, self.view.frame.size.height)];
awesomeView.backgroundColor = [UIColor colorWithRed:0.5/i green:0.5 blue:0.5 alpha:1];
[scroll addSubview:awesomeView];
for (int j=0; j<4; j++) {
NSString *imageName = [NSString stringWithFormat:#"image%d.png", k];
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect imageFrame=CGRectMake(0, k*screenHeight/4, screenWidth/5, screenHeight/5);
imageView.frame=imageFrame;
[awesomeView addSubview:imageView];
k++;
}
images are displayed vertically on first page view. Moreover it looks like vertical scrolling is working. What I am missing?
In this line:
CGRect imageFrame=CGRectMake(0, k*screenHeight/4, screenWidth/5, screenHeight/5);
You are messing with frame your imageView (inside UIView - awesomeView).
Your k variable is 1,2,3,4
So i assume that you have 4 imageViews in vertical, and next 'column' with four image on the left, right?
Also you don't set contentSize for your scrollView anywhere so, you might not see the second 'column'
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;
}
I have a UIScrollView that I would like to use with a UIPageControl to have different pages to swipe horizontally. I need to add a UITextView and a number of UIImageView for every page.
In my ViewController I call a webservice and, when data arrive, I add items as follows:
for(int i=0;i<[arrData count];i++) {
NSString *body=#"Dummy text";
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size.width = self.scrollView.frame.size.width;
frame.size.height = 40; //vedere landscape
UILabel *label = [[UILabel alloc] initWithFrame:frame];
[label setText:body];
label.numberOfLines=0;
[label sizeToFit];
label.autoresizingMask=UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.scrollView addSubview:label];
[label setBackgroundColor:[UIColor whiteColor]];
[self.scrollView addSubview:label];
int y_pos=label.frame.size.height+10;
int x_pos=0;
for(int img=0; img<[[[arrData objectAtIndex:i]objectForKey:#"images"] count]; img++) {
NSString *imageURL=[[[[arrData objectAtIndex:i] objectForKey:#"images"] objectAtIndex:img] objectForKey:#"fn"];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];
UIImage *image = [UIImage imageWithData:imageData];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[imageView setFrame:CGRectMake(self.scrollView.frame.size.width * i+img*100, y_pos, image.size.width, image.size.height)];
[self.scrollView addSubview:imageView];
}
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * [arrData count], self.scrollView.frame.size.height);
It runs fine in portrait, but when the device is rotated, obviously, the layout is ruined ... which is the best way to work with a ScrollView with PageControl? Do I have to handle rotation and change the distance between the inserted items or (as I think) is there a better way to build everything?
yes you have to set your scrollviews frame again every time orientation changes, because flexible width stretches the width of scrollview from both sides in landscape mode,so its contents get overlapped and causes problem when you have horizontal scrolling. one thing you can do is set you scrollview's auto resizing mask to flexibleRightMargin|flexibleLeftMargin. it will keep the contents of your scrollview at the center but scrolling will not look clean.