I am creating a chat UI interface in Nativescript and I almost have everything working, but I am having a few issues in iOS that I cannot figure out. Everything in Android works correctly.
Problem 1:
Problem 2:
Here is a demo project I created on Playground that shows the problem. Playground Demo Project
Below is a GIF showing both of the issues.
Any help is appreciated. Thanks!
Problem 1:
This is because IQKeyboardManager hosts a ScrollView on top of the ViewController (Page) and RadListView has its own scrollable region. The solution would be adjusting the insets when keyboard is active.
The code below takes keyboard height and caches it in application object when its first shown.
import * as application from "@nativescript/core/application";
let observer = application.ios.addNotificationObserver(
UIKeyboardDidShowNotification,
notification => {
application.ios.removeNotificationObserver(
observer,
UIKeyboardDidShowNotification
);
(application as any)._keyboardHeight = notification.userInfo.valueForKey(
UIKeyboardFrameBeginUserInfoKey
).CGRectValue.size.height;
}
);
When text field is focused adjust the insets of list view
textFieldFocus() {
console.log("Focus on TextField");
(this
.radList as any)._originalContentInset = this.radList.ios.contentInset;
if ((application as any)._keyboardHeight) {
this.radList.ios.contentInset = UIEdgeInsetsMake(
(application as any)._keyboardHeight,
0,
0,
0
);
} else {
setTimeout(() => this.textFieldFocus(), 100);
}
}
Problem 2:
This is because the text view layouts itself when text is updated. Preventing that may keep the scroll position intact. The override below checks if the field is focused and ignores layout calls.
import { TextView } from "@nativescript/core/ui/text-view";
TextView.prototype.requestLayout = function() {
if (
!arguments[0] &&
this.nativeViewProtected &&
this.nativeViewProtected.isFirstResponder
) {
this.nativeViewProtected.setNeedsLayout();
IQKeyboardManager.sharedManager().reloadLayoutIfNeeded();
} else {
View.prototype.requestLayout.call(this);
}
};