How to open UITextView web links in a UIWebView in

2019-02-02 09:51发布

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 UITextView is not editable, and it perfectly detects web links and open them in Safari.

How to avoid that? How to grab that url so i can use with my own UIWebView?

3条回答
混吃等死
2楼-- · 2019-02-02 10:08

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.

查看更多
Animai°情兽
3楼-- · 2019-02-02 10:21

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
    }

}
查看更多
Evening l夕情丶
4楼-- · 2019-02-02 10:32

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;
}
查看更多
登录 后发表回答