How to open UITextView web links in a UIWebView instead of Safari?

前端 未结 3 1989
孤独总比滥情好
孤独总比滥情好 2020-12-28 08:32

I\'m developing and iPhone 3.0 application. And I\'m trying to open web links in a UITextView into a UIWebView instead of Safari. But still no luck.

The UIText

相关标签:
3条回答
  • 2020-12-28 08:52

    With Swift 3, UITextViewDelegate provides a textView(_:shouldInteractWith:in:interaction:) method. textView(_:shouldInteractWith:in:interaction:) has the following declaration:

    Asks the delegate if the specified text view should allow the specified type of user interaction with the given URL in the given range of text.

    optional func textView(_ textView: UITextView,  shouldInteractWith URL: URL,  in characterRange: NSRange,  interaction: UITextItemInteraction) -> Bool
    

    The following code shows how to open UITextView web links in a SFSafariViewController instead of opening them in Safari app:

    import UIKit
    import SafariServices
    
    class ViewController: UIViewController, UITextViewDelegate {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Set textView
            let textView = UITextView()
            textView.text = "http://www.yahoo.fr http://www.google.fr"
            textView.isUserInteractionEnabled = true
            textView.isEditable = false
            textView.isSelectable = true
            textView.dataDetectorTypes = UIDataDetectorTypes.link
    
            // Add view controller as the textView's delegate
            textView.delegate = self
    
            // auto layout
            view.addSubview(textView)
            textView.translatesAutoresizingMaskIntoConstraints = false
            textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
            textView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
            textView.heightAnchor.constraint(equalToConstant: 300).isActive = true
            textView.widthAnchor.constraint(equalToConstant: 300).isActive = true
        }
    
        func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
            // Open links with a SFSafariViewController instance and return false to prevent the system to open Safari app
            let safariViewController = SFSafariViewController(url: URL)
            present(safariViewController, animated: true, completion: nil)
    
            return false
        }
    
    }
    
    0 讨论(0)
  • 2020-12-28 09:11

    The simplest way is to override the webView:decidePolicyForNavigationAction:request:frame:decisionListener: method on UITextView like so:

    @interface UITextView (Override)
    @end
    
    @class WebView, WebFrame;
    @protocol WebPolicyDecisionListener;
    
    @implementation UITextView (Override)
    
    - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id < WebPolicyDecisionListener >)listener
    {
        NSLog(@"request: %@", request);
    }
    @end
    

    This will affect all UITextViews in your application. If you only require this on a single view, create a subclass and override the method on that.

    Note: this is technically a private API and could be removed at any time. There is no way to do this via the public API.

    edit: as of iOS 7.0 a new method has been introduced on UITextViewDelegate to support this. See nihad's answer for details.

    0 讨论(0)
  • 2020-12-28 09:12

    This is an old question but incase anyone is looking for an updated way of doing this.

    Assign your viewController that holds the UITextView as a delegate in your viewController's .m file and just add:

    -(BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange{
    
        //Do something with the URL
        NSLog(@"%@", URL);
    
    
        return NO;
    }
    
    0 讨论(0)
提交回复
热议问题