Drag UIView containg UIScrollView - ios

I have been having trouble trying to drag a UIView that has a UIScrollView within it. The UIView drags up from the bottom of the screen, when it has hit the top you can use the UIScrollView inside it. When the user scrolls to the top of the UIScrollView, the UIView should drag down with their finger.
It should work like the Google Maps popup when you click a pin.
Update: I can get the dragging up of the UIView working (touchesMoved) that changes the Y value. The main functionality I am having problems with is the dragging down of the UIView when the user touches inside the UIScrollView. I want the user to still be able to drag the scrollview as normal until it reaches the top at which point the dragging action should then move the parent UIView down off the screen.
Update 2: This is the code you suggested to turn off the user interaction:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if(scrollView.contentOffset.y<=0){
scrollView.userInteractionEnabled = NO;
}else{
scrollView.userInteractionEnabled = YES;
}
}

Most apps handle this scenario by using the UIScrollViewDelegate method scrollViewDidScroll.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// check the scrollView.contentOffset.y to see if you
// have reached the top of the scroll view.
}
You can then check the contentOffset and continue with your dragging code the way you want.

Related

Pull up keyboard while scrolling UITableView and scroll along with the tableView

To add panning behaviour to the keyboard, I am using DAKeyboardControl. It works just fine (after modifications) for panning behaviour to close the keyboard.
How do I make the keyboard appear if the user tries to scroll downwards (finger pan in up direction) at the end of the UITableView. To be more specific, I am looking for behaviour similar to the Facebook Messages app, where, if you scroll up the keyboard appears, with panning, and scrolls with the table.
EDIT: It seems I am not clear about what I want. I wish to move the keyboard along with the scrollview (UITableView). In the following image, I am panning the keyboard along with the table. The table is already scrolled to it's bottom, and if I try to scroll down any further the keyboard begins to appear. My finger, meanwhile, is in the middle of the table.
This effect can be achieved by setting the scrollview's keyboardDismissMode to UIScrollViewKeyboardDismissModeInteractive and then in scrollViewDidScroll: calling [textField becomeFirstResponder];. Because you are in the middle of scroll, the keyboard will respect the keyboardDismissMode property and interactively appear. Drop the DAKeyboardControl; it's outdated.
You need an element such as UITextView and then, detect the scroll (for example, using any of the UIScrollView delegate methods). Once scrolled, call becomeFirstResponder on the text view.
add this in .h fileā€¦
#property (nonatomic, assign) CGFloat lastContentOffset
And add this in your .m file...
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
if (self.lastContentOffset > scrollView.contentOffset.y)
{
[textField becomeFirstResponder];
}
else if (self.lastContentOffset < scrollView.contentOffset.y)
{
[textField resignFirstResponder];
}
self.lastContentOffset = scrollView.contentOffset.y;
}
Hope this will do the trick, haven't tested it...

Determine if button can be seen by user

I have an interesting requirement. I have a webview that expands in size when the user swipes up. This works well, but now I am trying to detect if the user has scrolled up to the top, so that I can minimize it again.
I am trying to do this by placing an image behind the webview, if the user scrolls past the top of the webview, the bounce effect takes place and the underlying image becomes visible. I was trying to use the "hidden" property thinking that the image is hidden when under the webview, but visible when the webview has been pulled down. This however, doesnt seem to work properly.
Anyone have any ideas on how to detect if a button/image is visible to the user?
Because the UIWebView implements UIScrollViewDelegate, it declares conformity to that protocol, you can use the ScrollViewDidScroll delegate method.
First make sure that your UIWebView is not inside a UIScrollView
Important: You should not embed UIWebView or UITableView objects in
UIScrollView objects. If you do so, unexpected behavior can result
because touch events for the two objects can be mixed up and wrongly
handled.
Instead, you can access the UIScrollView through the UIWebView properties since we now know that UIWebView is based on a UIScrollView. Your view controller can implement the UIScrollViewDelegate.
#interface MyViewController : UIViewController<UIScrollViewDelegate>
#end
Then you have to set the scrollView property inside your webview to the UIScrollViewDelegate like so:
- (void)viewDidLoad
{
[super viewDidLoad];
// Set the scrollView property's delegate protocol to self. This is so that this view controller will receive the delegate methods being fired when we interact with the scrollView.
webView.scrollView.delegate = self;
}
We're only interested in one of the ScrollView's delegate method - scrollViewDidScroll. Then you can detect when the scrollView has been scrolled inside your webview and ultimately have a simple mathematics equation that checks if the scrollView has been scrolled to the top:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if(scrollView.contentOffset.y <= 0.0){
NSLog(#"TOP REACHED so do the chicken dance");
}
}
Look for contentOffset of scroll view of Web view if it's Y==0 then it means that user has scrolled up to the top.
CGRect visibleRect;
visibleRect.origin = webView.scrollView.contentOffset;
if(visibleRect.origin.y == 0)
{
//t means that user has scrolled up to the top
}

