每当激活带有链接的文本视图时,应用程序就会崩溃

时间:2017-04-03 16:05:27

标签: ios swift accessibility

堆栈追踪:

* 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

只要我在TextView中使用了激活,就会发生这种情况。我已经尝试了很多不同的东西,比如重写accessibilityActivate() -> Bool,但是在调用此方法之前应用程序崩溃了。有什么建议吗?

3 个答案:

答案 0 :(得分:2)

我解决了这个问题并希望分享,以便其他具有同样令人困惑的问题的人可以解决它。

要做的第一件事是继承UITextView并在该子类中覆盖func accessibilityActivate() -> Bool。然后创建一个委托来处理激活TextView时发生的事情并通过重写方法调用它。

然后根据UIAccessibilityIsVoiceOverRunning()设置TextView的委托,因此如果正在运行语音,则将UITextViewDelegate设置为nil,以防止崩溃发生,然后激活操作为由你在上面的子类中覆盖的方法处理。最后,为UIAccessibilityVoiceOverStatusChanged设置一个监听器,并在从off到on时将UITextViewDelegate设置为nil,并将其设置为相反方案的原始委托类。

一些代码:

//: 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
    }
}

答案 1 :(得分:1)

我看到了这个问题,除了我无条件的桥接错误是NSURL。当我将静态文本设置为UIAccessibilityTrait以及在属性文本中具有链接的UITextView时,会发生这种情况。我发现唯一可能的答案是,它是桥接标头签名中的一个错误,其中一种语言试图以不同的方式调用委托方法。我的解决方案是删除(shouldInteractWith url)委托方法,但是如果我复制了方法并使一些参数可选,它似乎也有效。我没有真正看到调用委托方法,所以我认为浏览器打开链接是自动处理的。

TLDR;我认为你有三种选择:

  1. 如果您不需要,可以禁用静态文本。
  2. 使用可选参数添加重复的委托方法,直到找到有效的签名。
  3. 完全删除委托方法。

答案 2 :(得分:1)

我刚刚碰到这个并注意到了这个细节:当我拥有while( $row = mysqli_fetch_array($sql)){ ?> <tr> <td><?php echo $no;?></td> <td><?php echo $row['soal']; ?></td> <td><input type="radio" name="jawabana" value="<?php echo $row['a']; ?>" <?php if(isset($_POST['jawabana']) && ($_POST['jawabana'] == $row['a'])) echo 'checked="checked" ';?>><?php echo $row['a']; ?></td> <td><input type="radio" name="jawabanb" value="<?php echo $row['b']; ?>" <?php if(isset($_POST['jawabanb']) && ($_POST['jawabanb'] == $row['b'])) echo 'checked="checked" ';?>><?php echo $row['b']; ?></td> <td><input type="radio" name="jawabanc" value="<?php echo $row['c']; ?>" <?php if(isset($_POST['jawabanc']) && ($_POST['jawabanc'] == $row['c'])) echo 'checked="checked" ';?>><?php echo $row['c']; ?></td> <td><input type="radio" name="jawaband" value="<?php echo $row['d']; ?>" <?php if(isset($_POST['jawaband']) && ($_POST['jawaband'] == $row['d'])) echo 'checked="checked" ';?>><?php echo $row['d']; ?></td> </tr> <?php $no++; } 实现的旧版iOS 9版本时,崩溃才会发生。我的代码看起来像这样:

UITextViewDelegate

删除extension ViewController: UITextViewDelegate { @available(iOS 10.0, *) func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { return true } func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool { return true } } textView(_:shouldInteractWith:in:)(并将目标提升到iOS 10)解决了崩溃问题。

不幸的是,这对我来说不是一个选择。

我已针对此问题记录https://bugreport.apple.com/web/?problemID=34187849。我确信它会被忽略,因为它涉及iOS 9支持。