Detecting when UITextField text has changed due to shake undo? - iphone

I have a UITextFieldDelegate that does a whole bunch of validation on user input to determine whether or not they should be allowed to end editing. In one particular example, it is not valid to leave the field blank.
Right now I'm using textField:shouldChangeCharactersInRange:replacementString: to validate the text input after each edit by the user.
The problem is this: if the user clears the field (with the little 'x' button), the validation code goes into "invalid" mode and prevents the user from navigating away until they have entered valid text. If the user then shakes the phone to get the old text back, shouldChangeCharactersInRange is not called again and the delegate stays in the "invalid" state instead of recognizing that everything is fine again.
Not sure if I'm using it correctly, but it seems like the built-in UITextFieldDelegate machinery is not able to cope with text changes due to undo / redo.
What's the best way to achieve proper validation in this scenario? Do I really need to subclass UITextField in order to implement motionEnded:withEvent:? Seems like the edit-handling stuff in UITextField should really be independent of whether the user actually typed it or it happened due to undo, so would be bummed if I actually had to go that route.

Hook up a method to the UIControlEventEditingChanged event ("Editing Changed" in IB -- not "Value Changed").
This appears to fire whenever/however the text field changes.

Related

Xcode/iPhone -- break when the next event enters my code?

I am working on a large (>30k lines) event-driven app. I have a sequence of inputs that produces a bug. What I want to do is to break as soon as the final input enters my code.
Is there a general way to do that?
I understand that for any specific sequence of inputs, I can find out where that last input is going to enter my code, then set a breakpoint there. What I would like to do is take out the step of "find out where that last input enters my code." In other words, I am running the app in the simulator, and I want to set a flag somewhere that says "break the next time you are going to enter non-system Objective C code." Then I send the event that causes the problem.
I understand what you are asking, but have you tried using an Exception Breakpoint? This will basically act like an auto-inserted breakpoint on the piece of code that throws the exception. If that doesn't work for you, try a symbolic breakpoint
If you want to intercept UI events, you can try subclassing UIWindow and overriding its sendEvent: method, then setting this class as the class of the UIWindow object in your main XIB file. sendEvent: will be called each time the user generates a touch event. Unfortunately, at this point you cannot yet know which UI object will finally consume the event (read: which event handler code will be ultimately called) since that depends on the actual state of the responder chain. But anyway, you can use this method to inject events into the system.

Gtk suppres focus-out

It seems for me that best place for validation of user input is in focus-out-event handler of entry type widgets (but this is only my thinking). I try to return TRUE from focus-out-event with idea that this will avoid to transfer focus to next control and keep focus on current widget, but this is not OK (not work as needed).
Which is proper way to suppress of transfering focus to next control in case when validation don't pass and where to put validation code on such widgets (gtkEntry, gtkSpinButton, etc) to be usable with signals invoked with both - mouse and keyboard actions?
That is hardly a good idea... Focus is (should be) always owned by the user. That is, the users should be able to move the focus wherever they see fit. If you try to direct the focus, or prevent moving it, based on any logic you can imagine, you will likely frustrate them.
It will surely frustrate me! Say for example that I wrote a wrong data in a box, and then I say, "hey, that's wrong! I want to select that data over there, copy it and paste it here". But I cannot do that because the program will not let me leave the box where I am now without writing an acceptable data. I have to delete the wrong data and enter something... just not good.
The best way to validate the user entry is when you actually do something with it. Either when you save it or when you make it effective. Then you can even make a pop-up saying that there is an error, and when it is close, move the focus to the first error.
If you feel that the user can benefit from an early warning that he is doing wrong, you can use colors (paint the box yellow/red if there is an error), or add a small error icon next to the box. That is waaaay less disruptive than moving the focus around.

iPhone SDK: Problem with textFieldDidEndEditing being called

In our app, in some cases, textFieldDidEndEditing is not being fired. After some debugging, it was easy to see the reason why....textFieldShouldEndEditing was returning NO when the current field is deemed invalid or in other words returning no from textFieldShouldEndEditing.
In the normal case, this behavior works just fine. However, if the user tries to cancel out of the form all together without every fixing the data problem flagged in textFieldShouldEndEditing, some critical code in textFieldDidEndEditing is never being called because that event never fires if textFieldShouldEndEditing=NO;
Can anyone provide some suggestions on how to deal with this case?
Thanks.
Do an [yorTextField resignFirstResponder]; when user try to cancel.
this seems to work....setting an instance variable when the user presses cancel and then using that in textFieldShouldEndEditing ie. = YES

iPhone SDK: How to store the time each word was typed?

My problem is twofold: 1) I'm trying to determine an eloquent way to allow the user to type into a UITextView and store the time each word was typed into an array. The time will be a float which starts at 0 when the user begins to type. 2) Conversely, I'd like the user to be able to tap on a word in the UITextView and display the time that word was typed (displaying in an NSLog() is fine). Considerations that may throw a wrench into a possible approach -- what if the user goes back to the top of the text and starts typing or to the middle of the text?
Even a suggested approach without code would be appreciated, because right now I'm drawing a blank.
I think you will need to have a delegate for UITextView which implements textView:shouldChangeTextInRange:replacementText:. In there you get every character that the user types. You can get the time/date (using NSDate) and save it when the user starts a word.

Detecting iPad keyboard hide versus external keyboard connect?

The iPad virtual keyboard will disappear in one of (at least) these 3 circumstances:
If the control (say, a UITextField) programmatically resigns first responder.
If the user taps the "dismiss keyboard" button in the lower right.
If the user connects to the USB/keyboard dock peripheral.
In all cases, I get the UIKeyboardWillHideNotification.
The problem is that the first two cases are generally equivalent-- in other words, the user is done editing the text field. But in the third case, the text field is still being edited, just from another input source.
The problem is detecting the difference between cases 2 and 3. All I get in both cases is UIKeyboardWillHideNotification. In case 2, I generally want to also lock the edit control and commit the value. In case 3, I generally want to do nothing and allow editing to continue.
But how can I tell the difference?
Apple's Pages app seems to be able to distinguish this on document-title renaming.
I would look at the UIKeyboardBoundsUserInfoKey passed with the notification. The physical keyboard probably has empty bounds.
It sounds like you're just trying to figure out when a user is done editing. You could listen for the UITextFieldTextDidEndEditingNotification notification for cases 1 and 2.
A much simpler solution would be couldn't you just check against the editing property of UITextField to determine if it's still supposed to be editing or not? I don't have a physical keyboard, so I have no way to test this. I'm just guessing.
Here's a link to the documentation on that property: http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITextField_Class/Reference/UITextField.html#//apple_ref/occ/instp/UITextField/editing
I'm very curious to know if this works or not... :)