iPhone SDK - opening links in a UITextView in a web view

前端 未结 6 1576
被撕碎了的回忆
被撕碎了的回忆 2021-01-06 18:00

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 UIWebV

相关标签:
6条回答
  • 2021-01-06 18:38

    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];
    }
    
    0 讨论(0)
  • 2021-01-06 18:44

    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
        }
    }
    
    0 讨论(0)
  • 2021-01-06 18:48

    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.

    0 讨论(0)
  • 2021-01-06 18:48

    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.

    0 讨论(0)
  • 2021-01-06 18:48

    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

    0 讨论(0)
  • 2021-01-06 19:04

    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.

    0 讨论(0)
提交回复
热议问题