# Can't focus on ios

**URL:** <https://discuss.prosemirror.net/t/cant-focus-on-ios/3372>\
**Category:** Uncategorized\
**Created:** [December 25, 2020, 8:08pm UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372 "2020-12-25T20:08:05Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![brandoncc](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/brandoncc/32/1880_2.png) [@brandoncc](https://discuss.prosemirror.net/u/brandoncc)\
**Post date:** [December 25, 2020, 8:08pm UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/1 "2020-12-25T20:08:05Z")

</div>

My problem: Neither focus() on my editor view instance nor editorViewInstance.dom.focus() will trigger the keyboard to show on ios.

My scenario: I mount the editor after a user clicks on a static element on the page, it isn’t in the DOM when the page loads initially.

My attempts to fix it:

- Add `autofocus` to the `contenteditable` DOM element before calling focus on it or the view instance.
- Call `click()` on the DOM element.
- Trigger `touchstart` on the DOM element before attempting to focus it.

Does anyone know how to fix this?

---

<div class="post-metadata">

**Author:** ![bhl](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/bhl/32/4074_2.png) [@bhl](https://discuss.prosemirror.net/u/bhl)\
**Post date:** [December 26, 2020, 8:44am UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/2 "2020-12-26T08:44:56Z")

</div>

Not sure if this will work, but trying setting a valid selection (via [https://prosemirror.net/docs/ref/#state.EditorState^create^config.selection](https://prosemirror.net/docs/ref/#state.EditorState%5Ecreate%5Econfig.selection)) and focusing on the editor.

---

<div class="post-metadata">

**Author:** ![brandoncc](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/brandoncc/32/1880_2.png) [@brandoncc](https://discuss.prosemirror.net/u/brandoncc)\
**Post date:** [December 27, 2020, 6:32pm UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/3 "2020-12-27T18:32:46Z")

</div>

Unfortunately, this didn’t work. You did, however, help me clean up some code where I was setting the selection after the editor was mounted. This is much cleaner, so thank you!

---

<div class="post-metadata">

**Author:** ![bhl](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/bhl/32/4074_2.png) [@bhl](https://discuss.prosemirror.net/u/bhl)\
**Post date:** [December 28, 2020, 1:27am UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/4 "2020-12-28T01:27:30Z")

</div>

> My scenario: I mount the editor after a user clicks on a static element on the page, it isn’t in the DOM when the page loads initially.

Ah I re-read this more carefully.

You need to figure a way to focus the editor _after_ it has been mounted onto the dom. This is because you can’t focus on an element that’s not currently in the dom.

The way I do it with react is via

```tsx
function EditorContent({editor}: {editor: Editor}) {
  return (
    <div className="editor-content" 
      ref={ref => (ref && editor && editor.view) && { ref.appendChild(editor.view.dom); editor.view.dom.focus() } }
    />
  )
};

```

---

<div class="post-metadata">

**Author:** ![brandoncc](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/brandoncc/32/1880_2.png) [@brandoncc](https://discuss.prosemirror.net/u/brandoncc)\
**Post date:** [December 28, 2020, 8:29am UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/5 "2020-12-28T08:29:27Z")

</div>

Thanks for that info. I create an EditorView in a useEffect hook, then call view.focus() on it. The view is appended in the constructor. Just to be sure, I tried appending it myself like you do, but it didn’t make a difference. This only happens on ios, its weird.

---

<div class="post-metadata">

**Author:** ![dminkovsky](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/dminkovsky/32/1673_2.png) [@dminkovsky](https://discuss.prosemirror.net/u/dminkovsky)\
**Post date:** [December 29, 2020, 2:31pm UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/6 "2020-12-29T14:31:01Z")

</div>

Try doing the focus after a timeout of 0. I usually do focus like this because otherwise I’ve encountered issues like you describe on many platforms.

---

<div class="post-metadata">

**Author:** ![brandoncc](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/brandoncc/32/1880_2.png) [@brandoncc](https://discuss.prosemirror.net/u/brandoncc)\
**Post date:** [January 2, 2021, 7:30pm UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/7 "2021-01-02T19:30:39Z")

</div>

Thank you both for your responses @bhl and @dminkovsky.

I created [this test app](https://frosty-noether-7d2838.netlify.app/) as a way to make sure that nothing else in my app was breaking it.

The code for the application is located [here](https://github.com/brandoncc/proseeditor).

If you access that in an iPhone (using Safari) or an Android device (using Chrome), you will see that the editor receives focus, but the keyboard doesn’t become shown.

I also tried adding `autofocus` to the dom element before appending it. That caused the same outcome, although I no longer had to call `focus()` for the editor to have focus.

---

<div class="post-metadata">

**Author:** ![dminkovsky](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/dminkovsky/32/1673_2.png) [@dminkovsky](https://discuss.prosemirror.net/u/dminkovsky)\
**Post date:** [January 4, 2021, 1:04pm UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/8 "2021-01-04T13:04:12Z")

</div>

Yeah, focus is “true” but the keyboard does not open until I tap. Have you tried just `view.focus()` directly on `view`, not `dom`?. That is what I do and it works fine… [https://prosemirror.net/docs/ref/#view.EditorView.focus](https://prosemirror.net/docs/ref/#view.EditorView.focus)

```auto
useImperativeHandle(ref, () => ({
    focus: () => proseMirror.current.view.focus(),
}));

```

I have that handle in my component that has the ProseMirror view, and then I call that `focus` function with a timeout of 0 to make sure the focus works fine on mobile.

Also, not sure about appending the view in the `ref` handler. Maybe use `useEffect` for this? Something like: [https://github.com/dminkovsky/use-prosemirror/blob/93edf8ae5323e9cbffa03e793b494a28046d490a/src/ProseMirror.tsx](https://github.com/dminkovsky/use-prosemirror/blob/93edf8ae5323e9cbffa03e793b494a28046d490a/src/ProseMirror.tsx)?

---

<div class="post-metadata">

**Author:** ![brandoncc](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/brandoncc/32/1880_2.png) [@brandoncc](https://discuss.prosemirror.net/u/brandoncc)\
**Post date:** [January 4, 2021, 7:39pm UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/9 "2021-01-04T19:39:01Z")

</div>

I have tried all of those things. My actual production code looks like this:

```
const editorNodeRef = useRef<HTMLDivElement | null>(null);

useEffect(() => {
  const view = new EditorView(editorNodeRef.current, {
    state: editorStateRef.current,
  });
  editorViewRef.current = view;

  view.focus();

  return () => {
    view.destroy();
  };
}, []);

return <div ref={editorNodeRef} />;

```

All of the things you saw in my test app were direct tests of what bhl recommended. Those didn’t work any better than my production implementation does, unfortunately.

I do have a question though. I don’t see anywhere in your `useProsemirror` hook that you are focusing on mount like I am trying to do. Am I missing it? Do you have an app which does this that I could test on my iPhone?

Thanks for the help. I feel like I must not have been the only person to face this issue…so there must be a solution.

---

<div class="post-metadata">

**Author:** ![brandoncc](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/brandoncc/32/1880_2.png) [@brandoncc](https://discuss.prosemirror.net/u/brandoncc)\
**Post date:** [January 4, 2021, 7:55pm UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/10 "2021-01-04T19:55:31Z")

</div>

I just added these lines to my effect, just trying to get anything to work:

```
view.focus();
$(view.dom).trigger('touchstart');
$(view.dom).trigger('click');
view.dom.focus();
view.focus();

```

No difference :-/

---

<div class="post-metadata">

**Author:** ![dminkovsky](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/dminkovsky/32/1673_2.png) [@dminkovsky](https://discuss.prosemirror.net/u/dminkovsky)\
**Post date:** [January 5, 2021, 12:17am UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/11 "2021-01-05T00:17:11Z")

</div>

Oh hey, I’m sorry I totally blanked on this: this is a well-known limitation or user-protection thing (depending on how you look at it) in iOS Safari: it is impossible to focus an element on a stack that did not originate from user interaction!

The reason I blanked on this is because I’ve been developing on iOS using Capacitor, which does not have this limitation because instead of iOS Safari it uses a WKWebView, which lets you enable non-user-interaction-originated focus.

So yeah, this behavior is totally “broken” on iOS Safari.

---

<div class="post-metadata">

**Author:** ![dminkovsky](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/dminkovsky/32/1673_2.png) [@dminkovsky](https://discuss.prosemirror.net/u/dminkovsky)\
**Post date:** [January 5, 2021, 1:10am UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/12 "2021-01-05T01:10:47Z")

</div>

See, for example, [ios - Programmatically focus on a form in a webview (WKWebView) - Stack Overflow](https://stackoverflow.com/questions/32449870/programmatically-focus-on-a-form-in-a-webview-wkwebview).

And of course there are hacks [like](https://blog.opendigerati.com/the-eccentric-ways-of-ios-safari-with-the-keyboard-b5aa3f34228d):

> Tip #3: Though programmatically setting focus on an input box won’t cause the keyboard to open, you can set focus on another input while handling the touchDown event; the soft keyboard still opens. Pairing this with #2 means that you can position a fake text input box near the bottom of the page, and when that’s tapped instead set focus to the real input box which is higher on the page (even if it’s offscreen, e.g. placed at top=0 left=99999px) … then, use setTimeout to run a function in a few milliseconds which moves that real input box down lower on the page to where you really wanted it.

But I’ve never tried anything like this. To be honest I’m not even sure I understand it 🥴.

---

<div class="post-metadata">

**Author:** ![brandoncc](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/brandoncc/32/1880_2.png) [@brandoncc](https://discuss.prosemirror.net/u/brandoncc)\
**Post date:** [January 6, 2021, 9:14pm UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/13 "2021-01-06T21:14:14Z")

</div>

Hmmm, I might be able to use a styled textarea as my click target…then focus the prosemirror editor and remove the textarea…it is worth a shot anyway!

Thank you for your input, I really appreciate it.

---

<div class="post-metadata">

**Author:** ![brandoncc](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/brandoncc/32/1880_2.png) [@brandoncc](https://discuss.prosemirror.net/u/brandoncc)\
**Post date:** [January 6, 2021, 9:56pm UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/14 "2021-01-06T21:56:28Z")

</div>

Well, I figured it probably wouldn’t let me trick iOS like that, and I was right. Bummer! I guess we’ll have to figure out some UI for dealing with this. Thank you again.

---

<div class="post-metadata">

**Author:** ![brandoncc](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/brandoncc/32/1880_2.png) [@brandoncc](https://discuss.prosemirror.net/u/brandoncc)\
**Post date:** [January 14, 2021, 6:08am UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/15 "2021-01-14T06:08:39Z")

</div>

Just to close out this thread, I finally figured it out. I needed to use pointer events rather than `onClick`. I ended up using `onPointerDown` and pepjs to polyfill.

I have a few different editors in my app. One of them works great just by rendering it and then calling `view.focus()`. Two of them require me to do this (I have no idea why non-iOS is different in this situation, but it works):

```auto
onPointerDown={
  isIOS
    ? () => setShowEditor(true)
    : () => setTimeout(() => setShowEditor(true), 0)
}

```

Ironically, if I use the `setTimeout` on iOS, it breaks. If I _don’t_ use it on desktop browsers, it breaks.

I used the [react-device-detect](https://github.com/duskload/react-device-detect) library to achieve this.

Upon render, `view.focus()` is called in all cases. Everything is working great. Thanks everyone for the help!

---

<div class="post-metadata">

**Author:** ![dminkovsky](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/dminkovsky/32/1673_2.png) [@dminkovsky](https://discuss.prosemirror.net/u/dminkovsky)\
**Post date:** [January 15, 2021, 1:18am UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/16 "2021-01-15T01:18:25Z")

</div>

Hi @brandoncc, thanks for the update. I’m sorry, I’m confused: are you saying this method got the keyboard to appear without user interaction?

---

<div class="post-metadata">

**Author:** ![brandoncc](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/brandoncc/32/1880_2.png) [@brandoncc](https://discuss.prosemirror.net/u/brandoncc)\
**Post date:** [January 19, 2021, 9:36pm UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/17 "2021-01-19T21:36:30Z")

</div>

The user clicks on the “container” element where I insert the editor. Other than that, no interaction is required!

---

<div class="post-metadata">

**Author:** ![dminkovsky](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/dminkovsky/32/1673_2.png) [@dminkovsky](https://discuss.prosemirror.net/u/dminkovsky)\
**Post date:** [January 22, 2021, 3:25am UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/18 "2021-01-22T03:25:34Z")

</div>

@brandoncc Thank you. So you click on a container that looks like the editor,and if for some reason you handle the click with `onPointerDown`—and the other details you write above—after you’ve inserted the editor, `view.focus()` will focus the editor and open the keyboard?

Did you try touch events, by the way? Last time I checked (I believe it was iOS 13), iOS didn’t support PointerEvents but did support TouchEvents. Guessing maybe that polyfill translates pointer events to touch events.

---

<div class="post-metadata">

**Author:** ![brandoncc](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/brandoncc/32/1880_2.png) [@brandoncc](https://discuss.prosemirror.net/u/brandoncc)\
**Post date:** [January 26, 2021, 1:06am UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/19 "2021-01-26T01:06:12Z")

</div>

Okay, I think I know why this magically worked, even though everything said it shouldn’t. `OnPointerDown` is causing my overlay element to be removed and the editor to be rendered in its place. By the time the user lifts their finger, the element under their finger is the editor, so they are triggering a touchend on that element.

---

<div class="post-metadata">

**Author:** ![dwzkit](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/dwzkit/32/4077_2.png) [@dwzkit](https://discuss.prosemirror.net/u/dwzkit)\
**Post date:** [May 20, 2024, 2:49am UTC](https://discuss.prosemirror.net/t/cant-focus-on-ios/3372/20 "2024-05-20T02:49:26Z")

</div>

Thank you very much for your detailed explanation. I encountered the exact same issue. After changing onClick to onPointerDown, the problem was resolved. Thank you!
