I have a CCMenu with cocos2d-iphone. It lists many items vertically.
I want the user to be able to swipe his finger to scroll.
What I have done so far was check when the user makes a touch and moves it. That way I can calculate the relative movement required to move the menu properly. And it works.
However, if the touch begins over a CCMenuItemImage, my layer will not receive the ccTouchesBegan nor the ccTouchesMoved messages, so I can't perform such calculations.
What do I do?
Related
I am playing with the pinching/dragging/rotating gestures (working with the gestures, not raw touch events). It works nice, but I have noticed one problem. For pinching/rotating both fingers need to be inside the view. As long as the view is large enough its not a problem, but as soon as the view becomes very small (in regards to the parent thats a scrollview), it feels a little bit like struggle to get the view "back". I have been checking some other apps, and Whatsapp does that the best. When you add a emoticon to an image inside Whatsapp, you can do all the gestures without the need to have both fingers on the view. For example, I made the emoticon really small, put two fingers so that the emoticon lies between them, and the gesture recognizer applies my movement to the emoticon (but not the to the scrollview which is the superview). When I do it inside my App the gestures are being applied to the scrollview as long as I dont place both fingers on the view I want to transform
Is there some setting on the gestures so it does that or do I have to work with raw touch events and calculate my own stuff ?
Thanks
I'm as beginner as you can get when it comes to iOS animation.
I know you can do fixed (non-gesture-controlled) animations, where you animate a property of a view over a fixed period of time. This however is entirely different than using a gesture to control the animation.
You know how you fold a sheet of 8x11 paper to put it in an envelope and mail it... you fold it in thirds. Well basically, my boss wants an interface such that 2/3rds of it is shown on the screen at a time, and the other third is slid on/off screen with a gesture. So basically, the screen would show either thirds 1 and 2, or thirds 2 and 3 depending on whether you swipe left or right.
Now this also means doing things like snapping/rubberbanding, bouncing, acceleration/deceleration, sticky. I have no clue where to even start to do something like this. I'm assuming those types of motions are not already built into any of the iOS framework and if you want snapping/rubberbanding, bouncing, acceleration/deceleration, you'd have to program that entirely from scratch.
Like how would a view know my artificial snap/bounce points are, and sticky behavior, such that you remove your finger from the screen before an arbitrary position is reached, and the view bounces back to it's previous position.
Where would you suggest I start on researching how to drive animations with gestures?
I suggest you take a look at Core Animation. You can do some really complex animations including accelerations, deceleration, bounce and others.
You could easily create a UIPanGestureRecognizer to track when someone has dragged their finger across the screen. Attach an action wasDragged to your gestureRecognizer
From the documentation:
A panning gesture is continuous. It begins (UIGestureRecognizerStateBegan) when the minimum number of fingers allowed (minimumNumberOfTouches) has moved enough to be considered a pan. It changes (UIGestureRecognizerStateChanged) when a finger moves while at least the minimum number of fingers are pressed down. It ends (UIGestureRecognizerStateEnded) when all fingers are lifted.
In wasDragged check what state the gestureRecognizer is in. If state is UIGestureRecognizerStateChanged, then you can adjust the size or position of your UIView so that it appears like you are dragging it out. If state is UIGestureRecognizerStateEnded, check whether the point at which the gesture ended is greater than your threshold point (e.g. halfway across the screen). If it isn't, then snap the view back using an animation, if it is then snap the view into where you want it.
Hope this makes sense.
I'm using the great iOS control iCarousel's Wheel type and I want all of the buttons it contains to be usable / selectable at any time (i.e. I can tap any of them, no matter which one is currently at the top of the wheel). The user can still scroll the wheel as normal, but no matter which button they tap, it should register.
The current behavior seems inconsistent: if I tap one of the buttons directly next to the center one (to its left or right), that button moves into the center slot. Clicking one of the buttons two positions away 'sometimes' causes it to scroll to that letter, sometimes it's ignored. Any other buttons are always ignored.
Is this possible to set up, preferably without hugely modifying the class? I'm by no means an expert, but am learning every day :)
Thanks in advance.
Set carousel.centerItemWhenSelected = NO;
That will disable the behaviour where buttons other than the centre one are scrolled to the centre when you tap them.
As for the reason why some are not responding to taps at all, it is most likely because the frame of your carousel view is too small and the tap events are outside of the frame.
If you set carousel.clipsToBounds = YES; it will crop the carousel views to the frame as well so you'll be able to see exactly what size your carousel actually is.
I'm trying to create some sort of timeline view like in video editors: media elements in a row, which are UIView's. I can successfully drag these views inside currently visible part of scroll view using UIScrollView touch events like touchesBegan and touchesMoved. I want to scroll the scroll view once subview is dragged to one of the scroll view edges. The best I can think of now is to create a timer that will scroll the view while user holds the subview with the finger near scroll view edge.
There's a lot of questions here on the same topic, but I was unable to find one that covers scrolling.
Is there a good way to do this? Should I use gesture recognizers instead?
Thank you in advance.
Actually what you want IS a timed event. As soon, as the user is at the edge of the scrollview, you start a timer, which regularly increases the contentOffset. If you don't like your animation results (i guess you're using setContentOffset:animated:?), just try another timing and distance of animation.. I guess you have to try some different settings. What I would try first is 1px at a time. Perhaps every 0.3 second?
If that doesn't work you could also try another "extreme". Start a single animation, when the user reaches the edge, which animates the contentOffset until the end of the contentSize. But over a large timespan so the movement is slow. If the user stops dragging, or moves out of the edge, stop the animation at the current position. That would even be a solution without a timer, because the animation would be your timer itself.
I seriously doubt gesture recognizers would part of a good solution to this since they tend to be most helpful with discreet gestures.
I don't think I can improve on your general direction based on the assumption, implied above, that you are looking for continuous/gradual scrolling.
What I suggest instead is that you consider designing this to use a paged scrolling approach. When your user drags the object to the edge of the scrollview, cause the scrollview to move one page in that direction (by setting the contentOffset to move in that direction according to the bounds of the scrollview). When that even occurs, move the object slightly out of the "hot zone" at the edge of the scrollview so that the user is forced to explicitly express that they want to move another page, or something along those lines - that is, since the design approach depends on this "paging events" you need to implement some sort of gestural system for the user to keep paging.
I suppose you could use a timer in that same situation, so that if the user maintains the position and touch for another second, you would page again.
I have noticed a slight delay on the highlighted state of a UIButton when touched down if it is inside a UIScrollView (or a table view). Otherwise, the highlighted state is pretty much instantaneous.
I surmise this must be by-design to provide a chance for user to scroll. But it just seems like the button is unresponsive to me. Is there a way to fix this?
Indeed, it's a design choice. It needs this small time to differentiate a scroll (panGesture) from a tap. If you eliminate this delay, then the user won't be able to scroll if he places the finger on top of the button, which is not good user experience.
Because a scroll view has no scroll bars, it must know whether a touch signals an intent to scroll versus an intent to track a subview in the content. To make this determination, it temporarily intercepts a touch-down event by starting a timer and, before the timer fires, seeing if the touching finger makes any movement. If the timer fires without a significant change in position, the scroll view sends tracking events to the touched subview of the content view.
from the UIScrollView Documentation
I wouldn't recommend disabling the delay, but if you insist, you can set it in interface builder (select the Scroll View, and on the right panel, right under "Bounces Zoom"), or using this code:
scrollView.delaysContentTouches = false