Restricting UIScrollView scrolling to only one page at a time - objective-c

I would like to limit a UIScrollView to only being able to scroll one page at a time.
In other words, even when the user flicks really fast, I want the UIScrollView to be restricted to scrolling only one page.
Is there a good way to do this?

UIScrollView *myScrollView;
...
myScrollView.pagingEnabled = YES;
When set to YES, the scroll view stops on multiples of the scroll view’s.

One way to achieve this, if you haven't already settled on the scroll view, is to use a UIPageViewController. I'm looking at one on my app and this functionality seems to come for free.
With the UIScrollView, I'm thinking you might want to respond to the UIScrollViewDelegate method - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
I was thinking you could hold your current 'page' in a property, and then in the scrollViewWillEndDragging:withVelocity:targetContentOffset: method you could modify the target content offset to only be the next/previous page.
There's a 2012 WWDC video, Enhancing User Experience with Scroll Views, that uses this approach if you wanted to see it in action.

Related

Custom UIScrollView Gesture

I have a collection view cell which contains an UIScrollview in which all of the content sits. I want to have a gesture that allows users to swipe down when the cell is at 0,0 and then that fades away into the list view of the collection view.
However, I still want the users to be able to scroll down into the rest of the cell content.
Should this be contained in the same gesture? If so, how do I override a scrollview's gesture?
Thanks.
Yea just try implement this method from UIScrollViewDelegate:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
Get scrollView and calculate gestures and make behaviour. And look other methods for make best visual effect :)

Pull to reveal hidden navBar-like menu in iOS? as seen in GetPocket App

I've been driving myself mad over this one. It might be one of those things where I need to take a step back and figure out the simplest way to implement this. Can't find anything on this either. I google-fu'd the heck out of this one.
In the Pocket App when you pull down a menu reveals itself just like the searchBar does. In this instance the faux bar when you pull it past its halfway point if you release it shows springs into place. If it is release before the halfway point the bar will snap back and hide. As shown here
In my case I've been trying to replicate this with no luck. In my case I have a UITextView inside of a UIViewController view. I think I have it all wrong.
I can get it to work with a UIScrollView hidden by initiating with it offscreen and then when I press a button the UIScrollView reveals itself. The problem is that this method covers everything so I'll have to resize and relayout a bunch of views. Is this in a UITableView possibly? I want it to be a pull action though and just want to put some TextStrings/Labels in this bar.
Thank you in advance.
Feels like you need a UIScrollView (or UITableView) and to put the menu you want to reveal at the top (in the table view header, for example) and then get the delegate callbacks for scrolling.
UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
You might also need to watch for some of the dragging delegate callbacks
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
You can initially hide the menu by setting the content offset to the height of the menu, then catch the delegate callbacks for scrolling and, if the scrolling has reached beyond half the size of the menu set the content offset with animation.
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
If I understand your goal correctly you don't need the scroll view.
What I would do is have an simple UIView containing all the stuff you need and place it outside of the visible area. This will be your pull-down view. Then add an UIPanGestureRecognizer to the view in your UIViewController and use it to track the movement of your finger and update the frame of the pull-down view accordingly. Then in this update method you simply check if the position has passed some threshold and if so you let the pull-down view snap to its final position (using animations of course).
If you are unfamiliar with the UIPanGestureRecognizer there is a really good tutorial here:
http://www.raywenderlich.com/6567/uigesturerecognizer-tutorial-in-ios-5-pinches-pans-and-more

UITableView in a UIScrollView - How to make the view scroll, but not the TableView in itself?

