Сбой React Native TextInput: NSInvalidArgumentException в RCTTextInputComponentView _selectionRangeIOS

Программируем под IOS
Ответить
Anonymous
 Сбой React Native TextInput: NSInvalidArgumentException в RCTTextInputComponentView _selectionRange

Сообщение Anonymous »

Проблема
Мое приложение React Native аварийно завершает работу с NSInvalidArgumentException при переходе между экранами, содержащими компоненты TextInput. Сбой происходит, в частности, при выборе текста в одном TextInput и последующем переходе на другой экран с другим TextInput.
Сведения о сбое:
  • Тип исключения: NSInvalidArgumentException
  • Неустрашимое исключение: Сбой происходит в -[RCTTextInputComponentView _selectionRange]
  • Основная причина: NSTextContentStorage offsetFromLocation:toLocation: с недопустимыми позициями текста
  • React Native Stack: RCTTextInputComponentView _selectionRange → RCTTextInputComponentView _textInputMetrics → updateLayoutMetrics:oldLayoutMetrics:
Этапы воспроизведения
  • Откройте экран с TextInput (с помощью React-native-paper TextInput)
  • Выберите текст в TextInput (клавиатура открыта)
  • Перейдите назад, пока клавиатура неподвижна open
  • Перейти на другой экран, который также имеет TextInput
  • Приложение аварийно завершает работу, когда новый TextInput пытается смонтировать
Stack Trace (из Firebase Crashlytics)

Код: Выделить всё

-[RCTTextInputComponentView _selectionRange]

Fatal Exception: NSInvalidArgumentException

0  CoreFoundation                 0xc98c8 __exceptionPreprocess
1  libobjc.A.dylib                0x317c4 objc_exception_throw
2  CoreFoundation                 0x1548d4 -[NSException initWithCoder:]
3  UIFoundation                   0xb757c -[NSTextContentStorage offsetFromLocation:toLocation:]
4  UIKitCore                      0xe55140 -[_UITextKit2LayoutController offsetFromPosition:toPosition:]
5  UIKitCore                      0x1727ef8 -[UITextInputController offsetFromPosition:toPosition:]
6  UIKitCore                      0x1701d18 -[UIFieldEditor offsetFromPosition:toPosition:]
7  UIKitCore                      0x1714960 -[UITextField offsetFromPosition:toPosition:]
8  [AppName]                      0x218c94 -[RCTTextInputComponentView _selectionRange] + 685 (RCTTextInputComponentView.mm:685)
9  [AppName]                      0x218470 -[RCTTextInputComponentView _textInputMetrics] + 658 (RCTTextInputComponentView.mm:658)
10 [AppName]                      0x2172d8 -[RCTTextInputComponentView updateLayoutMetrics:oldLayoutMetrics:] + 326 (RCTTextInputComponentView.mm:326)
11 [AppName]                      0x1f2e70 -[RCTMountingManager performTransaction:] + 87 (RCTMountingManager.mm:87)
12 [AppName]                      0x53062c facebook::react::TelemetryController::pullTransaction(...) + 40 (TelemetryController.cpp:40)
13 [AppName]                      0x1f1c54 -[RCTMountingManager performTransaction:] + 403 (function.h:403)
14 [AppName]                      0x1f1b54 -[RCTMountingManager initiateTransaction:] + 247 (RCTMountingManager.mm:247)
15 libdispatch.dylib              0x1adc _dispatch_call_block_and_release
16 libdispatch.dylib              0x1b7ec _dispatch_client_callout
17 libdispatch.dylib              0x38b24 _dispatch_main_queue_drain.cold.5
18 libdispatch.dylib              0x10ec8 _dispatch_main_queue_drain
19 libdispatch.dylib              0x10e04 _dispatch_main_queue_callback_4CF
20 CoreFoundation                 0x6b520 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
21 CoreFoundation                 0x1dd14 __CFRunLoopRun
22 CoreFoundation                 0x1cc44 _CFRunLoopRunSpecificWithOptions
23 GraphicsServices               0x1498 GSEventRunModal
24 UIKitCore                      0xa9ddc -[UIApplication _run]
25 UIKitCore                      0x4eb0c UIApplicationMain
Окружающая среда
  • React Native: [ваша версия]
  • react-native-keyboard-controller: 1.19.2 (проблемная версия)
  • react-native-paper: [ваша версия]
  • Платформа: iOS (симулятор и устройство)
Пример кода
Экран 1: FirstScreen.tsx

Код: Выделить всё

import React, { useState } from 'react'
import { TextInput } from 'react-native-paper'
import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'

const FirstScreen = ({ navigation }) =>  {
const [text, setText] = useState('')

return (



)
}
Экран 2: SecondScreen.tsx

Код: Выделить всё

import React, { useState } from 'react'
import { TextInput } from 'react-native-paper'
import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'

const SecondScreen = ({ navigation }) => {
const [input, setInput] = useState('')

return (



)
}
Что я пробовал
  • Отключение клавиатуры перед навигацией не предотвращает сбой.
  • Проблема заключается во внутреннем состоянии выбора TextInput, а не в видимости клавиатуры.
  • Тестирование в старой ветке без контроллера реакции-native-keyboard-controller показало, что проблема не возникла, подтверждая, что она связана с этим package
  • Сбой происходит только тогда, когда текст выбран в первом TextInput (диапазон выбора должен быть активным).
Решение
Обновление response-native-keyboard-controller с версии 1.19.2 до 1.19.5 (или более поздней) устраняет этот сбой.
Проблема заключалась в ошибке в response-native-keyboard-controller версии 1.19.2, которая неправильно обрабатывала очистку состояния выбора TextInput во время переходов навигации. При навигации между экранами с компонентами TextInput, когда выделен текст, предыдущий диапазон выбора TextInput остается в памяти с недопустимыми позициями текста. Когда React Native пытается вычислить метрики макета для нового TextInput, вызывая _selectionRange, он пытается получить доступ к недопустимым позициям текста через NSTextContentStorage offsetFromLocation:toLocation:, что приводит к сбою.
Сбой происходит именно во время цикла обновления макета React Native (

Код: Выделить всё

updateLayoutMetrics:oldLayoutMetrics:
), который запускается как часть транзакции монтирования при отображении нового экрана.
Исправление:

Код: Выделить всё

yarn upgrade react-native-keyboard-controller@^1.19.5
# or
npm update react-native-keyboard-controller@^1.19.5
После обновления сбой больше не происходит. Более новая версия правильно обрабатывает очистку состояния TextInput во время навигации.
Дополнительный контекст
  • Подтвержденная основная причина: Тестирование в старой ветке, в которой не было контроллера реакции-native-keyboard-controller, показало, что проблема не возникла, что подтверждает, что она связана с этим пакетом.
  • Затронутые компоненты: Проблема затрагивает все компоненты TextInput (как TextInput React Native, так и TextInput React-native-paper) при использовании KeyboardAwareScrollView или KeyboardAvoidingView из React-native-keyboard-controller
  • Местоположение сбоя: Сбой происходит в собственном коде React Native (

    Код: Выделить всё

    RCTTextInputComponentView.mm:685
    ) при попытке вычислить показатели диапазона выбора во время обновления макета


Подробнее здесь: https://stackoverflow.com/questions/798 ... utcomponen
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»