2013-11-16

Done button on iOS NumberPad with Xamarin

There are a ton of potential solutions on the Internet for adding a Done button to a NumberPad-type of UITextField on iOS.  Unfortunately most of them are old, use custom images or even require iterating through sub views to find the target keyboard.

Below is a solution -- using Xamarin -- to add a Done button without fear of index-out-of-bound exceptions or using out-dated custom images. The trick is using the WeakInputDelegate of the UITextField & adding a custom button to that.
A full working project is available on github.


  public override void ViewDidLoad ()
  {
   base.ViewDidLoad ();

   // Your stuff

   NSNotificationCenter.DefaultCenter.AddObserver ("UIKeyboardWillShowNotification", KeyboardWillShow);
  }

  public void KeyboardWillShow(NSNotification notification)
  {
   var doneButton = new UIButton (UIButtonType.Custom);
   doneButton.Frame = new RectangleF (0, 163, 106, 53);
   doneButton.SetTitle ("DONE", UIControlState.Normal);
   doneButton.SetTitleColor (UIColor.Black, UIControlState.Normal);
   doneButton.SetTitleColor (UIColor.White, UIControlState.Highlighted);

   doneButton.TouchUpInside += (sender, e) => 
   {
    // Make the Done button do its thing!  The textfield shouldn't be the first responder
    _txtNumbers.ResignFirstResponder();
   };

   // This is the 'magic' that could change with future version of iOS
   var keyboard = _txtNumbers.WeakInputDelegate as UIView;
   if (keyboard != null)
   {
    keyboard.AddSubview (doneButton);
   }
  }

EDIT 2013-11-18: Bug Fix

I modified the example on github to have another UITextField and to hide the done button whenever another keyboard is visible

3 comments:

Bindu Prasad said...

Thanks, works perfect!

Nour El-Dien said...
This comment has been removed by the author.
Noureldien Hussein said...

Hi,
Thanks for the code, it's a very helpful code snippet. One more step to make it perfect is to remove the done button after you resign the textField from being First Repsonder, i.e after this line: _txtNumbers.ResignFirstResponder();

Removing done button is important or it will stay on the keyboad as long as the app is alive. For example, it will appear on the full keyboard if opened. So, please add this line of code (in the TouchUpInside Event Handler):

// remove done button from the keyboard
doneButton.RemoveFromSuperview();