Amount of scrolling in scrollViewWillBeginDragging - iphone

Is there any way to find how much UITableView has been scrolled in any direction ? I am interested in amount not in direction.

You can easily grab the exact offset of the table view by looking at its contentOffset property. For the vertical scroll, look at:
tableView.contentOffset.y;
and with this you can take your tableview to any particular location
[theTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:savedScrollPosition inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
CGPoint point = theTableView.contentOffset;
point .y -= theTableView.rowHeight;
theTableView.contentOffset = point;
for you requirement of load more cells after 10 you can use this logic
- (void)scrollViewDidScroll:(UIScrollView *)aScrollView {
CGPoint offset = aScrollView.contentOffset;
CGRect bounds = aScrollView.bounds;
CGSize size = aScrollView.contentSize;
UIEdgeInsets inset = aScrollView.contentInset;
float y = offset.y + bounds.size.height - inset.bottom;
float h = size.height;
// NSLog(#"offset: %f", offset.y);
// NSLog(#"content.height: %f", size.height);
// NSLog(#"bounds.height: %f", bounds.size.height);
// NSLog(#"inset.top: %f", inset.top);
// NSLog(#"inset.bottom: %f", inset.bottom);
// NSLog(#"pos: %f of %f", y, h);
float reload_distance = 10;
if(y > h + reload_distance) {
NSLog(#"load more rows");
}
}

You need to measure the contentOffset of the UITableView when dragging begins and when it ends. Take a difference between the two, it will give you the amount of change from initial to final position.
CGPoint oldOffset;
CGPoint newOffset;
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
oldOffset = scrollView.contentOffset;
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
newOffset = *targetContentOffset;
CGPoint diff = {newOffset.x - oldOffset.x, newOffset.y - oldOffset.y};
// Where diff.x => amount of change in x-coord of offset
// diff.y => amount of change in y coord of offset
}
Hope that helps!

you can find it using below syntax...
NSLog(#"scrolled:%f",yourtableview.contentOffset.y);//y for vertical, x for horizontal

Related

adding the new view according to the finger touch location in iPhone using UITapGestureRecognizer

To all
I am using the
UITapGestureRecognizer*singleTap = [[[UITapGestureRecognizer alloc] initWithTarget: self action:#selector(doSingleTap:)] autorelease];
singleTap.numberOfTouchesRequired = 2;
[self.view addGestureRecognizer:singleTap
for getting the touch
And in doSingleTap: method i have this
-(void)doSingleTap:(UITapGestureRecognizer *)recognizer
{
CGPoint point = [recognizer locationOfTouch:0 inView:self.view];
NSLog(#"location X =>%f,location =>%f ",point.x,point.y);
CGPoint point1 = [recognizer locationOfTouch:1 inView:self.view];
NSLog(#"location X =>%f,location =>%f ",point1.x,point1.y);
NSLog(#"location X =>%f,location =>%f ",x,y);
UIView *test1 = [[UIView alloc]initWithFrame:CGRectMake(point.x, point1.y, x, y)];
test1.backgroundColor= [UIColor greenColor];
[self.view addSubview:test1];
}
getting the problem in adding the new view on the main view according to the finger location or position View is properly getting add on the view according to the position .
I want that view get add according to the two finger and automatically adjust their (x,y,w,h).
I need help if any one help me
Thanks in advance I google on this but didn't get any help
Compare with point.x and point1.x take lesser 1 as x and do same for y (compare with point.y and point1.y smaller 1 as y). take the difference between point.x and point1.x as width and do same for height (difference between point.y and point1.y) will sove the issue
float x = (point.x < point1.x) ? point.x : point1.x;
float y = (point.y < point1.y) ? point.y : point1.y;
float width = fabsf(point.x - point1.x);
float height = fabsf(point.y - point1.y);
UIView *test1 = [[UIView alloc]initWithFrame:CGRectMake(x, y,width,height)];
Try to calculate rect of view with the next:
float x = MIN(point.x, point1.x);
float y = MIN(point.y, point1.y);
float width = fabsf(point.x - point1.x);
float height = fabsf(point.y - point1.y);
CGRect frame = CGRectMake(x, y, width, height);

How can I zoom a UIScrollview to a fixed point?

I am creating a control for showing the timeline. Initially , it should show the year. When zooming in and the zoomScale reached a specific value, it will show the value of the individual months, and In the next zoom level, it should show the real values for the individual days.
I have creatd a scrollview and added the layers (for showing the month/year values) to this. After overriding the pinch guesture, I am able to do the zooming (Normal UIScrollview zooming). But I need to zoom it to a particular point. ie, Suppose i am zooming January, I need to keep it in the same position(for creating an effect like moving inside of January). Any suggestions to achieve this?
Is my way is currect? else please help me to start this.
Use This bellow method for your requirement,
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated
just call this above method with your selected frame or point , like if select January then just take the point ( position) of january button or view and just call above method with that frame..
for more information see this link UIScrollView_Class
i hope this helpful to you...
Here’s what it looks like:
#implementation UIScrollView (ZoomToPoint)
- (void)zoomToPoint:(CGPoint)zoomPoint withScale: (CGFloat)scale animated: (BOOL)animated
{
//Normalize current content size back to content scale of 1.0f
CGSize contentSize;
contentSize.width = (self.contentSize.width / self.zoomScale);
contentSize.height = (self.contentSize.height / self.zoomScale);
//translate the zoom point to relative to the content rect
zoomPoint.x = (zoomPoint.x / self.bounds.size.width) * contentSize.width;
zoomPoint.y = (zoomPoint.y / self.bounds.size.height) * contentSize.height;
//derive the size of the region to zoom to
CGSize zoomSize;
zoomSize.width = self.bounds.size.width / scale;
zoomSize.height = self.bounds.size.height / scale;
//offset the zoom rect so the actual zoom point is in the middle of the rectangle
CGRect zoomRect;
zoomRect.origin.x = zoomPoint.x - zoomSize.width / 2.0f;
zoomRect.origin.y = zoomPoint.y - zoomSize.height / 2.0f;
zoomRect.size.width = zoomSize.width;
zoomRect.size.height = zoomSize.height;
//apply the resize
[self zoomToRect: zoomRect animated: animated];
}
#end
Looking at it, it should be pretty straightforward to figure out how it works. If you see anything wrong with it, let me know in the comments.
Thanks :)
source: http://www.tim-oliver.com/2012/01/14/zooming-to-a-point-in-uiscrollview/
I had same problem,
I was having a world map image, & i wanted to zoom the map to certain location, India
This is how i fixed it.
I found out the position of India, in terms of CGRect(X,Y) [CGRect(500,300)]
& following code in DidLoad
[self.scrollViewForMap setZoomScale:2.0 animated:YES]; //for zooming
_scrollViewForMap.contentOffset = CGPointMake(500,300); //for location
This solved my problem. :)
- (void)pinchDetected:(UIPinchGestureRecognizer *)gestureRecognizer {
if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [gestureRecognizer scale];
}
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:#"transform.scale"] floatValue];
// Constants to adjust the max/min values of zoom
const CGFloat kMaxScale = 2.2;
const CGFloat kMinScale = 0.64;
CGFloat newScale = 1 - (lastScale - [gestureRecognizer scale]);
newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
[gestureRecognizer view].transform = transform;
[gestureRecognizer setScale:1.0];
lastScale = [gestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
}
}
What worked for me (Swift 4):
func zoomIn(with gestureRecognizer: UIGestureRecognizer?) {
guard let location = gestureRecognizer?.location(in: gestureRecognizer?.view)
let rect = CGRect(x: location.x, y: location.y, width: 0, height: 0)
scrollView.zoom(to: rect, animated: true)
}
Or in other words creating a CGRect with zero width and height will cause the UIScrollView to zoom to the rects origin at maximumZoomScale

How can i get CGRect values x,y,width,height after view is being autoresized?

I want x,y,widht,height values of view when it is autoresized automatically when orientation of ipad changes. How can i get that?
After the view has rotated you should be able to get the new dimensions of the view.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
CGRect myFrame = [self.view frame];
NSLog(#"height = %f", myFrame.size.height);
NSLog(#"width = %f", myFrame.size.width);
NSLog(#"x = %f", myFrame.origin.x);
NSLog(#"y = %f", myFrame.origin.y);
}
try this
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
float x = yourView.bounds.origin.x;
float y = yourView.bounds.origin.y;
float width = yourView.bounds.size.width;
float height = yourView.bounds.size.height;
NSLog(#"x=%f,y=%f,w=%f,h=%f",x,y,width,height);
}
after the rotation try.
NSLog(#"x = %.2f y = %.2f width = %.2f height = %.2f", view.frame.origin.x , view.frame.origin.y, view.frame.size.width, view.frame.size.height);
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
/*Subclasses may override this method to perform additional actions immediately after
the rotation. For example, you might use this method to reenable view interactions,
start media playback again, or turn on expensive drawing or live updates. By the time
this method is called, the interfaceOrientation property is already set to the new
orientation.*/
CGRect frame = self.view.frame
}

UIPinchGestureRecognizer Scale view in different x and y directions

i don't want to use the scale as classic zoom, instead i want to change the form of quadrates to a rectangle for example.
After a lot of trying i'm that far that my fingers are the corners of the rectangle.
So but if i start a new pinch gesture inside my view gets smaller to my fingers instead of getting bigger like the normal scale does.
if ([gestureRecognizer numberOfTouches] >1) {
//getting width and height between gestureCenter and one of my finger
float x = [gestureRecognizer locationInView:self].x - [gestureRecognizer locationOfTouch:0 inView:self].x;
if (x<0) {
x *= -1;
}
float y = [gestureRecognizer locationInView:self].y - [gestureRecognizer locationOfTouch:0 inView:self].y;
if (y<0) {
y *= -1;
}
//double size cause x and y is just the way from the middle to my finger
float width = x*2;
if (width < 1) {
width = 1;
}
float height = y*2;
if (height < 1) {
height = 1;
}
self.bounds = CGRectMake(self.bounds.origin.x , self.bounds.origin.y , width, height);
[gestureRecognizer setScale:1];
[[self layer] setBorderWidth:2.f];
}
does anyone know a way to make a X-Y-Scale which don't resize to my fingers position as corners.
Thank you very much
Got the solution
- (void) scaleSelfWith:(UIPinchGestureRecognizer *)gestureRecognizer{
if ([gestureRecognizer numberOfTouches] >1) {
//getting width and height between gestureCenter and one of my finger
float x = [gestureRecognizer locationInView:self].x - [gestureRecognizer locationOfTouch:1 inView:self].x;
if (x<0) {
x *= -1;
}
float y = [gestureRecognizer locationInView:self].y - [gestureRecognizer locationOfTouch:1 inView:self].y;
if (y<0) {
y *= -1;
}
//set Border
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
xDis = self.bounds.size.width - x*2;
yDis = self.bounds.size.height - y*2;
}
//double size cause x and y is just the way from the middle to my finger
float width = x*2+xDis;
if (width < 1) {
width = 1;
}
float height = y*2+yDis;
if (height < 1) {
height = 1;
}
self.bounds = CGRectMake(self.bounds.origin.x , self.bounds.origin.y , width, height);
[gestureRecognizer setScale:1];
[[self layer] setBorderWidth:2.f];
}
}
added xDif and yDif with the distance of my touch from the side of the view.
after scale i add them to the size

How can I use scrollRectToVisible to scroll to the center of an image?

I have a UIScrollView with zooming and panning. I want the image to scroll to the center after a user command. My problem is in calculating the size and location of a frame that is in the center of the image.
Does anyone know how to calculate the correct frame for the center of my image? The problem is that if the zoomScale is different the frame changes.
Thanks!
Here's maybe a bit better code in case anyone is in need ;-)
UIScrollView+CenteredScroll.h:
#interface UIScrollView (CenteredScroll)
-(void)scrollRectToVisibleCenteredOn:(CGRect)visibleRect
animated:(BOOL)animated;
#end
UIScrollView+CenteredScroll.m:
#implementation UIScrollView (CenteredScroll)
-(void)scrollRectToVisibleCenteredOn:(CGRect)visibleRect
animated:(BOOL)animated
{
CGRect centeredRect = CGRectMake(visibleRect.origin.x + visibleRect.size.width/2.0 - self.frame.size.width/2.0,
visibleRect.origin.y + visibleRect.size.height/2.0 - self.frame.size.height/2.0,
self.frame.size.width,
self.frame.size.height);
[self scrollRectToVisible:centeredRect
animated:animated];
}
#end
Based on Daniel Bauke answer, I updated his code to include zoom scale :
#implementation UIScrollView (jsCenteredScroll)
-(void)jsScrollRectToVisibleCenteredOn:(CGRect)visibleRect
animated:(BOOL)animated
{
CGPoint center = visibleRect.origin;
center.x += visibleRect.size.width/2;
center.y += visibleRect.size.height/2;
center.x *= self.zoomScale;
center.y *= self.zoomScale;
CGRect centeredRect = CGRectMake(center.x - self.frame.size.width/2.0,
center.y - self.frame.size.height/2.0,
self.frame.size.width,
self.frame.size.height);
[self scrollRectToVisible:centeredRect
animated:animated];
}
#end
private func centerScrollContent() {
let x = (imageView.image!.size.width * scrollView.zoomScale / 2) - ((scrollView.bounds.width) / 2)
let y = (imageView.image!.size.height * scrollView.zoomScale / 2) - ((scrollView.bounds.height) / 2)
scrollView.contentOffset = CGPointMake(x, y)
}
Okay, got it working. Here's the code incase anyone is in need:
CGFloat tempy = imageView.frame.size.height;
CGFloat tempx = imageView.frame.size.width;
CGRect zoomRect = CGRectMake((tempx/2)-160, (tempy/2)-240, myScrollView.frame.size.width, myScrollView.frame.size.height);
[myScrollView scrollRectToVisible:zoomRect animated:YES];