我正在开发一款 iPhone 3.0 应用程序。我试图将 UITextView 中的网页链接在 UIWebView 中打开,而不是 Safari。但还是没成功。
UITextView 不可编辑,它能够很好地检测到网页链接并在 Safari 中打开。
如何避免这种情况?如何获取该 URL,以便我可以在自己的 UIWebView 中使用?
我正在开发一款 iPhone 3.0 应用程序。我试图将 UITextView 中的网页链接在 UIWebView 中打开,而不是 Safari。但还是没成功。
UITextView 不可编辑,它能够很好地检测到网页链接并在 Safari 中打开。
如何避免这种情况?如何获取该 URL,以便我可以在自己的 UIWebView 中使用?
这是一个旧问题,但如果有人正在寻找更新的方法,请参考以下步骤:
在视图控制器(viewController)的.m文件中将包含UITextView的viewController指定为代理,并添加以下代码:
-(BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange{
//Do something with the URL
NSLog(@"%@", URL);
return NO;
}
UITextViewDelegate
提供了一个textView(_:shouldInteractWith:in:interaction:)
方法。其声明如下:
该方法用于判断文本视图是否应该允许用户与给定的URL进行交互,并要求代理返回一个布尔值作为判断依据。询问代理是否允许指定文本视图在给定的文本范围内使用指定类型的URL进行用户交互。
optional func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool
SFSafariViewController
中打开UITextView
的网页链接,而不是在Safari应用程序中打开它们:import UIKit
import SafariServices
class ViewController: UIViewController, UITextViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Set textView
let textView = UITextView()
textView.text = "http://www.yahoo.fr http://www.google.fr"
textView.isUserInteractionEnabled = true
textView.isEditable = false
textView.isSelectable = true
textView.dataDetectorTypes = UIDataDetectorTypes.link
// Add view controller as the textView's delegate
textView.delegate = self
// auto layout
view.addSubview(textView)
textView.translatesAutoresizingMaskIntoConstraints = false
textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
textView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
textView.heightAnchor.constraint(equalToConstant: 300).isActive = true
textView.widthAnchor.constraint(equalToConstant: 300).isActive = true
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
// Open links with a SFSafariViewController instance and return false to prevent the system to open Safari app
let safariViewController = SFSafariViewController(url: URL)
present(safariViewController, animated: true, completion: nil)
return false
}
}
最简单的方法是覆盖UITextView
上的webView:decidePolicyForNavigationAction:request:frame:decisionListener:
方法,如下所示:
@interface UITextView (Override)
@end
@class WebView, WebFrame;
@protocol WebPolicyDecisionListener;
@implementation UITextView (Override)
- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id < WebPolicyDecisionListener >)listener
{
NSLog(@"request: %@", request);
}
@end
这将影响应用程序中的所有UITextView
。如果您只需要在单个视图上执行此操作,请创建子类并覆盖该方法。
注意:这实际上是一个私有API,随时可能被删除。没有办法通过公共API来执行此操作。
编辑:从iOS 7.0开始,在UITextViewDelegate
上引入了一个新方法来支持此操作。有关详细信息,请参见nihad的答案。