Hiding a toolbar element when UITableView scrolls (similar to Facebook's app?)

How I can achieve this effect?
This isn't immediately noticeable from your screenshots, but I believe you want the that header toolbar to slide up as the user scrolls, right? (I'd suggest clarifying on that part)
You can do this a few ways, and in all of them you will have to implement your own scrolling logic, meaning how much the header toolbar slides up depending on where you have scrolled. That said, here's how to do it:
1. If you're using UITableView, I assume you've got your view controller set as its delegate. Since UITableView is a subclass of UIScrollView already, just add the UIScrollViewDelegate to your view controller. That will give us scroll events as they happen. You'll want to do your logic in scrollViewDidScroll:.
2.. If you're simply using UIScrollView, just set your view controller as its delegate, implement UIScrollViewDelegate, and do your logic in scrollViewDidScroll:.
That said, your code might look something like this:
- (void) scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint scrollPos = scrollView.contentOffset;
if(scrollPos.y >= 40 /* or CGRectGetHeight(yourToolbar.frame) */){
// Fully hide your toolbar
} else {
// Slide it up incrementally, etc.
}
}
Anyway, hope I helped.
If you have properly set the delegate, your table will call scrollViewDidScroll: when scrolled.
So in your controller, you can add something like :
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.contentOffset.y >0) //means that the user began to scroll down the table
{
[UIView animateWithDuration:0.4 animations:^{
//animations you want to perform
}];
}
}
Here i implemented code for UIView Hide / Show when tableview scrolling. When tableview scrolling down then UIView is hidden and when scrolling up then UIView show. I hope it's working for you...!
Step 1:- Make one property in .h file
#property (nonatomic) CGFloat previousContentOffset;
Step 2:- Write down this code in scrollViewDidScroll Method.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat currentContentOffset = scrollView.contentOffset.y;
if (currentContentOffset > self.previousContentOffset) {
// scrolling towards the bottom
[self.subButtonView setHidden:YES];
} else if (currentContentOffset < self.previousContentOffset) {
// scrolling towards the top
[self.subButtonView setHidden:NO];
}
self.previousContentOffset = currentContentOffset;
}
I create simple class for this effect:
UIHidingView is an iOS class that displays UIView element on top UITableView which is hiding when Table View is scrolling.
This will answer your question :
iPhone: Hide UITableView search bar by default
same concept, different control. You can put a UIView on top row of tableview or any other relevant control such as button.
Good luck.

iOS Programmatic Zoom in UIScrollView Not Working

I'm new to iOS and I've been stuck for a while on this. My goal is to programmatically zoom to a specific spot when the user pinches anywhere in the view. This may seem strange, but it's an internal app not for the App Store. Right now, when I pinch to zoom, nothing happens.
On my View (it's a single view application), I have images that I'd like to zoom in on programmatically. Here's what I have done.
In the Interface Builder, I dragged a Scroll View object onto my View, and changed the size to fit the View
In the Scroll View, I set the minimum zoom = 0 and the maximum zoom = 1000 (just to make sure this wasn't the problem)
I dragged a Pinch Gesture Recognizer on top of the UIScrollView.
I right-clicked the UIGestureRecognizer, and created an action called handlePinch() where I placed my code to programmatically zoom when the pinch was recognized.
Implemented the zoom in handlePinch (shown below)
- (IBAction)handlePinch:(UIPinchGestureRecognizer *)sender {
CGRect zoomRect;
zoomRect.origin.x = 500;
zoomRect.origin.y = 500;
zoomRect.size.width = 512;
zoomRect.size.height = 384;
[scrollView zoomToRect:zoomRect animated:YES ];
}
Known:
- The pinch gesture is being recognized, and handlePinch is being called
Thank you for any answers or suggestions in advance!
You don't need a pinch gesture to do this, since the zooming is built in. Here's what to do.
In your view controller header file, add the scroll view delegate:
#interface MyViewController : UIViewController <UIScrollViewDelegate>
Next in the implementation file, preferably in your viewDidLoad, set the scroll view's delegate to self:
- (void)viewDidLoad {
//other stuff
self.scrollView.delegate = self;
}
Then, copy and paste this scroll view delegate method into your implementation file:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
if (scrollView == self.scrollView) {
return self.viewToBeZoomed;
}
}
self.viewToBeZoomed is the view you want to zoom. This view is a subview of self.scrollView.

Drag a UIView from one UIScrollView to another

I have two UIScrollViews on my screen and I need to be able to drag a UIView from one scrollview to the other.
At the moment, I have a UILongGestureRecognizer on the UIView that I want to move, such that when the user starts dragging it, I make the view follow the touch:
- (void)dragChild:(UILongPressGestureRecognizer *)longPress {
[[longPress view] setCenter:[longPress locationInView:[[longPress view] superview]]];
}
But when I get the boundary of the starting UIScrollView, the view disappears because it's locked into that scrollview's bounds.
Is there a way to "pop" it out of the scrollview when I start dragging such that I can carry it over to the other scrollview?
Also, how do I test for the "drop" location? I want to know if it's been dropped over a certain other view.
Or am I going about this all the wrong way?
Thanks guys
If you will need to drag it from a scroll view to another do the following (pseudo code)
when you start dragging do the following
//scrollView1 is the scroll view that currently contains the view
//Your view is the view you want to move
[scrollView1.superView addSubView:yourView];
now when dropping the view, you will need to know if it is inside the other scrollview
//scrollView2 is the second scroll view that you want to move it too
//Your view is the view you want to move
CGPoint point = yourView.center;
CGRect rect = scrollView2.frame;
if(CGRectContainsPoint(rect, point))
{
//Yes Point is inside add it to the new scroll view
[scrollView2 addSubView:yourView];
}
else
{
//Point is outside, return it to the original view
[scrollView1 addSubView:yourView];
}
Here is an untested idea:
When the drag begins, move the dragging-view out of the scroll view (as a subview) and into the mutual superview of both scroll views.
When the drag ends, move the dragging-view out of the superview and into the new scroll view.
You'll probably have to be careful with coordinate systems, using things like [UIView convertPoint:toView:] to convert between the views' different perspectives when moving things around.

Resources