Stack trace:
* thread #1: tid = 0x1ee50f, 0x00000001096f5d05 libswiftFoundation.dylib`static Foundation.DateComponents._unconditionallyBridgeFromObjectiveC (Swift.Optional<__ObjC.NSDateComponents>) -> Foundation.DateComponents with unmangled suffix "_merged" + 85, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
frame #0: 0x00000001096f5d05 libswiftFoundation.dylib`static Foundation.DateComponents._unconditionallyBridgeFromObjectiveC (Swift.Optional<__ObjC.NSDateComponents>) -> Foundation.DateComponents with unmangled suffix "_merged" + 85
frame #1: 0x000000010558e36f Invest`@objc InvestDashboard.textView(UITextView, shouldInteractWith : URL, in : _NSRange) -> Bool + 79 at InvestDashboard.swift:0
frame #2: 0x000000011fd478fc UIKit`-[UITextViewAccessibility accessibilityActivate] + 838
frame #3: 0x000000011fed29d2 UIAccessibility`-[NSObject(UIStorage) accessibilityPerformAction:withValue:fencePort:] + 1448
frame #4: 0x000000011feaa63d UIAccessibility`_performActionCallback + 163
frame #5: 0x000000011fc0cec4 AXRuntime`_AXXMIGPerformAction + 107
frame #6: 0x000000011fc06f06 AXRuntime`_XPerformAction + 216
frame #7: 0x000000011fc16541 AXRuntime`mshMIGPerform + 266
frame #8: 0x0000000106d1ff89 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
frame #9: 0x0000000106d1ff01 CoreFoundation`__CFRunLoopDoSource1 + 465
frame #10: 0x0000000106d18045 CoreFoundation`__CFRunLoopRun + 2389
frame #11: 0x0000000106d17494 CoreFoundation`CFRunLoopRunSpecific + 420
frame #12: 0x000000010cc38a6f GraphicsServices`GSEventRunModal + 161
frame #13: 0x00000001078c2964 UIKit`UIApplicationMain + 159
frame #14: 0x000000010467e99f InvestDemo`main + 111 at AppDelegate.swift:29
frame #15: 0x000000010b88268d libdyld.dylib`start + 1
frame #16: 0x000000010b88268d libdyld.dylib`start + 1
This happens whenever I use activate on a TextView that has a link in it. I've tried a lot of different things, like overriding accessibilityActivate() -> Bool
but the app crashes before this method ever gets called. Any suggestions?
I solved this issue and wanted to share so that others with the same confusing problem can fix it.
The first thing to do is to subclass UITextView
and in that subclass override func accessibilityActivate() -> Bool
. Then make a delegate that handles what happens when the TextView is activated and call it through the overridden method.
Then set the delegate of the TextView based on UIAccessibilityIsVoiceOverRunning()
, so if voice over is running then set the UITextViewDelegate
to nil
which prevents the crash from happening and then the activation action is handled by the method you overrode in the subclass above. Finally, set up a listener for UIAccessibilityVoiceOverStatusChanged
and set the UITextViewDelegate
to nil
when going from off to on, and setting it to the original delegation class for the opposite scenario.
Some code:
//: Playground - noun: a place where people can play
import UIKit
class Test : UITabBarController, UITextViewDelegate, ActivationDelegate {
var voiceOverRunning : Bool {
get {
return UIAccessibilityIsVoiceOverRunning()
}
}
var testView = AccessibilityView()
override func viewDidLoad() {
if !voiceOverRunning {
testView.delegate = self
} else {
testView.activationDelegate = self
}
NotificationCenter.default.addObserver(
self,
selector: #selector(self.didChangeVoiceOver),
name: NSNotification.Name(rawValue: UIAccessibilityVoiceOverStatusChanged),
object: nil)
}
func doStuff() {
/*
Do what you want to happen here on activation
*/
}
@objc
func didChangeVoiceOver(){
testView.delegate = voiceOverRunning ? nil : self
testView.activationDelegate = voiceOverRunning ? self : nil
}
}
protocol ActivationDelegate : class {
func doStuff()
}
class AccessibilityView : UITextView {
var activationDelegate : ActivationDelegate!
override func accessibilityActivate() -> Bool {
activationDelegate.doStuff()
return true
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With