Skip to content

Add initial iOS Find in Post support - #609

Open
yunuschoudhurywork-lang wants to merge 6 commits into
wordpress-mobile:trunkfrom
yunuschoudhurywork-lang:add-find-in-post
Open

yunuschoudhurywork-lang wants to merge 6 commits into
wordpress-mobile:trunkfrom
yunuschoudhurywork-lang:add-find-in-post

Conversation

@yunuschoudhurywork-lang

Copy link
Copy Markdown

What?

Adds the initial iOS native Find in Post spike to GutenbergKit by enabling WKWebView's native Find interaction and exposing a presentFindNavigator() method from EditorViewController.

Why?

This is part of the work for WordPress-Android #23222 ("Find in post").

The editor is shared through GutenbergKit, so the Find behavior should be implemented at the GutenbergKit level rather than separately in the host applications.

This spike is intended to verify whether the native WKWebView Find interaction is suitable for Gutenberg's contenteditable editor before proceeding with the Android implementation.

How?

  • Enables WKWebView.isFindInteractionEnabled.
  • Adds presentFindNavigator() to EditorViewController, which presents the native iOS Find navigator.
  • Keeps the implementation limited to the native iOS Find API for this initial feasibility spike.

Testing Instructions

Runtime testing is still pending.

I am developing on Windows and currently do not have access to a macOS/iOS environment to run the GutenbergKit iOS application.

Once an iOS environment is available, verify:

  1. Open a post containing repeated instances of the same text.
  2. Open the native Find navigator.
  3. Search for the repeated text.
  4. Verify that matching text is highlighted.
  5. Navigate between matches using next/previous.
  6. Verify that the editor scrolls to the selected match.
  7. Dismiss the Find navigator.
  8. Verify that searching does not modify the post or create an undo/redo entry.
  9. Verify that Gutenberg's caret/block selection is not unexpectedly changed.

Accessibility Testing Instructions

Runtime accessibility testing is pending because an iOS/macOS environment is not currently available.

Once available, verify that the native Find navigator can be opened and operated using VoiceOver, including entering a search query, navigating between matches, and dismissing the navigator.

Screenshots or screencast

Not available yet because runtime iOS testing is pending.

@dcalhoun

Copy link
Copy Markdown
Member

@yunuschoudhurywork-lang thank you for exploring this. It may take me a little while to begin review of this, but hopefully I can next week. I'll follow up.

@dcalhoun
dcalhoun self-requested a review August 28, 2026 13:05
@yunuschoudhurywork-lang

Copy link
Copy Markdown
Author

@dcalhoun sure sir!! I'll wait for your confirmation then only I proceed further.

@yunuschoudhurywork-lang

Copy link
Copy Markdown
Author

@dcalhoun hi sir! Any update.

@dcalhoun

dcalhoun commented Sep 8, 2026

Copy link
Copy Markdown
Member

@yunuschoudhurywork-lang no, I was unable to review last week. It remains on my list, so I intend to follow up. Thank you for your patience.

dcalhoun and others added 3 commits September 16, 2026 10:03
Resolves a SwiftLint `vertical_whitespace` violation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Gives the iOS demo app an entry point for `presentFindNavigator()`, so the
find navigator can be exercised through the same path the host apps will use
rather than only via a hardware keyboard shortcut.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Dismissing the find navigator while the software keyboard is visible left
the web view short by the navigator's height, exposing a strip of the view
controller's background below the editor.

`UIKeyboardLayoutGuide` folds the find navigator into the region it tracks.
When the navigator and the keyboard go away together the guide never receives
a final update, so it stays short and the web view's bottom constraint
inherits the stale value.

Track the keyboard's visibility directly and pin the web view to the safe area
whenever neither the keyboard nor the navigator is present, leaving the guide
in charge only while something is actually docked there. The navigator still
reports itself visible during `keyboardWillHide` and only flips one run loop
later, so re-check then — still inside the keyboard's animation, and matching
its duration, so the web view grows alongside the keyboard instead of leaving
a gap that snaps shut once the keyboard has gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dcalhoun

dcalhoun commented Sep 16, 2026 •

Copy link
Copy Markdown
Member

@yunuschoudhurywork-lang testing this went well. I pushed few commits to this branch during my testing.

Screen recording of usage

ScreenRecording_09-16-2026.13-06-36_1.MP4

The usage of the native UIFindInteraction API seems like a valid path for iOS. That finding doesn't necessarily decide what we should do for Android, but it rules out that iOS requires a JS-based implementation.

I believe we can proceed forward exploring the Android implementation as discussed in wordpress-mobile/WordPress-Android#23222 (comment).

Below are a details summarized by Claude, where I discovered a few issues that we'll need to explore on iOS.


Spike result: the native UIFindInteraction path works.

The blocking question from the exploration notes — does native find decoration behave inside contenteditable — comes back clean. Highlighting, the match counter, and prev/next all work, with no observed disruption to caret position, block selection, dirty state, or undo history.

Three things to carry forward:

1. Match placement is wrong while the software keyboard is up. WebKit's find scroll path subtracts the keyboard from a viewport GBK has already subtracted it from, so the match parks against the top edge and clips by ~5pt. Measured: −5pt with the keyboard up, vs. 41% down the viewport with it dismissed. Caret scroll-into-view is unaffected, so this is specific to the find path rather than an editor layout bug. CSS scroll-padding/scroll-margin and scrollView.contentInset have no effect (verified with controls). The natural flow works around it — type the query, dismiss the keyboard with the search key, then step through matches. A real fix means moving the bottom toolbar's keyboard avoidance into the web layer, since the web view's shrink is what keeps the toolbar above the keyboard.

2. "Find Selection" comes free in the text-selection menu, and it's buggy. isFindInteractionEnabled adds it automatically. Sessions started that way never scroll to the first match until the query is modified — both in the demo and WP-iOS. The "Find in Post" entry point is unaffected. We can filter the item out of the edit menu if we'd rather not ship it.

3. There are no find-session callbacks. UIFindInteraction.delegate is readonly (set only via the initializer) and findNavigatorVisible isn't KVO-compliant, so notifying the host when find opens or closes would require polling. Worth dropping the idea.

Android is unblocked — the iOS verification that gated it passed. Item 1 is WebKit-specific and shouldn't recur there, but a custom find bar is still required regardless.

@yunuschoudhurywork-lang

Copy link
Copy Markdown
Author

@dcalhoun Thanks for the detailed verification and the additional findings.

The iOS spike results are clear, and I’ll proceed with the Android exploration as discussed in the WordPress-Android issue, starting with the native WebView find behavior and checking the match navigation, selection, dirty state, undo history, and keyboard/viewport behavior before moving into the actual implementation.

I’ll keep the Android work as a decision/behavior spike initially and report the findings before committing to the final native vs. JS approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants