I am developing an IOS application. I am using custom Ok button for iPhone number pad. This code work in all IOS version but IOS 8.3 not working.OK button added to keyboard but click event not working.
- (void)updateKeyboardButtonFor:(UITextField *)textField {
// Remove any previous button
[self.numberPadDoneButton removeFromSuperview];
self.numberPadDoneButton = nil;
// Does the text field use a number pad?
if (textField==nil || textField.keyboardType != UIKeyboardTypeNumberPad){
return;
}
// If there's no keyboard yet, don't do anything
if ([[[UIApplication sharedApplication] windows] count] < 2)
return;
UIWindow *keyboardWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
// Create new custom button
self.numberPadDoneButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.numberPadDoneButton.frame = CGRectMake(0, 163, 106, 53);
self.numberPadDoneButton.adjustsImageWhenHighlighted = FALSE;
[self.numberPadDoneButton setImage:self.numberPadDoneImageNormal forState:UIControlStateNormal];
[self.numberPadDoneButton setImage:self.numberPadDoneImageHighlighted forState:UIControlStateHighlighted];
[self.numberPadDoneButton addTarget:self action:#selector(numberPadDoneButton:) forControlEvents:UIControlEventTouchUpInside];
/*
// Locate keyboard view and add button
NSString *keyboardPrefix = [[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2 ? #"<UIPeripheralHost" : #"<UIKeyboard";
for (UIView *subView in keyboardWindow.subviews) {
if ([[subView description] hasPrefix:keyboardPrefix]) {
[subView addSubview:self.numberPadDoneButton];
[self.numberPadDoneButton addTarget:self action:#selector(numberPadDoneButton:) forControlEvents:UIControlEventTouchUpInside];
break;
}
}
*/
UIWindow* tempWindow;
UIView* keyboard;
for (UIWindow *window in [[UIApplication sharedApplication] windows])
{
if ([NSStringFromClass([window class]) isEqualToString:#"UITextEffectsWindow"])
{
tempWindow = window;
break;
}
}
for(int i = 0 ; i < [tempWindow.subviews count] ; i++)
{
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if([[keyboard description] hasPrefix:#"<UIPeripheralHost"] == YES){
[keyboard addSubview:self.numberPadDoneButton];
}
//This code will work on iOS 8.0
else if([[keyboard description] hasPrefix:#"<UIInputSetContainerView"] == YES){
for(int i = 0 ; i < [keyboard.subviews count] ; i++)
{
UIView* hostkeyboard = [keyboard.subviews objectAtIndex:i];
if([[hostkeyboard description] hasPrefix:#"<UIInputSetHost"] == YES){
[hostkeyboard addSubview:self.numberPadDoneButton];
BOOL isPortrait = UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
self.numberPadDoneButton.frame = CGRectMake(((isPortrait) ? 0 : -1),((int) (hostkeyboard.frame.size.height*3)/4) + ((isPortrait) ? 0 : 1),(int) hostkeyboard.frame.size.width/3-1, (isPortrait) ? 60 : 40);
[self.numberPadDoneButton addTarget:self action:#selector(numberPadDoneButton:) forControlEvents:UIControlEventTouchUpInside];
}
}
}
}
}
Ok I am solving this issue all IOS versions also IOS 8.3 FYI
NumpadViewController.h
#import <UIKit/UIKit.h>
#interface NumberPadViewController : BaseViewController {
UIImage *numberPadDoneImageNormal;
UIImage *numberPadDoneImageHighlighted;
UIButton *numberPadDoneButton;
}
#property (nonatomic, retain) UIImage *numberPadDoneImageNormal;
#property (nonatomic, retain) UIImage *numberPadDoneImageHighlighted;
#property (nonatomic, retain) UIButton *numberPadDoneButton;
- (IBAction)numberPadDoneButton:(id)sender;
- (void)doneButtonClick:(id)sender;
#end
NumpadViewController.m
#import "NumpadViewController.h"
#implementation NumberPadViewController
#synthesize numberPadDoneImageNormal;
#synthesize numberPadDoneImageHighlighted;
#synthesize numberPadDoneButton;
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle {
if ((self = [super initWithNibName:nibName bundle:nibBundle]) == nil) {
return nil;
}
if ([Helper isIOS7]) {
self.numberPadDoneImageNormal = [UIImage imageNamed:#"DoneDown7.png"];
self.numberPadDoneImageHighlighted = [UIImage imageNamed:#"DoneUp7.png"];
}else{
self.numberPadDoneImageNormal = [UIImage imageNamed:#"DoneUp.png"];
self.numberPadDoneImageHighlighted = [UIImage imageNamed:#"DoneDown.png"];
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[SVProgressHUD dismiss];
if([Helper isDeviceiPhone]){
// Add listener for keyboard display events
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardDidHideNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
// Add listener for all text fields starting to be edited
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(textFieldDidBeginEditingHandler:)
name:UITextFieldTextDidBeginEditingNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(textFieldDidEndEditingHandler:)
name:UITextFieldTextDidEndEditingNotification
object:nil];
}
}
- (void)viewWillDisappear:(BOOL)animated {
if([Helper isDeviceiPhone]){
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardDidHideNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UITextFieldTextDidBeginEditingNotification
object:nil];
}
if (self.numberPadDoneButton!=nil) {
[self.numberPadDoneButton removeFromSuperview];
}
[super viewWillDisappear:animated];
}
- (UIView *)findFirstResponderUnder:(UIView *)root {
if (root.isFirstResponder)
return root;
for (UIView *subView in root.subviews) {
UIView *firstResponder = [self findFirstResponderUnder:subView];
if (firstResponder != nil)
return firstResponder;
}
return nil;
}
- (UITextField *)findFirstResponderTextField {
UIResponder *firstResponder = [self findFirstResponderUnder:[self.view window]];
if (![firstResponder isKindOfClass:[UITextField class]])
return nil;
return (UITextField *)firstResponder;
}
- (void)textFieldDidBeginEditingHandler:(NSNotification *)note {
[self addButtonToKeyboard:[note object]];
}
- (void)textFieldDidEndEditingHandler:(NSNotification *)note {
[self removedSearchButtonFromKeypad];
}
- (void)keyboardWillShow:(NSNotification *)note {
[self addButtonToKeyboard:[self findFirstResponderTextField]];
}
- (void)keyboardDidShow:(NSNotification *)note {
//[self updateKeyboardButtonFor:[self findFirstResponderTextField]];
[self addButtonToKeyboard:[self findFirstResponderTextField]];
}
- (void)keyboardWillHide:(NSNotification*)note {
[self removedSearchButtonFromKeypad];
}
- (IBAction)numberPadDoneButton:(id)sender {
UITextField *textField = [self findFirstResponderTextField];
[textField resignFirstResponder];
if ( [self respondsToSelector:#selector(doneButtonClick:)] ) {
[self doneButtonClick:textField];
}
}
- (void)doneButtonClick:(id)sender{
}
- (void)dealloc {
[numberPadDoneImageNormal release];
[numberPadDoneImageHighlighted release];
[numberPadDoneButton release];
[super dealloc];
}
- (void)addButtonToKeyboard:(UITextField *)textField
{
[self removedSearchButtonFromKeypad];
if (textField==nil || textField.keyboardType != UIKeyboardTypeNumberPad){
return;
}
// create custom button
self.numberPadDoneButton = [UIButton buttonWithType:UIButtonTypeCustom];
//self.numberPadDoneButton.frame = CGRectMake(0, 163+44, 106, 53);
self.self.numberPadDoneButton.frame = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 53, [[UIScreen mainScreen] bounds].size.width / 3, 53);
self.numberPadDoneButton.adjustsImageWhenHighlighted = NO;
[self.numberPadDoneButton setTag:67123];
[self.numberPadDoneButton setImage:self.numberPadDoneImageNormal forState:UIControlStateNormal];
[self.numberPadDoneButton setImage:self.numberPadDoneImageHighlighted forState:UIControlStateHighlighted];
[self.numberPadDoneButton addTarget:self action:#selector(numberPadDoneButton:) forControlEvents:UIControlEventTouchUpInside];
// locate keyboard view
NSInteger windowCount = [[[UIApplication sharedApplication] windows] count];
if (windowCount < 2) {
return;
}
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIButton* donebtn = (UIButton*)[tempWindow viewWithTag:67123];
if (donebtn == nil)//to avoid adding again and again as per my requirement (previous and next button on keyboard)
[tempWindow addSubview:self.numberPadDoneButton];
}
-(void) removedSearchButtonFromKeypad{
NSInteger windowCount = [[[UIApplication sharedApplication] windows] count];
if (windowCount < 2) {
return;
}
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
for(int i = 0 ; i < [tempWindow.subviews count] ; i++)
{
UIView* keyboard = [tempWindow.subviews objectAtIndex:i];
[self removeButton:keyboard];
}
}
-(void) removeButton:(UIView*)keypadView{
UIButton* donebtn = (UIButton*)[keypadView viewWithTag:67123];
if(donebtn){
[donebtn removeFromSuperview];
donebtn = nil;
}
}
#end
Related
My iPhone has iOS8. I'd like to add DONE button on the UIKeyboardTypeNumberPad. DONE is displayed on the left side empty button. But the selector method doneButtonClicked is not called when I touch(press) DONE. My code is below. What is wrong with the code?
- (void)viewWillAppear:(BOOL)animtated {
// Register the observer for the keyboardWillShow event
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animtated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardWillShow:(NSNotification *)notification {
// create custom button
if (!self.doneButton)
{
self.doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.doneButton addTarget:self action:#selector(doneButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
self.doneButton.adjustsImageWhenHighlighted = NO;
[self.doneButton setTitle:#"DONE" forState:UIControlStateNormal];
[self.doneButton.titleLabel setFont:[UIFont systemFontOfSize:16.0]];
[self.doneButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.doneButton setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
// locate keyboard view
if ([[[UIApplication sharedApplication] windows] count] <= 1) return;
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++)
{
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if ([[keyboard description] hasPrefix:#"<UIPeripheralHost"] == YES)
{
BOOL isPortrait = UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
self.doneButton.frame = CGRectMake(((isPortrait)?0:-1),((int) (keyboard.frame.size.height*3)/4) + ((isPortrait)?0:1),(int) keyboard.frame.size.width/3-1, (isPortrait)?60:40);
[keyboard addSubview:self.doneButton];
}
//This code will work on iOS 8.0
else if([[keyboard description] hasPrefix:#"<UIInputSetContainerView"] == YES)
{
for(int i = 0 ; i < [keyboard.subviews count] ; i++)
{
UIView* hostkeyboard = [keyboard.subviews objectAtIndex:i];
if([[hostkeyboard description] hasPrefix:#"<UIInputSetHost"] == YES)
{
BOOL isPortrait = UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
self.doneButton.frame = CGRectMake(((isPortrait) ? 0 : -1),((int) (hostkeyboard.frame.size.height*3)/4) + ((isPortrait) ? 0 : 1),(int) hostkeyboard.frame.size.width/3-1, (isPortrait) ? 60 : 40);
[hostkeyboard addSubview:self.doneButton];
}
}
}
else{}
}
}
- (void)doneButtonClicked:(id)sender{
[self.heightUpdateTextField resignFirstResponder];
}
Try this out. This method works for me for iOS 6, 7 & 8:
- (void)keyboardWillShow:(NSNotification *)iNotification
// If there's no keyboard yet, don't do anything
if ([[[UIApplication sharedApplication] windows] count] < 2) {
return;
}
UIWindow *keyboardWindow = [[UIApplication sharedApplication] windows][1];
// Create new dismiss keyboard button
UIButton *aDismissKeyboardButton = [UIButton buttonWithType:UIButtonTypeCustom];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.3")) {
aDismissKeyboardButton.frame = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 53, [[UIScreen mainScreen] bounds].size.width / 3, 53);
} else {
aDismissKeyboardButton.frame = CGRectMake(0, 163, 106, 53);
}
aDismissKeyboardButton.adjustsImageWhenHighlighted = FALSE;
[aDismissKeyboardButton setExclusiveTouch:YES];
UIImage *aDismissKeyboardButtonImageNormal;
UIImage *aDismissKeyboardButtonImageHighlighted;
aDismissKeyboardButtonImageNormal = [UIImage imageNamed:#"myImage.png"];
aDismissKeyboardButtonImageHighlighted = [UIImage imageNamed:#"myImageHighLighted.png"];
[aDismissKeyboardButton setImage:aDismissKeyboardButtonImageNormal forState:UIControlStateNormal];
[aDismissKeyboardButton setImage:aDismissKeyboardButtonImageHighlighted forState:UIControlStateHighlighted];
SEL aDoneButtonSelector = NSSelectorFromString(#"doneButtonPressed");
[aDismissKeyboardButton addTarget:iDelegate action:aDoneButtonSelector forControlEvents:UIControlEventTouchUpInside];
// Locate keyboard view and add button
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.3")) {
for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
if ([[window description] hasPrefix:#"<UITextEffectsWindow"]) {
[window addSubview:aDismissKeyboardButton];
return;
}
}
} else if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.0")) {
for (UIView *aSubview in [[keyboardWindow.subviews objectAtIndex:0] subviews]) {
if ([[aSubview description] hasPrefix:#"<UIInputSetHost"]) {
[aSubview addSubview:aDismissKeyboardButton];
return;
}
}
} else {
NSString *keyboardPrefix = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"6.0") ? #"<UIPeripheralHost" : #"<UIKeyboard";
for (UIView *aSubView in keyboardWindow.subviews) {
if ([[aSubView description] hasPrefix:keyboardPrefix]) {
[aSubView addSubview:aDismissKeyboardButton];
return;
}
}
}
}
Here, I have defined a macro to check system version like this:
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
sorry for bad english.
I was copied your code earlier to check, what the mistake, after few changes its working good But the Frame of done Button is deferent tha t you can change according to your desire, let check edited code..
- (void)viewWillAppear:(BOOL)animtated {
// Register the observer for the keyboardWillShow event
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animtated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardWillShow:(NSNotification *)notification {
// create custom button
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
[doneButton addTarget:self action:#selector(doneButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
doneButton.adjustsImageWhenHighlighted = NO;
[doneButton setTitle:#"DONE" forState:UIControlStateNormal];
[doneButton.titleLabel setFont:[UIFont systemFontOfSize:16.0]];
[doneButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[doneButton setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
// locate keyboard view
if ([[[UIApplication sharedApplication] windows] count] <= 1) return;
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++)
{
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if ([[keyboard description] hasPrefix:#"<UIPeripheralHost"] == YES)
{
BOOL isPortrait = UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
doneButton.frame = CGRectMake(((isPortrait)?0:-1),((int) (keyboard.frame.size.height*3)/4) + ((isPortrait)?0:1),(int) keyboard.frame.size.width/3-1, (isPortrait)?60:40);
[keyboard addSubview:doneButton];
}
//This code will work on iOS 8.0
else if([[keyboard description] hasPrefix:#"<UIInputSetContainerView"] == YES)
{
for(int i = 0 ; i < [keyboard.subviews count] ; i++)
{
UIView* hostkeyboard = [keyboard.subviews objectAtIndex:i];
if([[hostkeyboard description] hasPrefix:#"<UIInputSetHost"] == YES)
{
BOOL isPortrait = UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
doneButton.frame = CGRectMake(((isPortrait) ? 0 : -1),((int) (hostkeyboard.frame.size.height*3)/4) + ((isPortrait) ? 0 : 1),(int) hostkeyboard.frame.size.width/3-1, (isPortrait) ? 60 : 40);
[hostkeyboard addSubview:doneButton];
}
}
}
else{}
}
}
- (void)doneButtonClicked:(id)sender{
[self->cityTxt resignFirstResponder]; //cityTxt is my textfield
}
its work for me, hope it works for you also.
I have a message view in which user can see conversation and type & send message. Menu (kind of context menu) is displayed when user long taps on message. I have used TableView and Button for chat history and send message button respectively.
My problem is canPerformAction:withSender method is hit when I tap on Button or TableView. And moreover this code was working fine till iOS 9.0.
#interface MessageDetailViewController ()
- (void)updateDetailView;
- (void)setMessageBar;
- (void)setCallButton;
#end
#implementation MessageDetailViewController
{
}
#synthesize messageField;
#synthesize messageList;
#synthesize messageBarView;
#synthesize navigationBarView;
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"MessageDetailView: viewDidLoad method called.");
// Observe keyboard hide and show notifications to resize the text view appropriately.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didHideEditMenu:) name:UIMenuControllerDidHideMenuNotification object:nil];
[messageField becomeFirstResponder];
messageArray = [[NSMutableArray alloc] init];
typingImage = [[UIImageView alloc] init];
presenceImage = [[UIImageView alloc] init];
navigationBarView = [[UIView alloc] init];
viewHeight = self.view.frame.size.height;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
[messageField setDelegate:self];
messageList.delegate = self;
messageList.dataSource = self;
[self updateDetailView];
[messageList reloadData];
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
/**
* This method is called to send instance method to server.
*/
- (void)onSendMessageButtonPressed:(id)sender
{
if([messageField.text length] == 0)
{
return;
}
messageField.text = [messageField.text substringToIndex:160];
[[DatabaseManager getDatabaseManager] addMessageInDatabase:messageField.text];
[messageField setText:#""];
[self updateDetailView];
[messageList reloadData];
}
-(void)handleLongPress : (UILongPressGestureRecognizer *)gesture
{
TableViewCell *cell = nil;
UIMenuController *menu = [UIMenuController sharedMenuController];
if(gesture.state == UIGestureRecognizerStateBegan)
{
CGPoint p = [gesture locationInView:self.messageList];
NSIndexPath *ip = [self.messageList indexPathForRowAtPoint:p];
rowPosition = ip.row;
NSLog(#"row = %d", ip.row);
if(ip)
{
cell = (TableViewCell *)[messageList cellForRowAtIndexPath:ip];
[self becomeFirstResponder];
[menu setMenuItems:nil];
UIMenuItem *copyMenuItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(#"COPY_MESSAGE", #"") action:#selector(copyMessage:)] autorelease];
UIMenuItem *deleteMenuItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(#"DELETE_MESSAGE", #"") action:#selector(deleteMessage:)] autorelease];
if(cell.imFailIndication.image != nil)
{
UIMenuItem *resendMenuItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(#"RESEND_MESSAGE", #"") action:#selector(resendMessage:)] autorelease];
[menu setMenuItems:[NSArray arrayWithObjects:copyMenuItem, deleteMenuItem, resendMenuItem, nil]];
}
else
{
[menu setMenuItems:[NSArray arrayWithObjects:copyMenuItem, deleteMenuItem, nil]];
}
[menu setTargetRect:cell.frame inView:cell.superview];
[menu setMenuVisible:YES animated:YES];
return;
}
}
}
- (void)copyMessage:(id)sender
{
MessageDetailInfo *detailMessageInfo = [messageArray objectAtIndex:rowPosition];
[UIPasteboard generalPasteboard].string = detailMessageInfo.message;
}
- (void)deleteMessage:(id)sender
{
messageDeleteActionSheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(#"PROMPT_MESSAGE_DELETE_CONFIRMATION", #"") delegate:self cancelButtonTitle:NSLocalizedString(#"CANCEL_BTN_TITLE", #"") destructiveButtonTitle:NSLocalizedString(#"DELETE_BTN_TITLE", #"") otherButtonTitles:nil, nil];
[messageDeleteActionSheet showFromTabBar:self.tabBarController.tabBar];
}
/*
The view implements this method to conditionally enable or disable commands of the editing menu.
The canPerformAction:withSender method is declared by UIResponder.
*/
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
UIMenuController *menu = (UIMenuController *)sender;
switch ([[menu menuItems] count])
{
case 0:
//This case is to display paste option for Message text field.
if(action == #selector(paste:))
{
return YES;
}
break;
case 2:
if(action == #selector(copyMessage:) || action == #selector(deleteMessage:))
{
return YES;
}
break;
case 3:
if(action == #selector(copyMessage:) || action == #selector(deleteMessage:) || action == #selector(resendMessage:))
{
return YES;
}
break;
default:
break;
}
return NO;
}
- (void)keyboardWillShow:(NSNotification *)notification
{
/*
Reduce the size of the text view so that it's not obscured by the keyboard.
Animate the resize so that it's in sync with the appearance of the keyboard.
*/
NSDictionary *userInfo = [notification userInfo];
// Get the origin of the keyboard when it's displayed.
NSValue* aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
// Get the top of the keyboard as the y coordinate of its origin in self's view's coordinate system. The bottom of the text view's frame should align with the top of the keyboard's final position.
CGRect keyboardRect = [aValue CGRectValue];
// Get the duration of the animation.
NSValue *animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration;
[animationDurationValue getValue:&animationDuration];
// Animate the resize of the text view's frame in sync with the keyboard's appearance.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:animationDuration];
/* change position of messageBarView based on visibility of keypadview. */
CGRect messageBarFrame = messageBarView.frame;
messageBarFrame.origin.y = viewHeight - keyboardRect.size.height - messageBarView.frame.size.height;
messageBarView.frame = messageBarFrame;
if(messageBarFrame.origin.y == (viewHeight - keyboardRect.size.height - messageBarView.frame.size.height))
{
[messageField becomeFirstResponder];
}
/* change height of messageList based on visibility of keypadView. */
CGRect messageListFrame = messageList.frame;
messageListFrame.size.height = messageBarView.frame.origin.y;
messageList.frame = messageListFrame;
[UIView commitAnimations];
/* scroll to table view at last message if messages are available. */
if ([messageList numberOfRowsInSection:0])
{
[messageList scrollToRowAtIndexPath:[NSIndexPath indexPathForRow ([messageList numberOfRowsInSection:0] - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
- (void)keyboardWillHide:(NSNotification *)notification
{
NSDictionary* userInfo = [notification userInfo];
/*
Restore the size of the text view (fill self's view).
Animate the resize so that it's in sync with the disappearance of the keyboard.
*/
NSValue *animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration;
[animationDurationValue getValue:&animationDuration];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:animationDuration];
/* change position of messageBarView based on visibility of keypadview. */
CGRect newFrame = messageBarView.frame;
newFrame.origin.y = self.view.frame.size.height - messageBarView.frame.size.height;
messageBarView.frame = newFrame;
/* Don't update tableview if datasource has been set nil. */
if(messageList.dataSource != nil)
{
/* change height of messageList based on visibility of keypadView. */
CGRect messageListFrame = messageList.frame;
messageListFrame.size.height = messageBarView.frame.origin.y;
messageList.frame = messageListFrame;
}
[UIView commitAnimations];
}
- (void)didHideEditMenu:(NSNotification *)notification
{
[[UIMenuController sharedMenuController] setMenuItems:nil];
}
- (void)didReceiveMemoryWarning
{
/* Releases the view if it doesn't have a superview. */
[super didReceiveMemoryWarning];
/* Release any cached data, images, etc that aren't in use. */
}
- (void)viewDidUnload
{
[super viewDidUnload];
/* Release any retained subviews of the main view.
e.g. self.myOutlet = nil; */
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerDidHideMenuNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
messageList.delegate = nil;
messageList.dataSource = nil;
}
-(BOOL)navigationShouldPopOnBackButton
{
NSLog(#"navigationShouldPopOnBackButton appearedFromComposeView = %d", [[NSNumber numberWithBool:appearedFromComposeView] intValue]);
if(appearedFromComposeView)
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
return YES; // Process 'Back' button click and Pop view controler
}
- (void)dealloc
{
[messageField release];
[messageList release];
[messageBarView release]
[messageArray release];
[super dealloc];
}
#end
I am using custom keyboard for webview by hiding the default keyboard. But my code is crashing whenever I tap on inputbox. It says
-[UITextInteractionAssistant containerIsTextField]: message sent to deallocated
After a lot of debugging I found out that [self.view endEditing:YES]; is reposnsible for UITextInteractionAssistant.
Can anyone help in this?
Help in advance!!!
// register for keyboard show event
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
hiding UIWebviewAccessary
-(void)keyboardWillShow:(NSNotification *)note {
[self.view endEditing:YES];
[self removeBar];
[self performSelector:#selector(adjustFrame) withObject:nil afterDelay:0.03];
}
- (void)adjustFrame {
[self.webView stringByEvaluatingJavaScriptFromString:#"window.scroll(0,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]) {
// 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];
}
}
}
}
}
I have a UITextField embedded in a UIScrollView, and I want the text field to scroll up to be visible when the keyboard is active. I tried the top answer in How to make a UITextField move up when keyboard is present? but it seems that it does not work with auto-layout, so instead I took the code from the apple docs. This almost works, but its not scrolling the view until the user actually enters some data, rather than when the keyboard actually appears.
Here's what I'm doing - is there something obviously wrong?
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWillShow:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your application might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, self.activeField.frame.origin) ) {
[self.scrollView scrollRectToVisible:self.activeField.frame animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
[UIView commitAnimations];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
NSLog(#"textFieldDidEndEditing");
self.activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
NSLog(#"textFieldDidEndEditing");
self.activeField = nil;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self registerForKeyboardNotifications];
}
Try this,
ViewController.h
bool keyboardIsShown;
UITapGestureRecognizer *tapGesture;
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
tapGesture.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapGesture];
scrollView.contentSize =CGSizeMake(0, self.view.frame.size.height+50);
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:self.view.window];
keyboardIsShown = NO;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
///// KEYBOARD
- (void) moveView:(float) yPos
{
[scrollView setContentOffset:CGPointMake(0, yPos) animated:YES];
}
- (void)keyboardWillHide:(NSNotification *)n
{
keyboardIsShown = NO;
[self.view removeGestureRecognizer:tapGesture];
[self moveView:0.0];
}
- (void)keyboardWillShow:(NSNotification *)n
{
if (keyboardIsShown)
{
return;
}
keyboardIsShown = YES;
[self.view addGestureRecognizer:tapGesture];
[self moveView:255.0];
}
// method to hide keyboard when user taps on a scrollview
-(void)dismissKeyboard
{
[self.view endEditing:YES];
}
Try the code below:
-(void)keyboardWillShow:(id)sender
{
if ([orientation==#"Landscape"])
[loginScrollView setContentSize:CGSizeMake(480, 620)];
else
[loginScrollView setContentSize:CGSizeMake(320, 670)];
}
and while editing the text use this
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if ([orientation == #"Landscape"]) {
if (textField == usernameTextField)
[loginScrollView setContentOffset:CGPointMake(xValue, 200) animated:YES];
if (textField == passwordTextField)
[loginScrollView setContentOffset:CGPointMake(xValue, 220) animated:YES];
}
else{
if (textField == usernameTextField)
[loginScrollView setContentOffset:CGPointMake(xValue, 168) animated:YES];
if (textField == passwordTextField)
[loginScrollView setContentOffset:CGPointMake(xValue, 172) animated:YES];
}
}
When the UIWebView displays the keyboard, there is a small toolbar at the top (accessory item) that has the buttons "done, previous, next"
Currently, I'm using the following as a workaround to remove this toolbar:
https://gist.github.com/2048571
However, I'm concerned this might not work in future version of iOS. Is there a better way to be doing this?
First, listen keyboard events:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
when keyboard will show,remove the toolbar:
- (void)keyboardWillShow:(NSNotification *)note {
[self performSelector:#selector(removeBar) withObject:nil afterDelay:0];
}
the removeBar is as follows:
- (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 webView] scrollView];
} else {
webScroll = [[[self webView] 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];
}
}
}
}
}
Reference: https://github.com/don/KeyboardToolbarRemover/blob/master/src/ios/KeyboardToolbarRemover.m