How to convert frame from UIScrollView to UIView - ios

I want to convert frame from UIScrollView to UIView, but not exaclty.
This is my code:
//Create UIScrollView addSubview self.view
scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
[scrollView setBouncesZoom:YES];
[scrollView setMinimumZoomScale:1];
[scrollView setZoomScale:4];
scrollView.delegate = self;
//create UIView overlay UIScrollView and addSubview self.view
overlayView = [[UIView alloc] initWithFrame:self.view.bounds];
overlayView.backgroundColor = [UIColor blueColor];
overlayView.alpha = 0.5;
[self.view addSubview:overlayView];
//create UIView addSubView overlayView, can move change postion
UIView *moveView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
moveView.backgroundColor = [UIColor redColor];
[overlayView addSubView:moveView];
If zoom in, zoom out scrollView, moveView change position by ratio when scrollView zoom in zoom out.
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
[scrollView setZoomScale:scale+0.01 animated:NO];
[scrollView setZoomScale:scale animated:NO];
CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = CGSizeMake(scrollView.bounds.size.width * scrollView.zoomScale, scrollView.bounds.size.height * scrollView.zoomScale);
visibleRect.origin.x = 0;
visibleRect.origin.y = 0;
overlay.frame = visibleRect;
CGRect moveRect = moveView.frame;
moveRect.origin.x *= scrollView.zoomScale;
moveRect.origin.y *= scrollView.zoomScale;
moveRect.size.width *= scrollView.zoomScale;
moveRect.size.height *= scrollView.zoomScale;
moveView.frame = moveRect;
}
I cannot change postion moveView exactly when scrollView zoom in zoom out. Please help me resolve this issue.

First I'd say, you really need to be using autolayout for all this stuff. Or none of this will work if you rotate the device, or on different devices, etc. Just using frames to position views is just not the done way anymore. It will work to a degree though. Yes autolayout is a learning curve but you just need to know it and use it all the time.
But looking at the code there two issues stand out : at the start of the didEndZooming method, you set the scale twice, Im not sure why -
[scrollView setZoomScale:scale+0.01 animated:NO];
[scrollView setZoomScale:scale animated:NO];
Then also later, you set the origin of the visibleRect property twice in different ways :
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = CGSizeMake(scrollView.bounds.size.width * scrollView.zoomScale, scrollView.bounds.size.height * scrollView.zoomScale);
visibleRect.origin.x = 0;
visibleRect.origin.y = 0;
Setting the x and y values there is the same as setting the origin to the scrollView.contentOffset - so first you set the origin to the content offset position, then to 0,0 - which doesnt make sense. Clearing up those problems might sort things out.

Related

iOS moving tapped point on View within ScrollView to the center of screen

I have an UIView(0,0,1000,1000) within an UIScrollView(0,0,500,500) as the UIScrollView's
content, here's my code:
//ScrollView setting
ScrollView.minimumZoomScale = 0.5;
ScrollView.maximumZoomScale = 1.0;
ScrollView.contentSize = View.frame.size
ScrollView.delegate = self;
//Get the tapped point & Place a mark on it
//already add an UITapGestureRecognizer on View
CGPoint tapped = [tapRecognizer locationInView:View];
UIView mark = [[UIView alloc] initWithFrame:CGRectMake(tapped.x-25,tapped.y-25,50,50)];
[View addSubview:mark];
//Centering the tapped point (1.0x)
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGPoint screenCenter = CGPointMake(screenRect.size.width/2,screenRect.size.height/2);
[ScrollView setContentOffset:(tapped-screenCenter.x, tapped-screenCenter.y) animated:YES];
This works fine when the UIScrollView zoom scale is 1.0x, but when I zoom it to 0.5x with code modified as below:
//Get zoom scale
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale{
CGfloat zoomScale = scale;
}
//Centering the tapped point (0.5x)
[ScrollView setContentOffSet:(tapped-screenCenter.x/zoomScale, tapped-screenCenter.y/zoomScale) animated:YES];
It didn't work as I expected, please help me figure it out.
[View setContentOffSet:(tapped-screenCenter.x * zoomScale, tapped-screenCenter.y * zoomScale) animated:YES];
You multiply by scale, not divide.

Why is UIScrollView's contentSize adjusted when zooming?

