【问题标题】:iPhone SDK - opening links in a UITextView in a web viewiPhone SDK - 在 Web 视图中的 UITextView 中打开链接
【发布时间】:2009-12-11 16:41:01
【问题描述】:

我在 UITextView 上指定了 dataDetectorTypes,以便在触摸时在 Safari 中打开 URL。

是否可以拦截此行为,以便我将 URL 加载到 UIWebView 中?或者我会编写自己的 URL 检测器代码来重新路由它吗?

【问题讨论】:

    标签: iphone uiwebview uitextview datadetectortypes


    【解决方案1】:

    您必须自己进行 URL 检测并在点击 URL 时手动加载 UIWebView。

    一切都需要定制,因为 Apple 会将所有 http://https:// URL 开口发送到 Safari。

    【讨论】:

      【解决方案2】:

      上面最有效的答案是替换 [UIApplication openURL:] 的方法实现

      另一种不使用 runtime.h 的方法是继承 UIApplication。然后,覆盖 openURL: 选择器。使用这种方法,您可以从您的子类中调用 [super openURL:] 来获取您想要默认处理的 URL。它对我来说似乎也更干净一些,因为您不需要弄乱类的内部方法实现。

      不过,如果您选择这种方法,还有 2 个其他重要步骤。在 main.m 文件中,您需要更改 UIApplicationMain 函数调用的第三个参数,使其与您的子类的名称匹配:

      int retVal = UIApplicationMain(argc, argv, @"MyApplicationSubclass", nil);
      

      另外,您可能应该将 MainWindow.xib 文件中文件所有者的类从 UIApplication 更改为您的子类。

      【讨论】:

      • 这非常适合那些希望在整个应用程序中拥有自己的实现的人。我发现它真的很有用
      【解决方案3】:

      我帮了大家一个忙,并通过博客文章和演示应用回答了您的问题。

      http://52apps.net/post/879106231/method-swizzling-uitextview-and-safari http://github.com/marksands/UITextViewLinkOptions

      要扩展 tt.Kilew 的帖子,您可以创建类别,但将您的方法称为其他名称,例如 customOpenURL。当你想回到 Safari 时,你会做一些叫做 Method Swizzling 的事情。它看起来像这样:

      #import <objc/runtime.h>
      ..
      Method customOpenUrl = class_getInstanceMethod([UIApplication class], @selector(customOpenURL:));
      Method openUrl = class_getInstanceMethod([UIApplication class], @selector(openURL:));
      method_exchangeImplementations(customOpenUrl, openUrl);
      

      当您想使用 Safari 或不想使用 Safari 时,只需调用此方法即可将 openURL 实现与您的 customOpenURL 实现交换。

      查看demo app 了解更多详情。希望这可以帮助! :)

      编辑

      如果您不想冒应用被拒绝的风险,您可能需要查看我开发的自定义 UITextView 以更好地适应这种情况:https://github.com/marksands/MSTextView

      【讨论】:

      【解决方案4】:

      另一个答案 :) 对我来说很好的是重新实现 UIApplication openURL:(NSURL *) url

      @interface UIApplication (Private)
      
      - (BOOL)openURL:(NSURL*)url;
      
      @end
      
      @implementation UIApplication (Private)
      
      - (BOOL)openURL:(NSURL*)url {
         // all viewcontrollers should change currentViewController to self
         if ([MyWatcher currentViewController]) {
            // Do anything you want
            [[MyWatcher handleURL:url withController:[MyWatcher currentViewController]];
            return YES;
         }
         return NO;
      }
      
      @end
      
      ... Some view controller
      - (void)viewDidLoad {
         [super viewDidLoad];
         [MyWatcher setCurrentController:self];
      }
      

      【讨论】:

      • 我找到了这个链接,它可以告诉你 MyWatcher 是什么——我在寻找答案时偶然发现了它——github.com/marksands/UITextViewLinkOptions/blob/master/Classes/…
      • 如果我这样做,Apple 是否会拒绝该应用程序?让我担心的是“私人”。它在这里做什么?
      • 您可以随意命名类别。 openURL 根本不是私有方法。另一种选择是使用您自己的实现子类 UIApplication 并使用方法覆盖而不是类别
      【解决方案5】:

      Swift 版本:

      您的标准 UITextView 设置应如下所示,不要忘记委托和 dataDetectorTypes。

      var textView = UITextView(x: 10, y: 10, width: CardWidth - 20, height: placeholderHeight) //This is my custom initializer
      textView.text = "dsfadsaf www.google.com"
      textView.selectable = true
      textView.dataDetectorTypes = UIDataDetectorTypes.Link
      textView.delegate = self
      addSubview(textView)
      

      在您的课程结束后添加以下内容: 请注意,您需要 https://github.com/TransitApp/SVWebViewController 这个库,据我所知,这是目前最好的。

      class myVC: UIViewController {
          //viewdidload and other stuff here
      }
      
      extension MainCard: UITextViewDelegate {
          func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {
              //Do your stuff over here
              var webViewController = SVModalWebViewController(URL: URL)
              view.presentViewController(webViewController, animated: true, completion: nil)
              return false
          }
      }
      

      【讨论】:

        【解决方案6】:

        您可以尝试在您的应用程序委托中实现application:handleOpenURL:。 每当打开 url 时都应该调用此方法。在这里,您应该能够在您的 webview 中打开 URL。

        【讨论】:

          猜你喜欢
          • 2019-07-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-21
          • 1970-01-01
          • 1970-01-01
          • 2012-07-28
          相关资源
          最近更新 更多