How to get currently active UIEvent? - objective-c

Background
I have a custom UIWindow implementation that posts a notification in the sendEvent method. Then I have a custom view that, once added to the window hierarchy, removes itself from superview as soon as the mentioned notification is posted (i.e. tapping anywhere, in this view or not, removes the view). Finally, I have a button that causes this custom view to be added to the view hierarchy. Now the problem is that when I tap this button, the view gets added to the view hierarchy, BUT, the event that was caused by this tap reaches my custom UIWindow sendEvent method AFTER the custom view is added, thus resulting in the custom view being removed immediately after it has been added.
Question
I want to somehow access whatever UIEvent is currently active. Is this possible to do, and if yes, then how?

I solved this by listening for the notification in order to track the most recent UIEvent (I provided the UIEvent in the userInfo). Then, when receiving the notification again, I made sure that it is not the same event as the one that occured just before the custom view appeared (if it is, I skip the removal of the custom view).
While this is an answer to my question, the solution to the underlaying problem that #matt proposed in an answer to the following SO question turned out to be much better: How can I know when any of the objects on screen were tapped?

Related

View not updating before automatic Segue away from itself

Essentially I have a view controller where the user picks from three choices. Once the user chooses something, the view segues away to another view controller that displays some information regarding their choice for about 5 seconds and then segues back to original view controller automatically where the User must make more choices... (its basically a loop until something is accomplished).
The problem I am having is when the User touches their option, it seems to just segue back to itself without ever displaying the intermediary screen. I added a sleep(5); to the viewDidLoad but all that causes it to do is pause on the original choice screen for 5 seconds before segueing to itself. I also put in an NSLog in just to make sure it was actually using the new controller, which it is indeed.
I didn't include code since its so trivial. viewDidLoad on the new controller, has sleep(5) and the call to segue back to the original view controller.
I solved the problem by moving the code to viewDidAppear. Should have done that from the beginning honestly, just didn't think it through enough I guess.

add a subview to a not-showed uiview

I'm dealing with a weird problem: I've got a UIViewController to handle a list of items to download via inapp purchase.
When a user choses the product to buy, all the purchase flow begins. At this particular moment, I push a UILabel and a progress bar to display the current state of the download.
If, before that, a user choses to go in another part of the application (i.e. by tapping an item form the tab bar menu ), the application continues the purchasing process from there (that is reduced down to saying yes to a couple of dialog boxes and inputing the itunes store account credentials).
The process (that is attached to a background thread) runs smoothly till the end of it, but if the user comes back to the store view the UILabel and the progress bar are not show, I mean, they are initialized and running but they're not visible.
Is there a right way to behave in that circumstance?
Do I have to force the refresh of the view, or do I have to remove'em from the superView and push'em back again?
thank in advance,
hope I'd be clear enough, otherwise don't be afraid to ask, I'll be glad to
explain myself in a more deep and clear way.
-k-
Without a code it is difficult to give you the exact solution.
A possibility is that when you moved out from the original UIViewController the system did unload the view on that controller. It is possible that with this unload the progress bar and label were not destroyed (because over-retained by your view controller or not nil-ed in the viewDidUnload method) but when you entered in the view controller again the view was reloaded from scratch (typically from the nib) with new progress and labels.
So it is correct that you retained the progress bar and label (even if there are better ways to achieve the same result) but you must add them to the view controller view in the viewDidLoad method. A typical way to do this is to store a "active" progress bar in a dictionary and when the view is reloaded from the nib it must be added to it. As soon as the download finish you can remove the progress from both the dictionary and the view. There are other ways to accomplish the same result, so my suggestion is just to give you an idea.
So in order to see if my answer is correct, you must check the viewDidUnload method, add a breakpoint on it and see, once it has been triggered and when you come back to your original view, if the progress bar has disappeared or not.
Hello Holographix u havnt posted any code so it would be difficult to tell
well it seems like the object of Uilabel and progress bar are getting released the time u comes back to the view.

UITextView: Must I always resignFirstResponder?

Must I always resignFirstResponder for a UITextView? Or, will this happen automatically when its view controller disappears?
I'm asking because I'm having an issue similar to iPhone Objective-C: Keyboard won't hide with resignFirstResponder, sometimes, where the keyboard stays up even when the nav controller pushes and pops other view controllers. The keyboard works, and when I hit done, it unfocuses the UITextView (i.e., the cursor disappears), but the keyboard stays up.
I never found out why this is happening, but maybe it's due to not doing resignFirstResponder before pushing another view controller, but I thought it was optional?
At a total guess, the UITextView has a reference to the view controller (as its delegate) but does not retain it. When you go to the next screen, the controller is dealloced and then the UITextView (which has perhaps been retained by something else) tries to call back to the dealloced controller and crashes. When you call resignFirstResponder, you reverse the order this happens, and therefore no crash.
The way round this to add a textView.delegate = nil call in your view controller's dealloc method - obviously put it before you release the text view.
The contract between a UITextView and it's delegate says that the delegate will send -resignFirstResponder when the text view is done editing. This informs the framework that the view is done editing, fires the events relating to that (willEndEditing and didEndEditing), and allows other parts of the responder hierarchy to react accordingly. Failing to do so might work, but it's not following the contract (that's all a protocol is) it agreed to.
I don't think you have to because the Xcode Sample UICatalog UITextField doesn't call resignFirstResponder before the TextViewController is popped.
The reason the keyboard got stuck for me is that I was having the same view controller present two view controllers modally at the same time, one after the other. UIKit didn't like that.
Calling resignFirstResponder makes sure that the text property contains the actual text shown in the control.
Depending on the state this is not always necessary, but if your controls have resigned first responder, you know that you're working with valid data.

Not getting viewDidLoad or Appear when switching tabs -- can I use NSNotification?

When I switch tabs in my tab bar application, one of my views needs to update because the user may have changed a preference that affects it. It is a UIViewController's view, but when the views switch, the viewDidLoad/Appear methods aren't called. Can this be solved using an NSNotification or any other way? Please give example code, especially for NSNotifications, as I am new to them.
You might want to peek at UITabBarControllerDelegate and tabBarController:didSelectViewController:. There you can determine how to handle the view change and whether you need to update the view based on the possible preference change.
tabBarController:didSelectViewController: you can implement this method in the appdelegate.
you will get the sxact root view controller at which yopu clicked . then you can update that view .

Present modal view controller on top of Quick Look PreviewController results in checkerboard-screen?

Situation: my app needs to present a full screen modal view whenever it becomes active (from background) to ask the user for a PIN. All fine.
Unless: if the user previews a file using QLPreviewController, leaves the app and comes back, the PIN input controller will be presented modally from the QLPreviewController which I'm keeping a reference to. The PIN input is shown but when it dismisses, I see a checkerboard-styled background which is even scrollable. Seems to be some leftover of the PreviewController but the actual preview data is no longer shown. Any idea what could cause that?
Do I have to reload the contents of the preview somehow?
I had similar issue and I've managed to pin down the problem to either viewWillDisappear or viewDidDisappear methods. My solution was to subclass QLPreviewController and overwrite those methods with empty implementation i.e. skipping the call to super. I don't know if it's very safe, though I haven't encountered issues and it solved my problem.