With the code below, I see a red square appear which I can scroll around (because scrollview's content is 4x screen).
But once I start zooming out (scale < 1.0), the scrollview's contentSize immediately jumps to scale times the iPad's screen size. For example:
0.985783 757.081249 1009.441665
After which I cannot move the square around anymore. I can only move the square when scale get's above 1.0; in which case the scroll indicators show that the contentSize is still scale times screen size.
Another effect is that when zooming out below 1.0, the red square moves toward the top-left corner normally by zooming out. However, after I release the screen (without any further zooming), it moves even further to the corner. EDIT: This must be the rubber banding of the scrollview.
(The square itself does scale as expected.)
What I am missing here? Here's my view controller code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.scrollView = [[UIScrollView alloc]initWithFrame:self.view.bounds];
self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width * 2, self.view.bounds.size.height * 2);
self.scrollView.backgroundColor = [UIColor colorWithWhite:0.5f alpha:1.0f];
self.scrollView.minimumZoomScale = 0.1f;
self.scrollView.maximumZoomScale = 4.0f;
self.scrollView.clipsToBounds = YES;
self.scrollView.delegate = self;
self.contentView = [[UIView alloc] initWithFrame:self.scrollView.bounds];
[self.scrollView addSubview:self.contentView];
[self.view addSubview:self.scrollView];
UIView* view = [[UIView alloc] initWithFrame:CGRectMake(400, 400, 100, 100)];
view.backgroundColor = [UIColor redColor];
[self.contentView addSubview:view];
}
#pragma UIScrollViewDelegate
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.contentView;
}
- (void)scrollViewDidEndZooming:(UIScrollView*)scrollView
withView:(UIView*)view
atScale:(double)scale
{
NSLog(#"%f %f %f", scale, self.scrollView.contentSize.width, self.scrollView.contentSize.height);
}

UIScrollview doesn't scroll iOS

I'm creating several scroll views in one view that scroll horizontally. The following code works fine:
-(void)updateSection {
builder = [NSMutableArray array];
float xPosition = 0;
float xposbut = 100;
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 100, self.frame.size.width, self.frame.size.height - 69)];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
scrollView.delegate = self;
[self addSubview:scrollView];
for (int i = 1; i < itemArticleArray.count; i++) {
ItemView *item = [ItemView loadNibs];
item.frame = CGRectMake(xposbut, 10, item.frame.size.width, item.frame.size.height);
xPosition += scrollView.frame.size.width + 2;
xposbut += 500;
UIView *seperatorView = [[UIView alloc] initWithFrame:CGRectMake(xposbut - 50, 4, 2, scrollView.frame.size.height - 8)];
[scrollView addSubview:seperatorView];
xPosition += scrollView.frame.size.width + 4;
[scrollView addSubview: item];
[builder addObject:item];
}
[scrollView setContentSize:CGSizeMake(xposbut, scrollView.frame.size.height)];
[self addSubview:scrollView];
}
However, when I change the 8th line of code to the following:
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 400, self.frame.size.width, self.frame.size.height - 69)];
It cause the layout to look fine, but the scroll views do then not scroll at all. Any ideas?
you set the contentSize.height to the scrollView.frame.size.height and so the scrollView cant scroll. you have to set the contentSize to the total height of you scrollView, including the not visible area. The frame is only the area on screen.
UIScrollview will scroll when content size is bigger then frame size. In your code you set content size equal to frame size that's why your scrollview is not scrolling.
Set the content size for the scroll view. The content size should be greater than frame.size, then only the scroll view will scroll. And also enable scrolling.
Use the code
scrollView.scrollEnabled=YES;
scrollView.contentSize=CGSizeMake(CGFloat width, CGFloat height);
Height should be greater than scrollView.frame.size.height and add contents inside scrollview beyond the scrolview's frame.
You must give the scroll some space to work so check this out:
Create the scroll in the storyboard
Create an outlet for the scroll
And the in the .m file you must paste these lines
The code:
(void)viewDidLoad {
[super viewDidLoad];
yourScroll.scrollEnabled=YES;
yourScroll.contentSize=CGSizeMake(self.view.frame.size.width, self.view.frame.size.height*2);
}
/*
* yourScroll.contentSize=CGSizeMake(your desired scroll width, your desired scroll height);
* The values must be bigger than the viewController size
*/

How do I use UIPageControl in my app?

