Long Tap Selection Doesn't Trigger Selection (also Selection Handles) in iOS
Is there an existing issue for this?
- [X] I have searched the existing issues
Flutter Quill version
10.8.5, also 11.0.0-dev.13
Steps to reproduce
Build a basic QuillEditor. Then build it on iOS, double tap to select works good, also triggers handles. But long tap to select will only show magnifier and copy, select all options after you end selecting. Same behavior in iPad. Mouse selection works good on iPad.
This is how my QuillEditor looks like:
final json = jsonDecode(widget.data) as Json;
final ops = (json['ops'] as List<dynamic>).map((e) => e as Json).toList();
final operations =
ops.map(Operation.fromJson).map(QuillUtils.mapColor).toList();
_controller = QuillController(
document: Document.fromDelta(Delta.fromOperations(operations)),
selection: const TextSelection.collapsed(offset: 0),
readOnly: true,
);
DefaultTextStyle(
style: GlobalUIData.defaultStyle!.copyWith(color: widget.textColor),
child: QuillEditor(
focusNode: FocusNode(),
controller: _controller!,
scrollController: ScrollController(),
config: QuillEditorConfig(
textSelectionControls: materialTextSelectionControls,
textSelectionThemeData: TextSelectionThemeData(
cursorColor: textSelectionTheme2.cursorColor,
selectionColor: textSelectionTheme2.selectionColor,
selectionHandleColor: textSelectionTheme2.selectionHandleColor,
),
enableInteractiveSelection: true,
showCursor: false,
autoFocus: false,
embedBuilders: [
CustomFormulaEmbedBuilder(widget.textColor),
CustomImageEmbedBuilder(onImageTap: widget.onImageTap),
VideoEmbedBuilder(onVideoInit: null),
CodeHighlightingEmbedBuilder(),
],
expands: false,
),
),
)
Expected results
Everything is good on Android.
https://github.com/user-attachments/assets/b6b854e0-9270-4d8b-a7c1-ee22c12166e3
Actual results
I double tap at 00:15
https://github.com/user-attachments/assets/be697a83-705a-44c3-be2a-17f55ed6936b
Additional Context
When I long tap to select, it selects the text as collapsed
TextSelection.collapsed(offset: 244, affinity: TextAffinity.upstream, isDirectional: false)
Can you confirm if this issue exists on older versions (before the magnifier feature #2026)?
flutter_quill: 9.5.23
As I checked the code, this is because when device is iOS the library coded to not select in range when long tapped. It just pops up magnifier. But at the end of selection, it asks to copy or select all. Which doesn't seem like a good flow.
I checked Cupertino behavior in other iOS apps. Long tap to select shows magnifier and also select the text in range.
lib/src/editor/editor.dart:
@override
void onSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) {
if (_state.configurations.onSingleLongTapMoveUpdate != null) {
if (renderEditor != null &&
_state.configurations.onSingleLongTapMoveUpdate!(
details,
renderEditor!.getPositionForOffset,
)) {
return;
}
}
if (!delegate.selectionEnabled) {
return;
}
// bool get isCupertino => {TargetPlatform.iOS, TargetPlatform.macOS}.contains(platform);
if (Theme.of(_state.context).isCupertino) { // <== When device is iOS, this can not be changed.
renderEditor!.selectPositionAt(
from: details.globalPosition,
cause: SelectionChangedCause.longPress,
);
} else {
renderEditor!.selectWordsInRange(
details.globalPosition - details.offsetFromOrigin,
details.globalPosition,
SelectionChangedCause.longPress,
);
}
editor?.updateMagnifier(details.globalPosition);
}
A solution may be adding a parameter to decide the long tap select whether ranged or collapsed. Or maybe whatever the better for Cupertino behavior.
Can you confirm if this issue exists on older versions (before the magnifier feature #2026)?
flutter_quill: 9.5.23
My project is not compatible with older intl. So I couldn't directly test it. But it seems like the problem still was there on that version. Because it still selects position on long tap if it is iOS. Instead, i think it should select range. Am I wrong?
@override
void onSingleLongTapStart(LongPressStartDetails details) {
if (_state.configurations.onSingleLongTapStart != null) {
if (renderEditor != null &&
_state.configurations.onSingleLongTapStart!(
details,
renderEditor!.getPositionForOffset,
)) {
return;
}
}
if (delegate.selectionEnabled) {
if (Theme.of(_state.context).isCupertino) {
renderEditor!.selectPositionAt(
from: details.globalPosition,
cause: SelectionChangedCause.longPress,
);
} else {
renderEditor!.selectWord(SelectionChangedCause.longPress);
Feedback.forLongPress(_state.context);
}
}
_showMagnifierIfSupported(details.globalPosition);
}```
if (Theme.of(_state.context).isCupertino)
I'm not sure about this check either, it seems this is a platform-specific check that allows the use of Theme which allows overriding the platform, leading to broken behavior, it probably should use isIOSApp instead which will be only true if running on an iOS mobile app (not browser or other platforms that uses Cupertino). I didn't change it to avoid regressions.
My project is not compatible with older intl. So I couldn't directly test it.
dependency_overrides:
flutter_quill: 9.5.23
Or try the example with version 9.4.0:
$ git clone --depth 1 --branch v9.4.0 https://github.com/singerdmx/flutter-quill.git
$ (cd flutter-quill/example && flutter run)
If you confirm this is not an issue on older versions, we will have enough regressions to revert the magnifier feature in v11 (breaking change). We're still discussing this change though.
I can confirm it was already not working on 9.5.23.
flutter_quill:
dependency: "direct overridden"
description:
name: flutter_quill
sha256: dbbe4190e6fdf6d4225ae89ae53f3dfe4e6d813c813889ac427b44131e8a0c71
url: "https://pub.dev"
source: hosted
version: "9.5.23"
Related issues have been fixed in 11.0.0-dev.20. @ataberkw Could you confirm if this version fixed the encountered issue?
+1 same bug
Could you try with the latest pre-release once again?
I’m experiencing the same issue. I tested it on 11.0.0-dev.21, but it doesn’t seem to be fixed yet.
The issue still occurs. v11.0.0
@EchoEllet I also tested with v11.0.0, but the issue still persists.
The issue still occurs on latest version.