I have a UIInteractiveTransition using a UIPanGesture which calls finishTransition or cancelTransition when it is finished.
However would there be a way to tell iOS the user has started panning again and you would like for it to cancel animating the view controller using the non-interactive portion of the transition and allow you to update manually ?
Call the finish/cancel transition after a delay with performSelector:withObject:afterDelay: and within that time if the gesture callback is received again, cancel the selector, and update the same instance of UIInteractiveTransition with the required percentage. Seems like this should do what you want.
Related
I have added an NSTimer which updates my interface, mainly labels with information 10 times every second. It calls a function which dispatches the work back to the main thread.
The view controller also has a scroll view. I have a paging system where I animate my scroll view's moving from page to page as a user taps on the tab (a button) which corresponds to each tab. That scrolling animation has just stopped happening - it is as if I am calling scrollToRect with animation as NO, even though I am calling it with YES.
I think that because I am updating my labels, auto layout is doing something dodgy in the background and ruining my scroll view animations. The same is happening for other animations which are using layout constraints to move views.
I know there are issues with Autolayout and NSTimer.
What can I do to fix this?
Thanks
I would create a boolean flag that inhibits the updates from the timer method. Set this to true just before you begin the animations and false once the animation completes. You probably also want to update the data 'manually' once the animation completes to capture any blocked updates.
Is there a way to begin a UIPanGestureEvent if the finger is already pressed at the time the object is instantiated?
I have a situation where when a user holds their find on a screen I create a UIView under their finger.
I want them to be able to drag that around and as such I have put a UIPanGestureRecognizer inside the UIView.
Problem is I need to take my finger off and put it back to trigger the UIPanGestureRecognizer to start up. I need it to start from an already pressed state.
Do you know how I can activate a UIPanGesture from an already pressed state i.e. can I get the touch event thats already active at the time of instantiation and pass it along?
You can do it, but the UIPanGestureRecognizer will need to exist already on the view behind the view you create (and you will then have to adjust your calculations based on this; not difficult).
The reason is that, under the circumstances you describe, the touch does not belong to the UIView you create - it belongs to the UIView behind it, the one that the user was originally touching. And given the nature of iOS touch delivery, you can't readily change that. So it will be simpler to let that view, the actual original touch view, do the processing of this touch.
I think Matt's solution is best so I am going to mark it as correct.
However my code structure wasn't going to allow me to cleanly implement it. Compounding the issue was the object listening was listening for a UILongGestureRecognizer.
So my solution was as follows:
Create a callback in my ViewController that would handle the longGestureOverride call
Add a callback to the object listening for the longGesture that would call the longGestureOverride callback and pass along the point
Manually move the object based on the point passed back
If the user lifts their finger, I disable the longGestureOverride callback, and begin using the UIPanGesture inside the new object
I am trying to programmatically make a 2nd tap occur on the screen a few seconds after the actual tap event occurs. For example, if I tap the screen in the bottom left corner...is it possible to then programatically make a tap occur at a specified set of coordinates a few seconds later (see image).
You don't need to do horrid things like overlaying invisible buttons and faking taps.
All you need to do is set your view controller to conform to the UIWebViewDelegate protocol, and implement the webView:shouldStartLoadWithRequest:navigationType: protocol method.
By implementing this method and checking for a link-tap event with if(navigationType == UIWebViewNavigationTypeLinkClicked) your app is now being informed of link-taps without intercepting and eating them via invisible buttons, so your web site doesn't miss out on being informed of the request.
You can then implement the necessary logic to change categories in JQuery on the site.
When I demo my touch apps to remote teams the people on the other end dont know where I am touching. To remedy this, I have been working on an event intercepting view/window that can display touches over applications. No matter how may variations on nextResponder I call, I am unable to react to the touch and pass it along to the controllers underneath. Specifically scroll views dont react nor do buttons.
Is there a way to take an event, get its position, then pass it along to what ever component would have been responding to it initially (the controller underneath)?
Update:
I am making some progress with a UIView. The new view is always returning NO to pointInside.This works great for when the touch starts, but it doesnt track moves or releases. Is there a strategy to adding gesture recognizers to the touch in order to track its event lifecycle?
Joe
You could try creating your own subclass of UIApplication that overrides sendEvent:. Your implementation should call [super sendEvent:event] as well as process the event as needed.
Update your main.m and pass the name of you custom UIApplication class as the 3rd parameter to the call of UIApplicationMain.
After some more due diligence, I found my oversight. In the layer that was on top and displaying the touches, user interaction needed to be set to false. Once I set that to false, I was able to use that layer for display while catching events on the layers below. The project still isn't done but I am one step closer.
Take care,
Joe
In my iOS application, when the user pushes a button in a view, a NSTimer is trigered in the controller.
On the third tick, I would like to make the background of the view bliking.
I've written the blinking function in the view (it should't be written in the controller, should it ?)
I can trigger this blinking function in the controller by
LostView *lostView = (LostView* ) self.view;
[lostView blinkBackground];
But it's bad, isn't it ? The controller shoudn't know the view neither the name of the function ?
I would like to apply the MVC pattern
Is the observer/obervable pattern applicable in this situation ?
Thanks
No it's not bad at all. It looks like you implemented the method to make the view blink in the view itself. That's fine, because it's directly related to the visual representation (i.e. the view part of MVC). You could reuse that view in any other app that requires a blinking view.
Since that blinking is triggered by an NSTimer I assume that it's somehow dependent on the logic in this specific app. The view can't (shouldn't) know when it's supposed to blink (that would only be the case if that blinking was a direct reaction of an interaction with it or another related part of the UI - or it was part of a more complex element, for example a countdown timer that always starts to blink when it reaches the last 10 secs or so. For example the UIButton provides the possibility to highlight it self if it's touched.)
But if that blinking is a reaction of some state transition in your app, maybe some new data becomes available or a countdown is about to expire, the controller is a perfectly reasonable place to trigger that.