首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用SFSafariViewController从UITextView自动检测到的链接打开网站

使用SFSafariViewController从UITextView自动检测到的链接打开网站
EN

Stack Overflow用户
提问于 2015-10-08 03:31:00
回答 3查看 5.4K关注 0票数 9

我有一个UIViewController,它有一个UITextView,可以自动检测文本中的超链接。它正常工作,但我会使用SFSafariViewController打开链接,这样我就可以“呆在”我的应用程序中,而不是打开单独的浏览器,这是“开箱即用”的行为。

我已经采取了下面的步骤大纲,但网站仍然打开一个单独的Safari浏览器,而不是在我的应用程序。我没有收到错误或警告,但检测到的网站仍然在单独的浏览器中打开,而不是在我的应用程序中。UITextViewDelegate方法似乎没有被调用(我抛出了一条日志语句来检查)。

我查看了UITextViewDelegate,我想我想使用这个方法打开UITextView检测到的网站

代码语言:javascript
复制
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    // Fill code in here to use SFSafariViewController
    return YES;
}

我到目前为止所做的事:

1)在MyViewController.h中导入SafariServices,进行委托声明,并声明委托属性。

代码语言:javascript
复制
@import SafariServices;

@interface MyViewController : UIViewController <UITextViewDelegate, SFSafariViewControllerDelegate>

@property(nonatomic, weak, nullable) id< SFSafariViewControllerDelegate, SFSafariViewControllerDelegate > delegate;

2)在我的.m文件中添加了一个委托部分,并试图从上面的存根中填充此方法:

代码语言:javascript
复制
- (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%我搞砸了,但我无法越过终点线。我遗漏了什么?

EN

回答 3

Stack Overflow用户

发布于 2017-03-19 21:50:32

如果有人在寻找Swift 3实现。

有效的解决方案:

1.进口Safari服务

代码语言:javascript
复制
import SafariServices

2.创建属性文本,添加链接,将字符串赋值给textView

代码语言:javascript
复制
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.在“维也纳公约”中增加代表:

代码语言:javascript
复制
class MyViewController: UIViewController, UITextViewDelegate

4.增加代表法:

代码语言:javascript
复制
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
    let safariVC = SFSafariViewController(url: URL)
    present(safariVC, animated: true, completion: nil)
    return false
}

希望能帮上忙!

票数 17
EN

Stack Overflow用户

发布于 2015-10-18 11:23:53

我试着做同样的事情,但有不同的问题。

首先,您需要为delegate方法设置文本视图的委托。我在viewDidLoad中这样做:

代码语言:javascript
复制
myTextView.delegate = self;

然后,告诉UITextView不要与URL交互:

代码语言:javascript
复制
- (BOOL)textView:(UITextView *)textView 
        shouldInteractWithURL:(NSURL *)url 
        inRange:(NSRange)characterRange
{
    [self presentViewController:websiteToOpen animated:YES completion:nil];
    return NO;
}

这样,我就可以显示safari视图控制器,尽管它是空的,即没有内容,也没有Done按钮。所以我做了别的错事..。

票数 3
EN

Stack Overflow用户

发布于 2016-06-14 01:21:57

您将在实现结束时返回YES,这将告诉系统,继续执行您要对这个URL所做的操作(在本例中,打开Safari)。如果您决定自己处理这个问题,则返回NO

话虽如此,但有几个注意事项:

  • Safari视图控制器只支持http / https URL。在使用Safari视图控制器之前,一定要检查URL.scheme
  • 虽然textView:shouldInteractWithURL:inRange:的文档建议您应该使用此方法来拦截URL上的点击. 可以使用此方法触发其他操作,例如在当前应用程序中的web视图中的URL上显示web内容。

...you想要小心点。“应该交互”不仅仅包括一个常规的点击--这个方法也会被用于长按压等等,这通常有一种不同的行为,而且据我所知,无法确定为什么要调用这个委托方法。

出于这些原因,您可能需要考虑将自己的UITapGesturRecognizer附加到UITextView,如this answer中详细介绍的那样。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33006133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档