Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed appearing of text editing menu in iOS textfields by every tap #1293

Merged
merged 1 commit into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ private fun getTapHandlerModifier(
textLayoutResult = layoutResult,
editProcessor = currentState.processor,
offsetMapping = currentOffsetMapping,
showContextMenu = {
// it shouldn't be selection, but this is a way to call context menu in BasicTextField
currentManager.enterSelectionMode(true)
showContextMenu = { show ->
// it shouldn't be selection, but this is a way to call a context menu in BasicTextField
if (show) { currentManager.enterSelectionMode() } else { currentManager.exitSelectionMode() }
},
onValueChange = currentState.onValueChange
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package androidx.compose.foundation.text

import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.EditProcessor
import androidx.compose.ui.text.input.OffsetMapping
Expand All @@ -40,24 +39,23 @@ internal fun TextFieldDelegate.Companion.cupertinoSetCursorOffsetFocused(
textLayoutResult: TextLayoutResultProxy,
editProcessor: EditProcessor,
offsetMapping: OffsetMapping,
showContextMenu: (Rect) -> Unit,
showContextMenu: (Boolean) -> Unit,
onValueChange: (TextFieldValue) -> Unit
) {
val offset =
offsetMapping.transformedToOriginal(textLayoutResult.getOffsetForPosition(position))
val currentValue = editProcessor.toTextFieldValue()
val currentText = textLayoutResult.value.layoutInput.text.toString()
val previousOffset = currentValue.selection.start

val cursorDesiredOffset = determineCursorDesiredOffset(
offset,
currentValue,
previousOffset,
textLayoutResult,
currentText
)

if (cursorDesiredOffset == offset) {
showContextMenu(textLayoutResult.value.getCursorRect(offset))
}
showContextMenu(cursorDesiredOffset == offset && cursorDesiredOffset == previousOffset)
onValueChange(
editProcessor.toTextFieldValue().copy(selection = TextRange(cursorDesiredOffset))
)
Expand All @@ -73,22 +71,21 @@ internal fun TextFieldDelegate.Companion.cupertinoSetCursorOffsetFocused(
* - If there’s a punctuation mark before the word, the caret is between the punctuation mark and the word.
* - When you make a single tap on the first half of the word, the caret is placed before this word.
* - If you tap on the left edge of the TextField, the caret is placed before the first word on this line. The same is for the right edge.
* - If you tap at the caret, that is placed in the middle of the word, it will jump to the end of the word.
* - If you tap at the caret placed in the middle of the word, it will jump to the end of the word.
* @param offset The current offset position.
* @param currentValue The current TextFieldValue.
* @param previousOffset The previous offset position (where caret was before incoming tap).
* @param textLayoutResult The TextLayoutResultProxy representing the layout of the text.
* @param currentText The current text in the TextField.
* @return The desired cursor position after evaluating the given parameters.
*/
internal fun determineCursorDesiredOffset(
offset: Int,
currentValue: TextFieldValue,
previousOffset: Int,
textLayoutResult: TextLayoutResultProxy,
currentText: String
): Int {
val previousCaretPosition = currentValue.selection.start
val caretOffsetPosition = when {
offset == previousCaretPosition -> offset
offset == previousOffset -> offset
textLayoutResult.isLeftEdgeTapped(offset) -> {
val lineNumber = textLayoutResult.value.getLineForOffset(offset)
textLayoutResult.value.getLineStart(lineNumber)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class CupertinoTextFieldDelegateTest {
) {
val actual = determineCursorDesiredOffset(
offset = givenOffset,
createSimpleTextFieldValue(text = sampleText, cursorOffset = cursorOffset),
createSimpleTextFieldValue(text = sampleText, cursorOffset = cursorOffset).selection.start,
textLayoutResult = createSimpleTextLayoutResultProxy(sampleText),
currentText = sampleText
)
Expand Down