I currently have a project where I present a HUD using this control:
https://github.com/samvermette/SVProgressHUD
I present the SVProgress HUD over a complicated hierarchy of UIViews and ScrollViews.
SVProgressHUD is a bit like a UIAlertView, it presents a message but it auto dismisses itself.
In one part of my app, I am using it each time the user pops through a page in my UIScrollView.
The autodismiss feature is good but I want the user to be able to tap the hud and dismiss it early if required.
So I know SVProgressHUD posts a notification to notification center
SVProgressHUDDidReceiveTouchEventNotification
This is good, and what i've done is add a notification observer in my main viewController which calls a class method on SVProgressHUD to dismiss any presented HUD's when the SVProgressHUDDidReceiveTouchEventNotification is posted.
My problem (and question is) how can I ensure this dismiss method doesn't interfere with my scrollview?
I want my users to be able to quickly swipe through scrollview content pages, however since I started listening to this notification the scrollview doesn't react to the first touch of the user, it uses the first touch to dismiss the HUD. This feels quite clunky.
The problem is SVProgressHUDDidReceiveTouchEventNotification is being posted even if the HUD isn't touched and instead my Scrollview underneath is touched. How can I add a hittest inside my dismiss method to check that SVProgressHUDDidReceiveTouchEventNotification was posted because the HUD itself was touched?
Thanks!
I implemented touchesEnded in SVProgressHUD and handle touches there.
Related
I have a tab bar app that works. Each tab is a UINavigationController whose root view is some kind of UIViewController, often a UITableViewController.
There are instances in the app where I want to display a full-screen "veil" with a message about what's happening until some operation completes. The point is to swallow up any touches on the UI that would navigate away from where the operation started.
The veil is a UIView subclass. There is one singleton instance of the class. When displayed, I insert it as a subview of the UITabBarController view. The view appears over the entire UI, tab bar included. Great!
Here's the problem. I can tap the tabs and the UI changes. What I would have expected is that my veil view would have just swallowed up the touches.
I have implemented in my veil class the various touches{Began|Ended|Moved|Canceled} methods (as do-nothing methods), but the touches are still picked up by the tab bar, and frankly by any object under whereever I happen to touch.
I've also tried overriding a number of other methods including nextResponder, hitTest:withEvent:, etc, to no avail.
I am a little stumped at this point. I'm hoping someone will have some sage advise. :-)
Thanks.
It's not safe to modify the view hierarchy of framework classes. You would be much better-served simply adding it as a subview of the window itself. As for consuming touches, if making this change doesn't work, then you should also verify that userInteractionEnabled is set to YES on the view. You should not have to actually implement any touch-related methods.
I also had this problem and came up with a hacky solution. In the init of your custom UIView class, create a dummy UIView that's impossible to hit, for example [[UIView alloc] initWithFrame:CGRectMake(-1, -1, 0, 0)]. Or actually, I think any UIView not attached to the window works. Then, in hitTest:withEvent:, have it return the dummy view for every point not in your area of interest.
I did a simple view based application.
I need to place three textfields in an alert view.
it is not possible According to UI guidelines.
So that i crate a view just like an alert view,And place text field in them.
Add it as subview to mainview while tap on a button.
Now what i need is when ever tap on button i need to disable userinteraction to main view,and enable userinteraction to the subview.
For that i am trying this code on button click event.
[object.viewController.view setUserInteractionEnabled:NO];
here object is object of appdelegate class.
But,if i place this it disables userinteraction of subview also.
But i need to disable for only main view.
i think people get what my problem,
if not let me add a comment.
Thank u in advance.
You can add UITextField inside UIAlertView, so it will cover main view so (as you required) user could not interact with the main view.
Similar thread which discuss UITextField in UIAlertView on iPhone - how to make it responsive?
Here is You tube video to add UITextField inside UIAlertView
I hope it will resolve your problem.
i resolve my problem,instead of disable of user interaction of main views i disabling user interaction for contents in the view(Buttons,textfields...).
And enabling then when sub view while closing sub view.
Let me Know if there is any Better way than this.
try using an action sheet. they;re much more flexible. on second thought check out InputAlertView in this
I have a page-curl modal working. But I need to be able to track when the user hits the page curl to close the page so I can see some vars. Is there an event I can listen for or some delegate where I will get a call to tell me of this event?
Many Thanks
-Code
You'll see a lot of advice around here advocating the use of performSelector:withObject:afterDelay: with a small delay to take action after the dismissal of modal views, but I think there may be a better approach.
Generate the notification yourself. If you control the view that's being presented modally, use the viewDidDisappear: method in its controller to generate an "I was dismissed" notification which you then subscribe to in your main view controller (or somewhere else). viewDidDisappear: is called after the page uncurl animation completes upon dismissal of the modal view.
In the worst case, where the view may be presented modally or otherwise, you can keep state on the presenting view controller to ensure that the notification actually corresponds to a modal view dismissal.
For completeness' sake, viewWillDisappear: is generated when the page decurl transition starts.
I'm currently working with 2 views on a UINavigationController.
I have a Leaves view (Tom Brow's leaves project) to simulate curling effect for pages which only works with images, and my actual view controller with the page and it's contents.
What I'm trying to do is, when tapped on certain place, popViewControllerAnimated:NO the actual view controller, leaving the leaves view behind on top and trying to do the page turn without having to tap again on the screen and keeping things as if no switch ever happened.
My issue here is that the touches seem to go through a black hole and never get to the current view. I've even tried to catch the touches with a custom UIApplication subclass, but as soon as the first view gets popped the touches start coming with nil view and window and phase = UITouchPhaseStationary.
The views in the navigation controller are pushed: one as the rootViewController in the init method and the other with a pushViewController:animated:.
Is there something I'm missing or there's just no way to keep touches through views in a UINavigationController?
EDITED: Final solution, clear overlay to get touches
In this (Flip View Iphone) post, I have created a flip view for my iPhone app.
Now, I want to make sure that whenever the user hits the 'Back' button in the navigation bar, the next time around when he drills down to the flippable view, this view is in its original, non-flipped position. Currently, the app actually loads the correct view, but somehow, when you try to flip it over, it cannot doesn't load the flip view, and presents a black background only.
One solution could be to assign the flip back method ("showLessInfo") to the navigation button, and that is what I need your help for.
Alternatively, and quite likely a better idea for me would be to understand, why the flip view is not loaded the second time around.
Any suggestion is welcome!
You can override the viewWillAppear: method on your flip view's view controller and make sure behind the scenes it loads the proper view before showing (remember to call [super viewWillAppear:animated]).
Or else, you could override the viewWillDisappear and make sure things are cleaned up on the way out. It will get invoked when the user taps the back button.