Как открывать веб-ссылки UITextView в UIWebView вместо Safari?

Разрабатываю и приложение для iPhone 3.0. И я пытаюсь открывать веб-ссылки в UITextView в UIWebView вместо Safari. Но все равно не повезло.

UITextView не редактируется, он отлично определяет веб-ссылки и открывает их в Safari.

Как этого избежать? Как получить этот URL-адрес, чтобы я мог использовать его со своим UIWebView?


person lucadb    schedule 20.08.2009    source источник


Ответы (3)


Самый простой способ - переопределить _ 1_ в UITextView вот так:

@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

Это повлияет на все UITextView в вашем приложении. Если вам это нужно только для одного представления, создайте подкласс и переопределите метод для него.

Примечание: технически это частный API, который может быть удален в любое время. Это невозможно сделать через общедоступный API.

edit: начиная с iOS 7.0 в UITextViewDelegate был введен новый метод для поддержки этого. Подробности см. В ответе Нихада.

person rpetrich    schedule 20.08.2009
comment
Хм, если быть конфиденциальным, как вы думаете, это будет проблемой для утверждения в магазине приложений? Кстати, сегодня вечером я проверю ваш код и дам вам знать. Спасибо. - person lucadb; 20.08.2009
comment
Это не то, что они могут проверить, но вы можете подвергнуться небольшому риску будущих изменений ОС (это общедоступный API в настольном эквиваленте, и маловероятно, что Apple перестанет использовать WebKit, но это возможно). Худшее, что может случиться, - это возврат к поведению по умолчанию при запуске MobileSafari. - person rpetrich; 20.08.2009
comment
Хороший! Другой ответ - переопределить [UIApplication openURL: (NSURL *) url] stackoverflow.com/questions/1889262/ - person tt.Kilew; 12.02.2010
comment
@crash - вы когда-нибудь отправляли приложение, используя этот код? Было ли оно отклонено или прошло? Есть ли у кого-нибудь еще здесь какие-либо приложения, одобренные с использованием этого кода? - person Jasarien; 22.03.2010
comment
Я бы не стал рисковать. Я не уверен, что создание подкласса UIApplication и переопределение openURL: считается закрытым; возможно, но он ближе к публичным API, чем мой ответ - person rpetrich; 22.03.2010
comment
Apple теперь выполняет машинное сканирование кода на наличие нелегальных API. Я уверен, что сейчас это не пройдет. - person Rog; 24.03.2010
comment
Я никогда не отправлял приложение, использующее этот код. Я полностью согласен с @rpetrich и @Roger Nolan - person lucadb; 27.03.2010
comment
@rpetrich Может кто-нибудь уточнить, куда бы я поместил код выше? Я занимаюсь разработкой некоторых приложений около 6 месяцев, но все еще не уверен в файловой структуре и во всем, что связано с расширением базовых классов. Куда бы я поместил этот код и какое имя файла ему нужно? Я знаю, как это сделать при создании подкласса UITextView, но если этого не сделать, то куда это денется? - person sunny; 23.06.2015

Это старый вопрос, но на тот случай, если кто-то ищет обновленный способ сделать это.

Назначьте свой viewController, который содержит UITextView в качестве делегата в файле .m вашего viewController, и просто добавьте:

-(BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange{

    //Do something with the URL
    NSLog(@"%@", URL);


    return NO;
}
person nihad    schedule 17.11.2013
comment
Я считаю, что это правильный способ для iOS 7. Это помогло мне, так что спасибо! - person ajfigueroa; 10.02.2014
comment
@nihad Большое спасибо, это кажется чище и проще, чем старое решение. - person sunny; 23.06.2015

В Swift 3 UITextViewDelegate предоставляет метод textView(_:shouldInteractWith:in:interaction:). textView(_:shouldInteractWith:in:interaction:) имеет следующее объявление:

Спрашивает делегата, должно ли указанное текстовое представление разрешать указанный тип взаимодействия пользователя с заданным URL-адресом в заданном диапазоне текста.

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

В следующем коде показано, как открывать UITextView веб-ссылки в SFSafariViewController вместо того, чтобы открывать их в приложении Safari:

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
    }

}
person Imanou Petit    schedule 24.01.2017