Imagine, there is a UIViewController with a UIScrollView in it. At the top of the view there is an UIImageView, some UILabels and other things. Furthermore, there is a UITableView which content is Dynamic Prototypes. I attach a picture to make it clear:
I haven't got a static amount of cells in the UITableView so it could be scrollable. My problem is the following: the UITableView scrolls in itself but I want to scroll the whole View. What is the best possibility to do that?
Possible solutions I've founded today
1) The first thing is: I create a UITableViewController and declare a header section in which I include all my labels, images etc. programmatically (I would love to use the interface builder for that...)
2) Another solution is to calculate the height of the view. I tried the best to do it like this way - but: without success. If this is the best way to do that: Can anybody give an example?
I would ditch the UIScrollView and just use a UITableView. You can add a UIView object as the tableHeaderView of the UITableView just by dragging it in in Interface Builder. Now since everything is part of the UITableView hierarchy, everything will scroll together as expected.
You could also try setting delaysContentTouches to NO on your scrollView. Depending on your setup, this may make the scroll view respond to the touch first instead of the table view.
From Apples UIScrollView Docs:
delaysContentTouches
A Boolean value that determines whether the scroll view delays the
handling of touch-down gestures.
#property(nonatomic) BOOL delaysContentTouches
Discussion
If the value of this property is YES, the scroll view delays handling
the touch-down gesture until it can determine if scrolling is the
intent. If the value is NO , the scroll view immediately calls
touchesShouldBegin:withEvent:inContentView:. The default
value is YES.
You'll have to (as you've mentioned) add the UIView containing the image and buttons to the actual UITableView. Embedding it in the scroll view will produce the undesired behavior that you're seeing.
I would recommend returning the UIView as the header view for the first section of your table view. You can do this by implementing the UITableViewDelegate method:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
If you maintain an IBOutlet to the view containing your image/labels, you can return it here.
this is same demo i hope its helps you from iphone sorce code library
http://developer.apple.com/library/ios/#samplecode/iPhoneCoreDataRecipes/Introduction/Intro.html
thank you

How to synchronize scrolling of a NSScrollView and a WebView?

My app has two main views: a NSTextView subclass within a NSScrollView and a WebView. What the WebView displays is dependent on what the user enters into the text view - so I would like when the user scrolls either the text view or the web view the other scrolls proportionately to it.
I found this article which mentions how to do it with 2 scroll views. My problem is that WebKit doesn't seem to use normal Scroll views anywhere.
How should I implement this? What am I missing?
This is not a trivial problem to solve perfectly, as it's difficult to know whether the amount of text being edited in your text view corresponds to a similar amount of scrolling in the web view.
However, to answer your question about scroll views in WebView, they are used but as far as I know not documented extensively. You have to take advantage of the fact that you can obtain the scrollview being used, using public API, by asking the appropriate WebView subview for its "enclosingScrollView". Something like this works for me in a WebView where I know that there is only one frame:
[[[[myWebView mainFrame] frameView] documentView] enclosingScrollView];
If they are scrolling proportionately, probably the simplest solution would be to override touches events on your UIScrollview and impliment stringByEvaluatingJavaScriptFromString: on the UIWebView with (js) window.scroll(x,y). However, scrolling from the webView to the textview will require more work. The webView eats touches events, so you would need to
create a top level UIView or UIScroll view which captures the touches and sends them on to both the scrollView and the webView (via javascript) for ALL touches events, or
use a gesture recognizer to do the same.

How do I dynamically add images to a UIScrollView?

I'm working on an an app that updates both a UITableView and a UIScrollView. I like how UITableView updating works. As I add, remove, or update items, I call insertRowsAtIndexPaths:withRowAnimation:, reloadRowsAtIndexPaths:withRowAnimation:, and deleteRowsAtIndexPaths:withRowAnimation: as appropriate. However, updating the UIScrollView has turned out to be more of a challenge.
So how can I do it? My UIScrollView contains images, and I want to be able to insert, update, and remove individual images -- with animation -- efficiently and smoothly, and perhaps in random order. How does one do this sort of thing?
As an example, I have code like this in my UIScrollViewDelegate implementation for adding a new image:
if (newImageindex == currentImageIndex) {
[scrollView setNeedsDisplay];
[scrollView setContentOffset:portalView.contentOffset animated:YES];
} else if (newImageIndex < currentImageIndex) {
currentImageIndex++;
CGPoint offset = portalView.contentOffset;
offset.x += portalView.frame.size.width;
portalView.contentOffset = offset;
}
This is close, I think, but not quite right. I end up with the images added, but the UIScrollView seems to scroll to a position before the first image in the view. If I start scrolling it by hand, the first image appears. It's like it's scrolled to position -1 in my images.
The example may not help to highlight my problem much, but surely it's a common need to dynamically rejigger the images appearing in a UIScrollView. What's the state of the art on this?
A UIScrollView is not so specialized and structured as a UITableView. The former is a generic view that scrolls and zooms anything you put in it, and you can put any subviews into it anywhere, whereas the latter is made especially to display lists of cells stacked on top of each other.
So the answer is: you need to animate the subviews in the scrollview yourself. There are various libraries like Three20 which provide frameworks for creating more advanced views, you'll need to use a suitable component from one of those or roll your own.