Open nastasiupta opened 1 year ago
Thanks very much for reporting this and the additional notes you supplied. I think it must be a regression (maybe for iOS 17?), but I should be able to take a look at it within the next couple of days.
@stevengharris Any ETA for this issue ?
I started to look at it, thinking I had a good idea how to fix it, but it turns out not to be as simple as I thought. The fact it's not happening with things like indent is a good clue, considering I'm conceptually doing the same thing (invoke a JavaScript function, modify the DOM, notify the Swift side that there has been a change). Maybe some kind of change in the underlying WKWebView to accommodate changes in UITextInteraction in iOS 17 (e.g., https://developer.apple.com/videos/play/wwdc2023/10058/), but considering I never do anything with UITextInteraction directly in the MarkupEditor, I'm not sure. So, the short answer is: no ETA, but I'm looking at it.
FWIW, the simulator shows this problem does not show up in iOS 16.
Also in iOS 17, when positioning the cursor in the middle of a word using the "loupe" (i.e., long press showing a magnifier above the touch point), the console spits out:
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API and this value is being ignored. Please fix this problem.
If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental variable.
And if you put CG_NUMERICS_SHOW_BACKTRACE in the environment, you get this backtrace:
<CGPathAddLineToPoint+71>
<+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadii:segments:smoothPillShapes:]+2718>
<+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadius:segments:]+167>
<+[UIBezierPath _roundedRectBezierPath:withRoundedCorners:cornerRadius:segments:legacyCorners:]+338>
<-[_UITextMagnifiedLoupeView layoutSubviews]+2240>
<-[UIView(CALayerDelegate) layoutSublayersOfLayer:]+2141>
<_ZN2CA5Layer16layout_if_neededEPNS_11TransactionE+527>
<_ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE+67>
<_ZN2CA7Context18commit_transactionEPNS_11TransactionEdPd+706>
<_ZN2CA11Transaction6commitEv+728>
<_UIApplicationFlushRunLoopCATransactionIfTooLate+70>
<__processEventQueue+9465>
<__eventFetcherSourceCallback+163>
<__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__+17>
<__CFRunLoopDoSource0+157>
<__CFRunLoopDoSources0+215>
<__CFRunLoopRun+919>
<CFRunLoopRunSpecific+557>
<GSEventRunModal+137>
<-[UIApplication _run]+972>
<UIApplicationMain+123>
<__swift_destroy_boxed_opaque_existential_1Tm+12707>
<$sSo21UIApplicationDelegateP5UIKitE4mainyyFZ+123>
<$s11SwiftUIDemo11AppDelegateC5$mainyyFZ+39>
<main+24>
109d023ee 1179a43a6
The loupe positioning still works okay, but 🤔.
Some potentially related issues:
Mostly just makes me think this is going to require some kind of weird hack to fix without Apple themselves fixing it. I will probably try to reproduce it using a very simple test case with only WKWebView and submit the problem as a formal Technical Support Incident.
We can give it a try. Let me know after you solve this, and I will test it out :D
@stevengharris also, another issue I noticed on a freshly installed app, when the MarkupEditorView begins editing, the UIPasteBoard permission is triggered and it ask to allow the paste action...
I had thought that was all taken care of in https://github.com/stevengharris/MarkupEditor/pull/78, but, again, maybe something changed for iOS 17. I will check it out and raise a separate issue for it if needed.
@stevengharris any update on this issue?
I have not had the time to dig in further. If you would open a separate issue for the UIPasteboard permission problem with any details to reproduce, it will help me track it. Thx.
@stevengharris any update on this issue ?
No, I think I will have to dig into UITextInteraction to fix it but have not had the time.
Hello @stevengharris, I have the same issue as described above. Do you maybe have a fix or a workaround for this ?
Unfortunately, no. I spent some time trying to sort out UITextInteraction, and am not sure it is a path to fixing the issue, which seems to be in WKWebView itself. Anyway, sorry, but I haven't been able to make any progress on it. Do you know if it is still a problem on iOS 18?
Yes it is still an issue on iOS 18.
It occurred to me that maybe a workaround would be to force the keyboard to show after bold/italic etc, although doing so takes some swizzling. This was discussed a long time ago in this issue/comment https://github.com/stevengharris/MarkupEditor/issues/88#issuecomment-1416474586. As Gavin notes in the comment, I once had commented-out code in MarkupWKWebView to do this, but I removed it completely when I did what I felt was a proper job on getting focus. Here is the old code I just resurrected from git (no idea if it works, but putting it here for my own purposes and in case someone wants to take a closer look themselves). The idea would be to restore this code in working form to MarkupWKWebView and then call showKeyboard()
, perhaps inside the evaluateJavaScript
closure of MarkupWKWebView.bold(handler:)
, italic, etc.
typealias NewClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Voi
func setKeyboardRequiresUserInteraction(_ value: Bool) {
guard
let WKContentViewClass: AnyClass = NSClassFromString("WKContentView") else {
print("Cannot find the WKContentView class")
return
}
let ios13Selector: Selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:")
if let method = class_getInstanceMethod(WKContentViewClass, ios13Selector) {
swizzleAutofocusMethod(method, ios13Selector, value)
}
func unsetKeyboardRequiresUserInteraction() {
guard
let WKContentViewClass: AnyClass = NSClassFromString("WKContentView") else {
print("Cannot find the WKContentView class")
return
}
let ios13Selector: Selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:")
if let method = class_getInstanceMethod(WKContentViewClass, ios13Selector) {
unswizzleAutofocusMethod(method, ios13Selector)
}
func swizzleAutofocusMethod(_ method: Method, _ selector: Selector, _ value: Bool) {
print("swizzling")
let originalImp: IMP = method_getImplementation(method)
let original: NewClosureType = unsafeBitCast(originalImp, to: NewClosureType.self)
let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void = { (me, arg0, arg1, arg2, arg3, arg4) in
original(me, selector, arg0, !value, arg2, arg3, arg4)
}
let imp: IMP = imp_implementationWithBlock(block)
method_setImplementation(method, imp)
func unswizzleAutofocusMethod(_ method: Method, _ selector: Selector) {
print("unswizzling")
let originalImp: IMP = method_getImplementation(method)
let original: NewClosureType = unsafeBitCast(originalImp, to: NewClosureType.self)
let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void = { (me, arg0, arg1, arg2, arg3, arg4) in
original(me, selector, arg0, arg1, arg2, arg3, arg4)
}
let imp: IMP = imp_implementationWithBlock(block)
method_setImplementation(method, imp)
public func showKeyboard() {
setKeyboardRequiresUserInteraction(false)
becomeFirstResponder()
unsetKeyboardRequiresUserInteraction()
}
Since it's clear this problem isn't going to go away on the WKWebView end even in iOS 18, I will try to circle back around to this approach as a workaround.
I created a simple project, added the framework using SPM and using the SwiftUI example. If I tap somewhere and select the "Bold" option to write something bolded, the keyboard is dismissed... I have to tap again in the same place and start writing. iOS version 17.1 Xcode version 15.0.1 Framework version 0.6.0
Note 1: This happens only when I activate the bold, underline, italic and strike, when i disable the effect, the keyboard remains. And if I tap again, the keyboard is dismissed. Note 2: For other options (dots list etc) works fine.