I have got a hierarchy where UIScrollviews exist within each other.
How may I redirect swipe events for a certain area to an inner scrollview?
If you set your UIScrollViews to only be scrollable in one axis or the other (ie, set their contentSize property appropriately for this. To have a view only be scrollable vertically, set its contentSize.width value to be the same as its bounds.size.width). then they should just work, assuming that no two views scroll in the same axis. Usually, you'll have the 'child' views scroll vertically, and the parent view scroll horizontally.
If it's at all possible, you should redesign to avoid this. Safari handles this kind of situation, i.e. iframes and textareas, by having the embedded view scroll with two fingers. This isn't very discoverable, but it's better than the alternative, which would be even more frustrating. If an embedded view were just barely onscreen, an attempt to scroll the outer view could instead scroll the inner view, but not display much of anything; it would just appear to be non-responsive.
That said, If you still want to do this, try setting the outer scroll view's canCancelContentTouches to NO. This should prevent the outer view from scrolling when a touch begins in the inner view. Getting Safari-style two finger scrolling would probably involve subclassing UIScrollView and implementing the -touchesShouldBegin:withEvent:inContentView: method.
Related
I have a UIScrollView which contains a timelime. Sometimes I may only want to let the user see say one third of the view and therefore I would like it to only show this part of the scrollview but still have this nice "bouncing" effect in both ends of the view to "preview" what is outside the scrollable area.
Is there any way to do this?
I think you should specify the size of the UIScrollView to end where you want your user to scroll to but leave the size of the inner view (subview) of the UIScrollView.
I have a UIScrollView instance with many views inside. I have touchesBegan: defined inside my implementation of a subclass of UIView, but touches are only detected for views that are originally shown inside the scrollview (without scrolling). That is, initially all touches are detected, but when I scroll down, no touches are detected, except for on those views which were originally above the fold (i.e. they originally fit in the scrollview), and moreover, only those parts of those views which were above the fold (in the cases of views that were partially shown originally).
I hope this is clear... anyone have any idea what could be causing a situation like this?
After a day of debugging, I found the simple solution. The height of the frame of the view inside the scrollview had been set to the height of the screen. I needed to extend it to the full height of the scrollview.
I'm developing my first iPhone app and I would greatly appreciate you guy's input on a problem I'm having.
I'm looking to implement scrolling both horizontally and vertically. I want the horizontal scrolling to be paged, without the vertical one being paged (scrolling "normally"). A single UIScrollView with pagingEnabled set to YES will page in both directions. The natural solution would be to nest a UIScrollView inside another one, however when I do that, I can't get the "inner" UIScrollView to scroll at all. Seems the outer one is "eating" up all the tap events, like in:
UIScrollView : paging horizontally, scrolling vertically?
I read something about "inner scrolling" being improved upon in SDK 3.0 and actually when I add an inner UITableView instead of a UIScrollView the scrolling works flawlessly. Since UITableView subclasses UIScrollView I imagine that my desired behavior should be achievable by making my own subclass of UIScrollView.
Is this the right approach? If so, what should this subclass look like?
This works out of the box with the SDK now. See Scrolling Madness and Apple's UIPageControl sample for guidelines on how to implement paged horizontal scrolling with a view controller for each page.
The nested UIScrollViews you add as subviews to your outer UIScrollView should have the same frame heights as the container. If you do this then the outer UIScrollView will pass through the vertical scrolling events to the subview. My app has three levels of UIScrollView and UIWebView nesting and I've found Cocoa is really intelligent about passing the events to the one I want as long as I set my frame sizes so that only one view is really scrollable (contentSize > frame) on each axis.
If you are trying something like Twitter profile UI I achieved this by putting header view and bottom scrollview in a a parent scrollview and underlaying another scrollview behind.
Underlaying scrollview is responsible for the adjusting content offsets of header and bottom. Its contentsize is also adjusted by the inner item heights.
It looks complicated when I tell, better see the code
https://github.com/OfTheWolf/Twitterprofile
I've been using this great lib by Andrey Tarantsov for months: SoloComponents
You can use it as an "horizontal UITableView" with support for pagination and view recycling.
Well made and perfectly cocoa-style designed.
Based on Dylan's answer, in my case, I actually also had to make content size heights equal for both parent and nested UIScrollViews to make nested UIScrollView to scroll vertically. Making only "the same frame heights as the container" as Dylan explained was not enough:
parentScrollView.contentSize = CGSizeMake(parentScrollView.contentSize.width, desiredContentHeight);
nestedScrollView.contentSize = CGSizeMake(nestedScrollView.frame.size.width, desiredContentHeight);
What Dylan says. And, perhaps of interest on this topic - you do not need to enable scrolling in the master "paging" UIScrollView, just enable paging and direction lock. This seems to assure that all vertical scrolling cues go to the nested, fixed-size, vertical-scrolling NSScrollViews. It works back to at least iOS 9.
This is more of a check as I believe this is right but its a lot of work if I'm wrong.
I want to basically achieve fixed positioning with a scrollView. I want to have a list along the top that is always visible, scrolls horizontal only and then a scrollview beneath that to move around the information which scrolls both vertically and horizontally.
I figure I need to subclass UIScrollView and overwrite touchesBegan, touchesMoved and touchesEnded to send the touch to both UIScrollViews.
Is this right or off track?
Cheers
Overriding the touch events on a scroll view is probably not what you want to do. Instead you can simply use a single scroll view, and then in the parent view's -layoutSubviews or in the scroll view's delegate methods you can move the list so it's always at the same vertical position (use the scroll view's contentOffset property to determine where that should be). Both the delegate method and -layoutSubviews is called before the drawing actually occurs after the scroll view scrolls, so by always repositioning your view where you want it to be, it will appear to remain fixed to the user.
They "brush" the subject in this thread, but it does not really answer much:Stackoverflow UIScrollView question
I have a UIScrollView and a UIPageControl working together to present a set of views.
(Standard "Home screen" swipe style, in lack of better words)
Each of these views, inside the scrollView, has a thin menu in the bottom part, that can also be swiped from side to side. If anyone remember the previous FaceBook app, this also had a menu that could be swiped horizontally, however, not incased in another scrollView, but the idea is similar.
So the outer scrollView will scroll the entire view, including the view containing the inner scrollView, but the inner scrollView will only change a menu inside the view.
I already did a proof of concept test of this, what happens, is that delegate methods gets called in both the scrollViews no matter where on the screen the swipe takes place, and the innermost scrollView will crash the app when swiped left to right, but not right to left…
I sort of get the feeling that this can be done, but that Im going about it the wrong way.
Is there a way to set which area of the screen reacts to swipes? i.e. decide that the upper ¾ of the screen will call one set of delegate methods and the bottom ¼ will call another set.
Maybe through some sort of mediator that catches the swipes before they are "processed" and then determines which scrollView should react?
Hope someone can point me in a good direction on this one, thanks:)
What about de-nesting the scroll views? Instead of embedding a scrollview inside another scrollview, make them same-level siblings of a parent UIView.
In support of your nesting though, I can think of the App Store app which lets you scroll screen shots horizontally while the app description scrolls vertically.