how to add done button in keypad - iphone

i need to add button done on keypad.
Apple does n't provide such felicity but some of application i found that done ,next,previous buttons.
like this.
how can i add these and how can i give click event to them.
can any one please help me.

1.Define the done button (= return key):
textField.returnKeyType = UIReturnKeyDone;
2.Add the action-listener:
[textField addTarget:self action:#selector(textFieldDoneEditing:) forControlEvents:UIControlEventEditingDidEndOnExit];
3.Define the action-event:
- (IBAction)textFieldDoneEditing:(id)sender {
[sender resignFirstResponder];
}
Have fun!
EDIT:
Here you can find detailed instructions how to add a Toolbar with Next & Previous above UITextField Keyboard:
http://www.randomsequence.com/articles/adding-a-toolbar-with-next-previous-above-uitextfield-keyboard-iphone/
EDIT2:
Now, I have a really great example for you: "This view extends UITextView adding on top of the keyboard associated with this UITextView a toolbar with a « Done » Button"
I check the code and it is a lot of easier than the first example:
http://blog.demay-fr.net/2009/07/cocoa-how-to-add-a-toolbar-with-button-on-top-of-a-uitextview-in-order-to-add-a-dismiss-button/
EDIT3:
Hmmm, no, I doesn't test to code. But I will test it now!
1.Problem: the right initialization. If I add the UITextView in IB, initWithCoder gets called:
- (id)init {
NSLog(#"init");
if (self = [super init]) {
//register a specific method on keyboard appearence
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
NSLog(#"initWithCoder");
if (self = [super initWithCoder:decoder]) {
//register a specific method on keyboard appearence
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
NSLog(#"initWithFrame");
if (self = [super initWithFrame:frame]) {
//register a specific method on keyboard appearence
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
return self;
}
2.Problem: There's no view with the the Prefix "UIKeyboard":
for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) {
NSLog(#"keyboardWindow = %#", keyboardWindow);
for (UIView *keyboard in [keyboardWindow subviews]) {
NSLog(#"keyboard = %#", keyboard);
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES) {
// THERE'S NO VIEW 'UIKeyboard'!!!
}
}
}
The code doesn't work, I'm sorry... I don't know why there's no view "UIKeyboard"... Maybe the first example will help you at this point and you can build your own solution.

Related

NSNotification in Cocos2d iphone

i have a button in the start screen of my game,when the user tap the button it will redirected to the next page, i calling a notification in this button click event ,the code for this is
- (void)switchsounds
{
CCLOG(#"hiii");
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadvieweyes" object:nil];
CCTransitionJumpZoom *transition = [CCTransitionJumpZoom transitionWithDuration:1.0 scene:[HelloWorldLayer scene]];
// Tell the director to run the transition
[[CCDirector sharedDirector] replaceScene:transition];
}
the above code is the button click function
on the next page of init statmnet i put this code to get the functonalty of the button event
-(id) init
{
if( (self=[super init])) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(viewreloadedeyes) name:#"reloadvieweyes" object:nil];
}
return self;
}
-(void)viewreloadedeyes
{
CCLOG(#"hiii");
}
i didnt get the cclog in button click event aswell as the function in the next page.but the page redirction is done with the button lcick.what is the problm with my code.how to get nsnofication from one page to anothe in a button click.
Thanks in advance.
Notification selectors require the NSNotification* parameter. Change your code to this:
-(id) init
{
if( (self=[super init])) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(viewreloadedeyes:)
name:#"reloadvieweyes"
object:nil];
}
return self;
}
-(void)viewreloadedeyes:(NSNotification*)notification
{
CCLOG(#"hiii");
}
heyy guys,i found the solution, i just put the notification inside the view transtion like this
- (void)switchsounds
{
CCLOG(#"hiii");
CCTransitionJumpZoom *transition = [CCTransitionJumpZoom transitionWithDuration:1.0 scene:[HelloWorldLayer scene]];
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadvieweyes" object:nil];
// Tell the director to run the transition
[[CCDirector sharedDirector] replaceScene:transition];
}
now its woking perfectly.Thanks.

Keyboard and getting up state on iPhone

How do I find out if the keyboard is up?
I have a UISearchbar instance which becomes the first responder.
When the keyboard appears a notification is sent out as part of the API, however I don't want to respond to this right away. I could record this in a boolean state, but that seems clunky. I'd like to know if there is a "getter" some where I can call to find out.
This is how I do it:
KeyboardStateListener.h
#interface KeyboardStateListener : NSObject {
BOOL _isVisible;
}
+ (KeyboardStateListener *) sharedInstance;
#property (nonatomic, readonly, getter=isVisible) BOOL visible;
#end
KeyboardStateListener.m
#import "KeyboardStateListener.h"
static KeyboardStateListener *sharedObj;
#implementation KeyboardStateListener
+ (KeyboardStateListener *)sharedInstance
{
return sharedObj;
}
+ (void)load
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
sharedObj = [[self alloc] init];
[pool release];
}
- (BOOL)isVisible
{
return _isVisible;
}
- (void)didShow
{
_isVisible = YES;
}
- (void)didHide
{
_isVisible = NO;
}
- (id)init
{
if ((self = [super init])) {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(didShow) name:UIKeyboardDidShowNotification object:nil];
[center addObserver:self selector:#selector(didHide) name:UIKeyboardWillHideNotification object:nil];
}
return self;
}
-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
#end
Then use this to figure out the rest:
KeyboardStateListener *obj = [KeyboardStateListener sharedInstance];
if ([obj isVisible]) {
//Keyboard is up
}
The only sure way that I can think to do it as you said. using notifications like this:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
and then
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
Other than that, you may be able to iterate through your views subviews and look for the keyboard like:
UIView *keyboard = nil;
for (UIView *potentialKeyboard in [myWindow subviews]) {
// iOS 4
if ([[potentialKeyboard description] hasPrefix:#"<UIPeripheralHostView"]) {
potentialKeyboard = [[potentialKeyboard subviews] objectAtIndex:0];
}
if ([[potentialKeyboard description] hasPrefix:#"<UIKeyboard"]) {
keyboard = potentialKeyboard;
break;
}
}
But I am not sure if this will break when the SDK changes ...
Maybe use this method and add a category to the window so that you can just always ask the window for the keyboard ... just a thought.

Is it possible to check if done button is pressed

I have notification on movie player:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
And it's handler:
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
// Remove observer
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
[self dismissModalViewControllerAnimated:YES];
}
Here in this handler method I want to check if the done button is sender. Because I have two senders to this method. How ti check this?
Per docs: MPMoviePlayerPlaybackDidFinishNotification userInfo dictionary must contain NSNUmber for MPMoviePlayerPlaybackDidFinishReasonUserInfoKey key indicating the reason playback has finished. Its possible values:
enum {
MPMovieFinishReasonPlaybackEnded,
MPMovieFinishReasonPlaybackError,
MPMovieFinishReasonUserExited
};
You will first need to assign tag to your buttons before the action and then check the value of the sender tag.
Just add these lines of code:
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
NSInteger anyInteger = [sender tag];
//Now check the value of the anyInteger and write the code accordingly.
//switch case or if condition whatever you want.
}
That's it.
This is an old thread but I stumbled upon it while looking for a solution, and the accepted solution doesn't show the final code.
Here is what you have to do:
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
NSLog(#"moviePlayBackDidFinish");
// Remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
NSInteger movieFinishReason= [[[notification userInfo]objectForKey:
MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
if(movieFinishReason == 2 || movieFinishReason == 1 || movieFinishReason == 0){
[self dismissViewControllerAnimated:YES completion:nil];
}
/*
MPMovieFinishReasonPlaybackEnded = 0,//played movie sucessfuly.
MPMovieFinishReasonPlaybackError = 1, //error in playing movie
MPMovieFinishReasonUserExited = 2; //user quitting the application / user pressed done button
*/
}
Add tag with the button and put condition according to the tag.
Or check by
if([sender isEqual:btn1])
{
}
else
{
}

textFieldShouldBeginEditing + UIKeyboardWillShowNotification + OS 3.2

I have multiple textfields on a UIView.
I resign for a previous textField in textFieldShouldBeginEditing method, where following sequence of events are performed
UIKeyboardWillHideNotification is received corresponding to that field where the keyboard for the previous field is hidden.
the method textFieldShouldBeginEditing returns a YES and then
UIKeyboardWillShowNotification is received where the keyboard for the current field is displayed.
However, in OS 3.2 even though textFieldShouldBeginEditing returns a YES, UIKeyboardWillShowNotification for the current field is not received.
The logic works for OS < 3.2
Any ideas where I might be doing wrong?
Listed below a part of my code (with only two text fields in xib).
I need to perform a set of operations at keyboardWillShow and keyboardWillHide Look at the difference on running the code in OS 3.2 and OS < 3.2
Can anyone explain the difference in behaviour?
.h
#interface ExampleViewController : UIViewController
{
IBOutlet UITextField *numericTextField;
IBOutlet UITextField *alphaTextField;
UITextField *lastTextField;
int lastCursorPos;
int cursorPosition;
NSMutableArray *textFields;
}
#property (nonatomic, retain) UITextField *lastTextField;
#property (nonatomic, retain) NSMutableArray *textFields;
#end
.m
- (void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:self.view.window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:self.view.window];
self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
self.textFields = [[NSMutableArray alloc] initWithCapacity:2];
[self.textFields insertObject:alphaTextField atIndex:0];
[self.textFields insertObject:numericTextField atIndex:1];
cursorPosition = 1;
[numericTextField becomeFirstResponder];
}
-(void)viewWillDisappear:(BOOL)animated
{
[self setEditing:NO animated:YES];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
int index;
for(UITextField *aField in self.textFields){
if (textField == aField){
index = [self.textFields indexOfObject:aField];
}
}
if(index>=0 ){
lastCursorPos = cursorPosition;
self.lastTextField = [self.textFields objectAtIndex:lastCursorPos-1];
cursorPosition = index +1;
}
[self.lastTextField resignFirstResponder];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
- (void)keyboardWillShow:(NSNotification *)notif {
NSLog(#"Inside keyboardWillShow");
}
- (void)keyboardWillHide:(NSNotification *)notif {
NSLog(#"Inside keyboardWillHide");
}
I believe that as of iOS 3.2, UIKeyboardWillHideNotification and UIKeyboardWillShowNotification are no longer fired when switching between two text fields. Basically, the notifications only fire if the keyboard is actually shown or hidden, and since switching from one text field to another doesn't hide the keyboard, the event doesn't fire.
Prior to iOS 3.2 the events used to fire whenever you changed fields. The new way is arguably more correct, but it does make what you are trying to do a bit more challenging.
You might be better off implementing the delegate for the text fields, then you can check for the shouldBeginEditing/didEndEditing events, or alternatively, you could subclass UITextField and override the becomeFirstResponder/resignFirstResponder methods so that you can hook into them and implement your logic when the fields receive and lose focus.
I think you are trying to change the keyboard types when you are on a particular text field. Instead of tracing it the way your doing simply use the two methods,
- (void)textFieldDidBeginEditing:(UITextField *)textField;
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
The first method is called whenever you touch a textfield for editing.
Here you can write you keyboard changing code
EG: If textfield is of type 1
set Keyboard Type to alphanumeric.
Else if textfield is of type 2
set Keyboard Type to numeric only.
Then the second method is called whenever you press the RETURN key on the onscreen keyboard.
Here you can write the [textfield resignFirstResponder] statement for any incoming textfield control.
Hope this helps.. :) cheers!
When the keyboard appears, the method is called by notificationCenter.
If it's not working set the object to nil.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:self.view.window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:self.view.window];

UIWebView Keyboard - Getting rid of the "Previous/Next/Done" bar

I want to get rid of the bar on top of the keyboard that appears when you focus a text field in a webview. We have some other ways of handling this and it's redundant and unnecessary.
webview keyboard bar http://beautifulpixel.com/assets/iPhone_Simulator-20100120-152330.png
If you hit this problem, make sure to head over to https://bugreport.apple.com and duplicate rdar://9844216
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification {
[self performSelector:#selector(removeBar) withObject:nil afterDelay:0];
}
- (void)removeBar {
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
for (UIView *possibleFormView in [keyboardWindow subviews]) {
// iOS 5 sticks the UIWebFormView inside a UIPeripheralHostView.
if ([[possibleFormView description] rangeOfString:#"UIPeripheralHostView"].location != NSNotFound) {
for (UIView *subviewWhichIsPossibleFormView in [possibleFormView subviews]) {
if ([[subviewWhichIsPossibleFormView description] rangeOfString:#"UIWebFormAccessory"].location != NSNotFound) {
[subviewWhichIsPossibleFormView removeFromSuperview];
}
}
}
}
}
This works well.
url: http://ios-blog.co.uk/iphone-development-tutorials/rich-text-editor-inserting-images-part-6/
This is an addition to Yun's answer. On iOS6 (6.0.1) there might be a horizontal grey border or shadow line on top of the row where the accessory (previous / next / done) used to be before it was removed. This fix works for me, and I'd like to share. Curious to hear if it works for you as well.
To remove the border, I added this code to the inner loop of removeBar():
if ([[subviewWhichIsPossibleFormView description] rangeOfString:#"UIImageView"].location != NSNotFound) {
[[subviewWhichIsPossibleFormView layer] setOpacity: 0.0];
}
We need to add the QuartzCore framework to the head of the .m file, so we can set the opacity of the layer involved.
So, we get:
...
#import <QuartzCore/QuartzCore.h>
...
- (void)removeBar {
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
for (UIView *possibleFormView in [keyboardWindow subviews]) {
// iOS 5 sticks the UIWebFormView inside a UIPeripheralHostView.
if ([[possibleFormView description] rangeOfString:#"UIPeripheralHostView"].location != NSNotFound) {
for (UIView *subviewWhichIsPossibleFormView in [possibleFormView subviews]) {
if ([[subviewWhichIsPossibleFormView description] rangeOfString:#"UIWebFormAccessory"].location != NSNotFound) {
[subviewWhichIsPossibleFormView removeFromSuperview];
}
// iOS 6 leaves a grey border / shadow above the hidden accessory row
if ([[subviewWhichIsPossibleFormView description] rangeOfString:#"UIImageView"].location != NSNotFound) {
// we need to add the QuartzCore framework for the next line
[[subviewWhichIsPossibleFormView layer] setOpacity: 0.0];
}
}
}
}
}
It looks like there is a very simple way, but I'm pretty sure it will not pass the App Store review. Maybe someone has a clever idea? ;)
#interface UIWebBrowserView : UIView
#end
#interface UIWebBrowserView (UIWebBrowserView_Additions)
#end
#implementation UIWebBrowserView (UIWebBrowserView_Additions)
- (id)inputAccessoryView {
return nil;
}
#end
There are no public APIs for doing this. You could remove it by examining the view hierarchy and removing the view as some have suggested, but this would be very risky.
Here's why it's a bad idea:
If Apple doesn't have an official API for removing the bar, they may have good reasons for doing so, and their own code may rely on it being there. You might not ever encounter a problem because you do all your testing (for example) on an English keyboard. But what if the view you are removing is required for entry in another language, or for accessibility purposes? Or what if in a future version of iOS their own implementation changes such that it assumes the view is always there? Your code will crash, and you'll be stuck scrambling to get an update out while frustrated users wait for weeks.
Interestingly, Remco's appended answer proves this point. On iOS 6.0.1, a change was made that required a fix to the hack. Anyone who had implemented the hack for ios 5 would have been forced to do an update as a result. Fortunately it was only an aesthetic change, but it could have been much worse.
I was thinking of intercepting the UIKeyboardWillAppear notification, and giving it to a hidden text field instead, and forwarding the events through javascript to the real one in the webview. But it seems hairy. Things cursor movement and selection would then suck.
check out this one. https://gist.github.com/2048571.
It works in iOS 5 and later, doesnt work for earlier versions.
this code definetly works for me... hope this also works for you.
- (void)viewDidLoad{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
-(void)viewWillAppear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification {
[self performSelector:#selector(removeBar) withObject:nil afterDelay:0];
}
- (void)removeBar {
// Locate non-UIWindow.
UIWindow *keyboardWindow = nil;
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
if (![[testWindow class] isEqual:[UIWindow class]]) {
keyboardWindow = testWindow;
break;
}
}
// Locate UIWebFormView
for (UIView *possibleFormView in [keyboardWindow subviews]) {
if ([[possibleFormView description] hasPrefix:#"<UIPeripheralHostView"]) {
for (UIView* peripheralView in [possibleFormView subviews]) {
// hides the backdrop (iOS 7)
if ([[peripheralView description] hasPrefix:#"<UIKBInputBackdropView"]) {
//skip the keyboard background....hide only the toolbar background
if ([peripheralView frame].origin.y == 0){
[[peripheralView layer] setOpacity:0.0];
}
}
// hides the accessory bar
if ([[peripheralView description] hasPrefix:#"<UIWebFormAccessory"]) {
// remove the extra scroll space for the form accessory bar
UIScrollView *webScroll;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) {
webScroll = [[self webviewpot] scrollView];
} else {
webScroll = [[[self webviewpot] subviews] lastObject];
}
CGRect newFrame = webScroll.frame;
newFrame.size.height += peripheralView.frame.size.height;
webScroll.frame = newFrame;
// remove the form accessory bar
[peripheralView removeFromSuperview];
}
// hides the thin grey line used to adorn the bar (iOS 6)
if ([[peripheralView description] hasPrefix:#"<UIImageView"]) {
[[peripheralView layer] setOpacity:0.0];
}
}
}
}
}
Not easily. You could try to go poking around the subviews in the web view but it would be taboo with Apple.
How about not putting the text field in the web page on the web side, and adding your textfield/textview to the webview explicitly so it doesn't show the nav bar at all, and you can add your own from scratch?
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
-(void)keyboardWasShown:(NSNotification*)aNotification
{
UIWindow* tempWindow;
//Because we cant get access to the UIKeyboard throught the SDK we will just use UIView.
//UIKeyboard is a subclass of UIView anyways
UIView* keyboard;
//Check each window in our application
for(int c = 0; c < [[[UIApplication sharedApplication] windows] count]; c ++)
{
//Get a reference of the current window
tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:c];
//Get a reference of the current view
for(int i = 0; i < [tempWindow.subviews count]; i++)
{
keyboard = [tempWindow.subviews objectAtIndex:i];
if([[keyboard description] hasPrefix:#"<UIPeripheralHostView"] == YES)
{
keyboard.hidden = YES;
UIView* keyboardLayer;
for(int n = 0; n < [keyboard.subviews count]; n++)
{
keyboardLayer = [keyboard.subviews objectAtIndex:n];
NSLog(#" keyboardLayer ::: %# " ,keyboardLayer);
if([[keyboardLayer description] hasPrefix:#"<UIWebFormAccessory"] == YES)
{
[keyboardLayer removeFromSuperview ];
}
}
keyboard.hidden = NO;
}
}
}
NSLog(#"keyboardWasShown" );
}
check this as well: http://pastebin.com/s3Fkxvsk