我有UIViewController
UITextView
,可以自动检测文本中的超链接。它工作正常,但我会使用SFSafariViewController
来打开链接,这样我就可以“留在”我的应用程序中,而不是打开一个单独的浏览器,这是“开箱即用”的行为。
我已经采取了下面的步骤,但网站仍然打开一个单独的Safari浏览器,而不是在我的应用程序内。我没有收到任何错误或警告,但检测到的网站仍在单独的浏览器中打开,而不是在我的应用程序中。 UITextViewDelegate
方法似乎没有被调用(我将一个日志语句放入检查中)。
我查看UITextViewDelegate
,我想我想使用此方法打开UITextView
检测到的网站:
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
// Fill code in here to use SFSafariViewController
return YES;
}
到目前为止我做了什么:
1)导入SafariServices,制作委托声明,并在MyViewController中声明委托属性。 h
@import SafariServices;
@interface MyViewController : UIViewController <UITextViewDelegate, SFSafariViewControllerDelegate>
@property(nonatomic, weak, nullable) id< SFSafariViewControllerDelegate, SFSafariViewControllerDelegate > delegate;
2)在我的.m文件中添加了一个委托部分,并尝试从上面的存根中填写此方法:
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
SFSafariViewController *websiteToOpen = [[SFSafariViewController alloc]initWithURL:URL entersReaderIfAvailable:YES];
websiteToOpen.delegate = self;
[self presentViewController:websiteToOpen animated:YES completion:nil];
return YES;
}
我确信这是100%我把它弄糟,但我无法超越终点线。我错过了什么?
答案 0 :(得分:7)
如果有人正在寻找 Swift 3 实施。
有效的解决方案:
1.导入Safari服务
import SafariServices
2.创建属性文本,添加链接,将字符串分配给textView
let myLink = "google.com"
let myText = "here is my link: \(myLink)"
let myAttributedText = NSMutableAttributedString(string: myText)
let rangeOfMyLink = myText.range(of: myLink)
if rangeOfMyLink.location != NSNotFound {
myAttributedText.addAttributes([NSLinkAttributeName: myLink], range: rangeOfMyLink)
}
myTextView.attributedText = myAttributedText
myTextView.delegate = self
3.将代表添加到VC:
class MyViewController: UIViewController, UITextViewDelegate
4.添加委托方法:
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
let safariVC = SFSafariViewController(url: URL)
present(safariVC, animated: true, completion: nil)
return false
}
希望它有所帮助!
答案 1 :(得分:3)
您在实施结束时返回YES
,告诉系统,继续执行您要对此URL执行的操作(在本例中为打开的Safari)。如果您决定自己处理此问题,请返回NO
。
话虽如此,但有几点需要注意:
URL.scheme
。虽然textView:shouldInteractWithURL:inRange:
的文档建议您应该使用此方法拦截网址上的点按...
您可以使用此方法触发替代操作,例如在当前应用程序的Web视图中的URL处显示Web内容。
......你要小心。 “应该互动”不仅包括常规点击 - 这种方法也会被称为长按等等,这通常会有不同的行为,我无法确定为什么正在调用此委托方法。
出于这些原因,您可以考虑将自己的UITapGesturRecognizer
附加到UITextView
,详见this answer。
答案 2 :(得分:1)
我正在尝试做同样的事情,但遇到了不同的问题。
首先,您需要设置文本视图的委托才能触发delegate
方法。我在viewDidLoad中执行此操作:
myTextView.delegate = self;
然后,告诉您的UITextView
不与网址互动:
- (BOOL)textView:(UITextView *)textView
shouldInteractWithURL:(NSURL *)url
inRange:(NSRange)characterRange
{
[self presentViewController:websiteToOpen animated:YES completion:nil];
return NO;
}
有了这个,我可以呈现safari视图控制器,虽然它是空的,即没有内容,也没有完成按钮。所以我做错了什么......