Closed nekzabirov closed 1 year ago
This is necessary to correctly display the element in focus. For example, TextField. If the focusable element is in focus and will be covered by the keyboard, then the Compose View will move to keep the element visible.
For now, this behaviour is not configurable.
@mykytaknyzevkiy Do you have some bugs with this behaviour? Can you please provide info on why you need another behaviour?
@dima-avdeev-jb. I do like to use native IOS UITextField in my Compose view. cause Compose TextField has a lot of bugs.
I found a solution to my problem.
internal val currentRootViewController by lazy {
ComposeRootController()
}
internal var onKeyboardOpen: ((Boolean) -> Unit)? = null
fun getRootController() = currentRootViewController
class ComposeRootController internal constructor(): UIViewController(null, null) {
private val keyboardVisibilityListener = object : NSObject() {
@Suppress("unused")
@ObjCAction
fun keyboardWillShow(arg: NSNotification) {
val (width, height) = getViewFrameSize()
view.setClipsToBounds(true)
composeView.layer.setBounds(
CGRectMake(
x = 0.0,
y = 0.0,
width = width.toDouble(),
height = height.toDouble()
)
)
onKeyboardOpen?.invoke(true)
}
@Suppress("unused")
@ObjCAction
fun keyboardWillHide(arg: NSNotification) {
val (width, height) = getViewFrameSize()
view.layer.setBounds(CGRectMake(0.0, 0.0, width.toDouble(), height.toDouble()))
onKeyboardOpen?.invoke(false)
}
@Suppress("unused")
@ObjCAction
fun keyboardDidHide(arg: NSNotification) {
view.setClipsToBounds(false)
onKeyboardOpen?.invoke(false)
}
}
private val composeView = Application(title = "Nek") {
App()
}.view
override fun viewDidLoad() {
super.viewDidLoad()
this.view.addSubview(composeView)
}
private fun getViewFrameSize(): IntSize {
val (width, height) = view.frame().useContents { this.size.width to this.size.height }
return IntSize(width.toInt(), height.toInt())
}
override fun viewDidAppear(animated: Boolean) {
super.viewDidAppear(animated)
NSNotificationCenter.defaultCenter.addObserver(
observer = keyboardVisibilityListener,
selector = NSSelectorFromString("keyboardWillShow:"),
name = UIKeyboardWillShowNotification,
`object` = null
)
NSNotificationCenter.defaultCenter.addObserver(
observer = keyboardVisibilityListener,
selector = NSSelectorFromString("keyboardWillHide:"),
name = UIKeyboardWillHideNotification,
`object` = null
)
}
}
The solution provided by @nekzabirov does work. Specifically, after Compose-iOS pans the y upward, we immediately set it back to zero, effectively disabling the built in behavior provide by Compose iOS here:
However, sometimes I was seeing a little janky animation from the offset back to 0.0. I was able to fix that by also adding view.layer.removeAllAnimations()
when updating the layer bounds.
@dima-avdeev-jb FYI, even with this hacky workaround, Compose iOS does still know how to scroll to the correct view to keep it visible! I was pleasantly surprised that it works exactly as expected now.
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
While the keyboard show my screen move up
How to disable it ?