How can we set the inputAccessoryView on a keyboard launched from a TextFiled?

ios

#1

I’m trying to add my own custom inputAccessoryView to the top of the keyboard. The view would hold a label, its text value would update via a binding between it and the TextFiled, which updates by default as the user types. There’d also be a clear text button, so the user can quickly clear the input value.

I’m looking at doing this so I don’t need to concern myself with manipulating the UI for the TextFiled (so users can see it while keyboard showing). Which is currently what I’m doing.

I’ve already managed to remove the autocorrectionType accessory view in the TextFields loaded event with view.ios.autocorrectionType = UITextAutocorrectionTypeNo.

And I have a keyboardObserver set up to capture the keyboard UI height on UIKeyboardWillChangeFrameNotification. That’s what I’m using to reposition the TextField so users can still see it.

So when it comes to implementing my own input accessory view, if this something I can handle in the TextFields loaded event, the keyboardObserver, or somewhere else?


#2

Trying to directly assign with view.ios.inputAccessoryVeiw = CGRectMake(0,0,320,45); just freezes the app. And the same thing happens if I try to set a nativescript view (i.e. Label).


#3

Of course it may even crash, inputaccessoryview expects a UIView, but CGRectMake will return a frame. Also Label !== UILabel or UIView, besides native view for any UI component will never be created until it’s added to a parent container.

You will have to create UIVIew instance natively, or understand the architecture of {N} view system and initiate necessary calls to create View / Label without adding it to a parent container, then assign it’s native view to inputaccessoryview.


#4

The view I’m referring to here is a TextField.

  • view.ios is supposed to return the native UITextField for that component, right?

  • view.createNativeView() is returning undefined

  • view.nativeView returns <UITextFieldImpl: 0x1674b3f0; baseClass = UITextField; frame = (1 1; 237 45); text = ''; opaque = NO; tintColor = UIExtendedSRGBColorSpace 1 0.988235 0.988235 1; gestureRecognizers = <NSArray: 0x166091c0>; layer = <CALayer: 0x1674ba00>>


#5

You will not usually call createNativeView that is handled internally but only when it’s parent is also a NativeScript View hierarchy. There are other few methods you have to call if it’s not one, you will get to know what they are if you go through the base View class. I don’t know them exactly as they are changed in 4.0 but should be easy to identify if you refer the source code.

Once you find that, you can easily assign the native view to inputAccessoryVeiw.


#6

I’v gat the inputAccessoryView up and running (at the most basic level).

const view = UITextView.alloc().initWithFrame(CGRectMake(0, 0, 0, 45));
text_field.ios.inputAccessoryView = view;

Still need to workout how to;

  • customise styling (i.e. fontSize, backgroundColor etc…)
  • create a binding between the text_field.text and view.text

You can set the text with view.text = "Something", but not sure how to initiate a binding relationship.

//When you create a {N} `Label` or similar you can use
Label.bind({sourceProperty, targetPropert})

But in a native context this returns view.bind is not a function.

Maybe I can tap into the keypress events of the keyboard and update view.text from that. Though ATM I think a binding would be the best/neatest solution.


#7

:white_check_mark: Styling

After you assign the view to the responders inputAccessoryView you can set font size, text color, and background color like so;

text_field.ios.inputAccessoryView.font = UIFont.systemFontOfSize(18);
text_field.ios.inputAccessoryView.textColor = UIColor.whiteColor;
text_field.ios.inputAccessoryView.backgroundColor = 
    UIColor.colorWithRedGreenBlueAlpha(
      250/255, 
      126/255, 
      130/255, 
      1
);

There are some other styles I still can’t get to work, like boderColor and centering the text vertically. I can apply the borderWidth with view.layer.borderWidth = 1, but color either does nothing or results in the border disappearing. Best I’ve come up with for vertically centering the text is to play with the frame height and font size until it looks right. But if text is longer than view is wide, causing text to wrap it will be cut off. As in frame height does not adjust.

Still no progress with text binding. Going to start on that now.


#8

:white_check_mark: Binding

Ok, I already had an Observer being set up in onNavigatedTo that was watching for the text_field.text value to change (It then passes the new value over to a function that filters out non-matching items).

So now I also pass in the text_field (which I get by ID), and before returning the new value to the filter function I directly update the text_field.ios.inputAccessoryView.text = new_value.

This is obviously all iOS only ATM, but will end up supporting both platforms.


#9

Try this, cross platform and possibly you still have access to features like binding, events, etc.,