I am making an app where I need some images can be scrolled through using a UIPageControl. Sadly, I don't know how to use a UIPageControl, or a UIScrollView either. A link to a YouTube video or Xcode documentation by Apple would be much appreciated!
Thanks in advance!!
here is a code which will help you
CGSize size = [[UIScreen mainScreen] bounds].size;
CGFloat frameX = size.width;
CGFloat frameY = size.height-30; //padding for UIpageControl
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(offsetX, offsetY, frameX, frameY)];
scrollView.pagingEnabled = YES;
scrollView.backgroundColor = [UIColor clearColor];
scrollView.contentSize = CGSizeMake(frameX, frameY);
[self.view addSubview: scrollView];
// let say you have array of image in imageArray
for(int i = 0; i < [imageArray]; i++)
{
UIImage *image = [UIImage imageNamed:[imageArray objectAtIndex:i]];
imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(frameX * i, 0.0, frameX, frameY);
[scrollView addSubview:imageView];
}
scrollView.contentSize = CGSizeMake(frameX*[imageArray count], frameY);
please declare the variables according to scope of use. i have declared all the variables locally so that might not get confuse and also add the UIPageControl at the bottom of your viewcontroller
Implement the delegate method of UIScrollView to the current Page indicator
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
float width = scrollView.frame.size.width;
float xPos = scrollView.contentOffset.x+10;
//Calculate the page we are on based on x coordinate position and width of scroll view
pageControl.currentPage = (int)xPos/width;
}
where pageControl is UIPageControl added on bottom your viewcontroller
ScrollView:
ScrollView is used to display the more number views/Objects. We can display those views by horizontal or vertical scrolling.
You can handle zooming, panning, scrolling etc.
You can go through some of these tutorials
Are there any good UIScrollView Tutorials on the net?
https://developer.apple.com/library/ios/documentation/windowsviews/conceptual/UIScrollView_pg/CreatingBasicScrollViews/CreatingBasicScrollViews.html
Example Code for Scrollview:
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0,self.view.frame.size.width, self.view.frame.size.height)];
//This will create a scrollview of device screen frame
You can enable the scrolling by
scroll.scrollEnabled = YES;
Example for adding 3 views to scrollview
NSInteger numberOfViews = 3;
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];
[awesomeView release];
}
// 3 views added horizontally to the scrollview by using xOrigin.
The most important part in this for is to understand the xOrigin. This will place every UIView exactly where the previous UIView has stopped, in other words, each UIView will start at the end of the previous one.
Now we got the scrollview with 3 views added horrizontally.
Set the UIScrollView contentSize
scroll.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);
The contentSize is just the sum of the widths of the three UIViews, if the width of each UIView is 320, and we have three UIViews, your contentSize width will be 920.
[self.view addSubview:scroll];
[scroll release];
//Add scrollview to viewcontroller
Page Control:
A Page control presents the user with a set of horizontal dots representing pages. The current page is presented as a white dot. The user can go from the current page to the next or to the previous page.
To enable paging you need to add
scroll.pagingEnabled = YES;
pageControl = [[UIPageControl alloc] init]; //SET a property of UIPageControl
pageControl.frame = CGRectMake(100,self.view.frame.size.height-100,self.view.frame.size.width-200,100);
pageControl.numberOfPages = 3; //as we added 3 diff views
pageControl.currentPage = 0;
Add delegate method of scrollview to implement the pagecontrol dots while scrolling
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x – pageWidth / 2 ) / pageWidth) + 1; //this provide you the page number
pageControl.currentPage = page;// this displays the white dot as current page
}
Now you can see pagecontrol for scrollview. Hope you understand. Refer this too
https://developer.apple.com/library/ios/documentation/uikit/reference/UIPageControl_Class/Reference/Reference.html
This is a very good tutorial by the Ray Wenderlich team on how to set up a paging scrollview: How To Use UIScrollView to Scroll and Zoom Content
Apple's documentation also has an example of how to implement a paging scroll view: PhotoScroller
My answer to this previous question may also be useful to you.

IOS Add subview on viewDidLoad

i have a problem when i'm trying to add subviews to a UIScrollView on viewDidLoad.
I'm using this code to programmatically add the UIImageViews to the scrollView:
- (void)viewDidLoad {
[super viewDidLoad];
NSInteger const_width = 100;
NSInteger numberOfViews = 4;
CGRect theFrame = [self.scrollView frame];
for (int i = 0; i < numberOfViews; i++) {
CGFloat xOrigin = i * const_width;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(xOrigin,theFrame.origin.y,const_width,110)];
UIImage *image = [UIImage imageNamed:#"cocoloco.jpg"];
[imageView setImage:image];
//[self.scrollView addSubview:imageView];
imageView.tag = i;
CGRect rect = imageView.frame;
rect.size.height = 110;
rect.size.width = 110;
imageView.frame = rect;
[self.scrollView addSubview:imageView];
}
self.scrollView.contentSize = CGSizeMake(const_width * numberOfViews, 110);}
But i get the current view:
It seems that the scroll view frame takes its position regardless the 3 yellow tabs (that are a special TabBarController) so i get a wrong frame origin from the UIScrollView and therefore the UIImageViews are wrong positioned.
Any idea?
I don't know exactly how to do it, but add the height of the frame to the "Y" position of your rectangle. Something like this:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(xOrigin,theFrame.origin.y + (theFrame.height),const_width,110)];
To get the scrollview below the navigation bar at the top, try
self.scrollview.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
Then position the table below the scrollview by setting it's origin base on the scrollview origin and height:
CGRect frame = tableView.frame;
frame.origin.y = self.scrollview.frame.origin.y + self.scrollview.frame.size.height;
tableView.frame = frame;
You should move any resizing or layout of your UI to the -(void)layoutSubviews method and this should sort your problem correctly.

Resources