按下 UITextView 上的链接时应用程序崩溃

Posted

技术标签:

【中文标题】按下 UITextView 上的链接时应用程序崩溃【英文标题】:App crashes when pressing link on UITextView 【发布时间】:2016-03-16 13:50:25 【问题描述】:

我在我的 ios 应用程序中遇到了一个奇怪的错误,它只发生在设备中。在我的应用程序中,我有一个主页,如果用户按下按钮,我将显示一个 FormSheet(关于我们页面)。

let storyBoard = UIStoryboard(name: "Utility", bundle: nil);
let aboutUsVC  = storyBoard.instantiateViewControllerWithIdentifier("AboutUs") as! AboutUsViewController;
aboutUsVC.modalPresentationStyle = .FormSheet;
aboutUsVC.preferredContentSize   = CGSize(width: 500,height: 400);
self.presentViewController(aboutUsVC, animated: true, completion: nil);

我在关于我们的页面中放置了一个 UITextView,并在其内容中添加了一个链接:

问题 1

当我长按该链接时,我的控制台上会收到一条警告消息:

<_uirotatingalertcontroller:> 已在其上呈现

问题 2

如果我再次点击链接,长按后,应用程序会崩溃并显示以下消息:

2016-03-16 18:11:37.022 MyApp[938:400786] *** 中的断言失败 -[UITextView startInteractionWithLinkAtPoint:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.29.5/UITextView_LinkInteraction.m:377

2016-03-16 18:11:37.023 MyApp[938:400786] *** 终止应用程序到期 未捕获的异常'NSInternalInconsistencyException',原因:'' *** 第一次抛出调用堆栈:(0x184220f48 0x198e47f80 0x184220e18 0x185114a1c 0x18a12de50 0x189d38be4 0x189d2f330 0x189958b5c 0x1897e685c 0x189d3070c 0x1897a58b8 0x1897a263c 0x1841d7bd0 0x1841d5974 0x1841d5da4 0x184104ca0 0x18f184088 0x18981cffc 0x100188368 0x19968a8b8) libc++abi.dylib:以未捕获的方式终止 NSException 类型的异常

我认为 UIKit 导致了崩溃。我该如何解决这个崩溃?

更多信息:

    基础 SDK:9.2 部署目标:8.1 Xcode 版本:7.2.1 iOS 设备操作系统版本:9.1

【问题讨论】:

看到这个链接可能对你有帮助***.com/questions/32653268/… 它看起来像错误:github.com/jessesquires/JSQMessagesViewController/issues/1247 这是 iOS9 的一个错误:forums.developer.apple.com/thread/19480 我必须执行该论坛帖子中列出的内容(以及@Anbu.Karthik 链接的答案中提到的内容) 【参考方案1】:

正如Apple Forum post 中所述,我实现了以下UITextViewDelegate 并解决了我的问题

func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool

    UIApplication.sharedApplication().openURL(URL)
    return false  
  

@Louis Tur:感谢您的链接

Swift 5.2

 @available(iOS 10.0, *)
func textView(_ textView: UITextView, shouldInteractWith url: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool 

    UIApplication.shared.openURL(url)
    return false  


@available(iOS, deprecated: 10.0)
func textView(_ textView: UITextView, shouldInteractWith url: URL, in characterRange: NSRange) -> Bool 

   UIApplication.shared.openURL(url)
   return false  

【讨论】:

我实现了委托方法,但我返回 true。返回 false 解决了问题。谢谢!【参考方案2】:

我对崩溃的修复是同时实现已弃用的委托方法及其替换委托方法。

/// Gets called if iOS version is >= 10.
@available(iOS 10.0, *)
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool 
    return textViewShouldInteractWithURL(URL: URL)


/// deprecated delegate method. Gets called if iOS version is < 10.
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool 
    return textViewShouldInteractWithURL(URL: URL)


func textViewShouldInteractWithURL(URL: URL) -> Bool 
    // common logic here

【讨论】:

【参考方案3】:

我们在 PSPDFKit 中也看到了这个问题,在调查了 UIKit 程序集和 WKWebView 源之后,我们发现了一个仍然很糟糕但没有侵入性的解决方法。

主要策略是有选择性并及时应用解决方法 - 然后再次清理。你可以在这里阅读源代码:

https://gist.github.com/steipete/b00fc02aa9f1c66c11d0f996b1ba1265

请欺骗rdar://26295020,希望能在 iOS 10 中及时修复。(该错误自 iOS 8 以来就存在,并首次在 iOS 8b5 上报告。)

这可能是比更改 URL 交互方式更好的解决方案。

【讨论】:

【参考方案4】:

我在链接中使用了不正确的 URL 格式时遇到了这个问题。我想在点击链接时在屏幕上显示一个新控制器,并实现了一个自定义 URL 方案来支持它。这样做时,我错误地以scheme:\\ 格式而不是scheme:// 编写了该方案并捕获了崩溃。

【讨论】:

以上是关于按下 UITextView 上的链接时应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

检测 UITextView 上的点击仅检测取消 [重复]

从 UITextView 的菜单中选择和删除文本时崩溃

单击时 UITextView 未打开 URL

在编辑模式下按下删除按钮时 UITableView 崩溃

当Webview方向更改然后按下后退按钮时,应用程序崩溃

Swift 4:@IBOutlet UITextView 崩溃