iPhone SDK - 在 Web 视图中打开 UITextView 中的链接

发布于 2024-08-13 22:19:03 字数 139 浏览 3 评论 0原文

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

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

I have specified dataDetectorTypes on a UITextView so that URLs open in Safari when touched.

Is it possible to intercept this behaviour so I load the URL in a UIWebView instead? Or would I have write my own URL detector code to re-route this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

谈场末日恋爱 2024-08-20 22:19:03

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

一切都需要自定义完成,因为 Apple 会将所有 http://https:// URL 开头发送到 Safari。

You would have to do the URL detection yourself and manually load the UIWebView when the URL is tapped.

Everything needs to be custom-done because Apple sends all http:// and https:// URL openings to Safari.

烟柳画桥 2024-08-20 22:19:03

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

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

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

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

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

The answer above that works best is the replacement of method implementation for [UIApplication openURL:]

Another way to achieve that, without using runtime.h is to subclass UIApplication. Then, override the openURL: selector. With this approach, you can call [super openURL:] from your subclass for URLs you want the default handling for. It also seems a little cleaner to me since you don't need to mess with the internal method implementations of the classes.

If you choose this approach, though, there are 2 other important steps. In the main.m file you need to change the 3rd argument to the UIApplicationMain function call so that it matches the name of your subclass:

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

Also, you should probably change the class of the File's Owner in your MainWindow.xib file from UIApplication to your subclass.

梦在深巷 2024-08-20 22:19:03

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

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 时,只需调用此方法即可将 openURL 实现与您的 customOpenURL 实现交换。

查看演示应用了解更多详细信息。希望这有帮助! :)

编辑

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

I did everyone a favor and answered your question with a blog post and demo app.

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

To expand on tt.Kilew's post, you create the category, but call your method something else such as customOpenURL. When you want to go back to Safari you do something called Method Swizzling. It looks like this:

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

Just call this method to swap the openURL implementation with your customOpenURL implementation when you do and don't want to use Safari.

Check out the demo app for more detail. Hope this helps! :)

Edit

If you don't want to risk your app getting rejected, you might want to check out a custom UITextView I developed to better suit the situation: https://github.com/marksands/MSTextView

濫情▎り 2024-08-20 22:19:03

另一个答案:)对我来说效果很好的是重新实现 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];
}

Another Answer :) That works fine for me is to re-implement 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];
}
梦幻的心爱 2024-08-20 22:19:03

Swift 版本:

您的标准 UITextView 设置应该如下所示,不要忘记 delegate 和 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
    }
}

Swift version:

Your standard UITextView setup should look something like this, don't forget the delegate and 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)

After your class ends add this piece:
Note that you need https://github.com/TransitApp/SVWebViewController this library, which is the best one out there as far as I know.

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
    }
}
绝不服输 2024-08-20 22:19:03

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

You can try implementing application:handleOpenURL: in your Application Delegate.
This method should get called whenever a url gets opened. Here you should be able to make the URL open in your webview.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文