How can I send characters to cursor position of UISearchBar? - iphone

I am trying to add a couple characters that are inconveniently located in the normal keyboard, and place them in a toolbar so that the user can use them just like normal keys.
Does anyone have a useable way to do this?
I found an article explaining how to do this by simulating a "Paste" operation, (remove pasteboard contents, replace with my character, paste into field, return original pasteboard contents) but my trouble is that I'm trying to do this with a UISearchBar, which seems to have no paste selector.
Update
I found a lead:
UIKIT_CLASS_AVAILABLE(2_0) #interface UISearchBar : UIView {
#private
UITextField *_searchField;
Since it is documented that there's a UITextField in a search bar, if I were to root through the searchbar's subviews and locate said text field, (assuming with 99% certainty that the text field has a delegate) would it make sense that I could "steal" the text field and make my class the delegate, then forward the messages to the original delegate once I'm done with them?

This is definitely tricky. UISearchBar doesn't give you inputAccessoryView and nor do you get selectedRange.
You can paste in a UISearchBar. If you want to get your tricky characters to the pasteboard, you could get a button to execute something such as:
[[UIPasteboard generalPasteboard] setString:#"[*]"];
and then get the user to use paste in the UISearchBar. Pretty awkward for the user though.
Rooting through the subviews to find the UITextField might work. If you do this, you'd need to grab the existing delegate and make yourself the delegate. Then your delegate would need to transmit messages on. The process is described in this stackoverflow question and answer. Potential challenges here: (a) the Apple implementation could change between iOS updates and even, though unlikely, change the delegate during the lifetime of the UISearchBar; (b) Apple might see this as using a private API and reject the app. (I don't have any hard evidence of (b), but it's something to consider.)
One approach might be to use the bookmark button. The UISearchBar delegate can detect this. You could use that to insert your special characters or offer up a menu of special character insertions. Of course, you won't know where the cursor is. But, depending on your use case, appending the special characters at the end might be OK. Perhaps this doesn't get you anything over a button on your interface that just appends something.
[[self searchBar] setText: [NSString stringWithFormat:#"%#[*]", [[self searchBar] text]]].)
Implementing your own search bar might be the best way to go as already suggested #hyperbole. I've done this successfully by adding a custom UITextField (with my own magnifying glass in the leftView slot etc.) and adding it as the titleView of my navigationBar. But, if I understand your question aright, that still won't be enough, as UITextField doesn't provide selectedRange and its delegate doesn't provide an equivalent of textViewDidChangeSelection:. You might have a go with a UITextView that is fixed to one line (with scrolling clamped down if required - it often seems to be).

Can't you simply set the text of the UISearchBar? Of course, the tricky part is to determine the cursor position. For that, you can register a UITapGestureRecognizer on the UISearchBar, determine the tap co-ordinates & calculate the cursor position using - (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode or its variants.
You may also have to register a UIPanGestureRecognizer, as the user can change the cursor position by tapping, dragging & then releasing the finger.
HTH,
Akshay

Related

How can I make an unknown UITextField resign first responder?

My view has two UITextFields and a UISwitch. If a user is edits a textField, and then immediately touches the switch (without pressing return), the text is left as they typed it, without AutoCorrect.
If I know which textField they were typing in, I can force the autocorrect to complete by calling [textField resignFirstResponder]. But the user could be typing in either textField, so I don't know which one to call.
How can I get around this? Is there a way of detecting which textField was being used? Or something simpler I haven't thought of?
One lovely way of doing this without having to keep track of which field is active:
// This causes the current responder (eg. an input field) to resignFirstResponder and
[self.endEditing:YES];
Replace [self.view endEditing:YES] with the below one...
[[UIApplication sharedApplication] sendAction:#selector(resignFirstResponder) to:nil from:nil forEvent:nil];
The uitextfielddelegate methods are called for the textfield on which the editing is in progress. So that way you needn't be facing the problem of detecting which text field is being edited.
So implement the uitextfielddelegate methods and assign the delegate of the text field to the class where you implement the methods and handle the responses in them.
The methods which you should be interested in are:
textFieldDidEndEditing:
Tells the delegate that editing stopped for the specified text field.
- (void)textFieldDidEndEditing:(UITextField *)textField
Parameters
textField
The text field for which editing ended.
Discussion
This method is called after the text field resigns its first responder status. You can use this method to update your delegate’s state information. For example, you might use this method to hide overlay views that should be visible only while editing.
Implementation of this method by the delegate is optional.
Availability
Available in iOS 2.0 and later.
Declared In
UITextField.h
You may keep track yourself which one is the current one, by using the textFieldDidBeginEditing delegate.

Change default touch events for UITextField

Alright, so here is what I am trying to do. I have a UITextField. When I single tap it, I want to call one of my methods. When I double tap (tap it twice with 1 finger) it, I want to edit the text field (as though I had single tapped it on a normal UITextField.)
I am not sure how to go about this. I was thinking of sub-classing UITextField and trying to intercept the touch event as it is sent, but I can't figure out which methods to override to do this. Which methods should I override and how?
Or, if there is a better way to do this, let me know! I'm all ears, and not sure how to proceed.
This would involve several steps:
1.) Add a NSBoolean property that keeps track of whether the user has already tapped the field once recently (you get to decide what recently means here).
2.) Implement the textFieldShouldBeginEditing: method of the delegate assigned to your UITextField. If the user has tapped twice in quick succession (detectable by checking whether or not the boolean property is true), then return YES. If not, call your method, and then return NO.

how do I know when UIKeyboard Join button is tapped?

How do I know when a user taps on the Join button on the UIKeyboard?
Also can this text be changed? I know there are several built options but I nee done that says 'Login' if I can.
I'm not a big fan of using UITextField delegate just for knowing when keyboard entry is completed by pressing the "return" on the keyboard (whatever it's labeled). UITextField actually works well with a Target/Action pattern which is much simpler and far more direct than using the delegate for this.
I've pointed this out before in an answer to "How to call a method when the Done Button in the KeyBoard is Clicked?". Please take a look at that for the details of using the traditional target/action pattern to know when keyboard entry is complete. Unfortunately, Apple's documentation isn't as clear is it could be on this subject.
UITextField delegate has its place, but if all you need is to know when entry is complete then using the delegate likely isn't the best approach. Use target/action.
For the UIReturnKeyType choices, see the returnKeyType property in the UITextInputTraits Protocol Reference.
You should set your delegate of your UITextField (I'm assuming that's a UITextField) and check for that delegate call :
- (BOOL)textFieldShouldReturn:(UITextField *)textField
Also, you return a BOOL to tell the UITextField to do its default behavior or not. You can check the documentation here.
Also, the options Apple gives you for the UIReturnKeyType are your only options.

Detect when a user clicks the paste button in a UITextView

I am having quite a issue trying to change the cut/copy/paste behavior of the UITextView.
What I want to achieve is: detect when the user has pasted some text into the UITextView. When I detect this I will then check the data and do my thing.
According to the documents, I found out about UIResponder.
So I created an simple class that inherits UITextView.
in the .m file I create 1 function called.
-(void) paste:(id)sender{
NSLog(#"paste button was pressed do something");
}
But for some reason it never seems to fire. I could get the select statement working and tracing data.
-(void) select:(id)sender
1. Is this the correct way to detect Paste in a UITextView?
2. Right now I am tracking buy how many Characters UITextView changes and if its greater than one char then I suspect that it could be a paste operation. But since the iPhone can autocomplete words eg Wedn (goes to Wednesday) its possibly not a paste operation.
In Interface Builder, I selected my textView in my NIB file, and selected its "Class Identity" to my nearly created class before and I know that this file was working as a subclass but it just would not respond to the Paste event.
thanks.
UITextView has a view that handles the cut, copy, paste. It's UIWebDocumentView. So if UITextView is the first responder, UIWebDocumentView will get it first instead of your implementation. I would like to overwrite these functions so this is very frustrating.
Same thing happens to me too. Select (and copy sometimes) gets called but paste never.
I have simulated the behavior using textViewDidChange where I always verify the difference between the current text and the previous one. If there are more letters different and the text.length is bigger than it must have been pasted.
Hope Apple will fix this.
In case somebody still needs short and easy solution I'll share mine. I use wonderfull NSObject+REResponder category from REKit project. The solution is as easy as this:
- (void)hookMessageTextFieldPasteAction
{
void (^textFieldDidPasteBlock)(id receiver, id sender) = ^(id receiver, id sender)
{
NSLog(#"paste hook");
};
[self.messageTextField respondsToSelector:#selector(paste:) withKey:nil usingBlock:textFieldDidPasteBlock];
}
Yes your above code for paste is correct according to Apple's Documentation which refers to it here.
- (void)paste:(id)sender
I suspect you are implementing it in the wrong file. You should be implementing it in a file that is part of the 1st Responder chain. Have you subclassed the UITextView or are you using a vanilla one in your ViewController?
Hmmm I think the problem is that you may need to make your UITextView subclass become the delegate in order for the delegate method to work, because it's not by the looks of things. I'll try to find how i did that before.
Okay think i found it. I think you need to do this on your subclassed UITextField class:
#interface mySpecialTextFieldClass : NSObject <UITextFieldDelegate>
{
}
Adding that onto the end should work, give it a try!
What it does is makes your subclass become an object of a type that the delegate can send a notification to...it's polymorphism, unless someone wants to correct me here :)
One last thing to try John, in the ViewController which contains the IBOutlet to the UITextView, try calling this method on the instance of the UITextView:
[myUITextView setDelegate:self];
Just to throw something completely random in there try setting it to become first responder.
[myUITextView becomeFirstResponder];
This is called programming in the dark kiddies! And is a very bad way to program, but I admit I do it and sometimes it pays off :P lol.

how to get input from UIAlertView?

I want take player name as input by using UIAlertView. Is it possible to add textField on the UIAlertView?
Since iOS 5, UIAlertView provides this: change the alertViewStyle property to one of the following:
UIAlertViewStylePlainTextInput (1 text field)
UIAlertViewStyleSecureTextInput (1 password field)
UIAlertViewStyleLoginAndPasswordInput (both a text field and password field)
Then use textFieldAtIndex: to get the text field you want. This way, you can even use the alertViewShouldEnableFirstOtherButton: delegate method to enable the button.
Yes, it's definitely possible, and it isn't a hack. You would need to subclass UIAlertView and place controls into it. Since it's a subclass, it will retain the same look & feel, etc.
For full details, see this tutorial by Jeff LaMarche (co-author of Beginning iPhone Development, from Apress).
Yes, but not without some hacking, see this previous question.
You'd have to directly manipulate the UIAlertView's subviews and add a UITextField and then resize the UIAlertView's frame. You're better off creating your own view.