Forum Xamarin.Forms

Add 'Done' button to keyboard on iOS

How does one add a 'Done' button to a keyboard when editing an Entry on Xamarin.Forms? (iOS only)

I'm not sure how to write a renderer for this and wire that to a Keyboard on Xamarin.Forms.

image

Posts

  • rogiheerogihee NLMember ✭✭✭
    edited June 2014

    This should be it, assuming that all Entry elements now get this keyboard (as I think MonoTouch.Dialog does by default):

    [assembly: ExportRenderer(typeof(Entry), typeof(DoneEntryRenderer))]
    namespace MyProject.iOS.Renderers
    {
        public class DoneEntryRenderer : EntryRenderer
        {
            protected override void OnModelSet(VisualElement model)
            {
                base.OnModelSet(model);
                var textField = (UITextField)this.Control;
                textField.ReturnKeyType = UIReturnKeyType.Done;
            }
        }
    }
    
  • rene_ruppertrene_ruppert DEXamarin Team, University, XamUProfessors Xamurai

    I think that's not exactly what he was looking for. Instead, try setting the InputAccessoryView property of the UITextField to a UIView that contains the widgets you need.

  • PedroLimaPedroLima US ✭✭
    edited June 2014

    Thanks much René, that's what I was looking for. With your hint and the following article I was able to implement what I needed ;-)

    http://nnish.com/2013/12/02/adding-custom-buttons-to-ios-keyboard-in-c-xamarin/

  • PaulDivanPaulDivan USMember ✭✭

    Pedro, Can you share the code you used to add the InputAccessoryView to an Xamarin.Forms.Edit control? I have like 50 fields on my various pages and I want to automatically add the InputAccessoryView to each of them, including a picker view if possible.

    Thanks

  • PedroLimaPedroLima US ✭✭

    I can't share the exact code I'm using as that code is actually my client's code, but here is the idea:

    Have a new Entry that extends Xamarin.Forms' Entry, like class MyEntry : Entry and create a custom renderer for it that extends EntryRenderer, like class MyEntryRenderer : EntryRenderer and on the OnElementChanged method you can set this.Control.InputAccessoryView to any UIView. You can follow this link to create an appropriate UIToolbar to set it here.

    Then in your app just reference MyEntry instead of Entry and if the renderer is implemented correctly you'll see that the InputAccessoryView appears.

    [assembly: ExportRenderer(typeof(MyEntry), typeof(MyEntryRenderer))]
    namespace MyProject.iOS.Renderers
    {
        public class MyEntryRenderer : EntryRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs<Entry> args) {
            {
                base.OnElementChanged(args);
                this.Control.InputAccessoryView = (...) ; // do your magic here
            }
        }
    }
    
  • PaulDivanPaulDivan USMember ✭✭

    Thanks with this and about 4 other posts I was able to get a custom view with the close button (and a bunch of other fun buttons that I'm going to remove) working with Xamarin.Forms

  • With the information on this post, I was able to get this working in iOS, but I need to be able to replicate this functionality on Android. Can this be done in a similar fashion for Android by modifying the Renderer?

    Thanks,
    Doug

  • VinayKumar.9706VinayKumar.9706 USMember

    public EntryDoneRenderer ()
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged (e);
    
        if (this.Element.Keyboard == Keyboard.Numeric) 
        {
            // only want the Done on the numeric keyboard type
            UIToolbar toolbar = new UIToolbar (new RectangleF (0.0f, 0.0f, (float)Control.Frame.Size.Width, 44.0f));
    
            var doneButton = new UIBarButtonItem (UIBarButtonSystemItem.Done, delegate {
                this.Control.ResignFirstResponder ();
                Type baseEntry = this.Element.GetType();
                if(baseEntrySendCompleted==null)
                    // use reflection to find our method
                    baseEntrySendCompleted = baseEntry.GetMethod("SendCompleted",BindingFlags.NonPublic|BindingFlags.Instance);
                    baseEntrySendCompleted.Invoke(this.Element,null);            });
    
            toolbar.Items = new UIBarButtonItem[] {  new UIBarButtonItem (UIBarButtonSystemItem.FlexibleSpace),doneButton   };
            this.Control.InputAccessoryView = toolbar;
        }
    }
    

    }

  • AdrianKnightAdrianKnight USMember ✭✭✭✭

    @VinayKumar.9706 I'm getting null for the SendCompleted event. It used to work but not anymore.

  • rocharocharocharocha USMember ✭✭

    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
    base.OnElementChanged(e);

        var toolbar = new UIToolbar(new CGRect(0.0f, 0.0f, Control.Frame.Size.Width, 44.0f));
    
        toolbar.Items = new[]
        {
            new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace),
            new UIBarButtonItem(UIBarButtonSystemItem.Done, delegate {
                Control.ResignFirstResponder();
                ((IEntryController)Element).SendCompleted();
            })
        };
    
        this.Control.InputAccessoryView = toolbar;
    }
    
  • NMackayNMackay GBInsider, University mod

    @rocharocha

    Wasn't working in iOS 10 for me, thanks for posting that code.

  • gruan.0990gruan.0990 USMember ✭✭

    https://github.com/gruan01/XFControls/blob/master/XFControls/Src/AsNum.XFControls/Effects/KeyboardEnter.cs
    https://github.com/gruan01/XFControls/blob/master/XFControls/Src/AsNum.XFControls.iOS/Effects/KeyboardEnterEffect.cs
    https://github.com/gruan01/XFControls/blob/master/XFControls/Src/AsNum.Control.Droid/Effects/KeyboardEnterEffect.cs

              <Entry Grid.Column="1"
                     x:Name="keyword"
                     Margin="0"
                     Placeholder="请输入商品名称"
                     effects:KeyboardEnter.Type="Search"
                     effects:KeyboardEnter.Cmd="{Binding SearchCmd}"
                     effects:KeyboardEnter.Param="{Binding Text, Source={x:Reference keyword}}"
                     />
    
  • AdrianKnightAdrianKnight USMember ✭✭✭✭
  • JohnHardmanJohnHardman GBUniversity mod

    Has anybody done the equivalent on UWP, to provide a Done button on UWP phones?

Sign In or Register to comment.