سؤال

هل من الممكن إجراء إجراء مخصص عند لمس المستخدم رابط الهاتف المكتسب تلقائيًا في UITextView. من فضلك لا تنصح باستخدام UIWEBView بدلاً من ذلك.

ويرجى عدم تكرار النص فقط من مرجع فصول Apple - بالتأكيد لقد قرأته بالفعل.

شكرًا.

هل كانت مفيدة؟

المحلول

تحديث: من ,

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction;

من عند و لاحقا UITextView لديه طريقة المندوب:

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange *NS_DEPRECATED_IOS(7_0, 10_0, "Use textView:shouldInteractWithURL:inRange:forInteractionType: instead");*

لاعتراض النقرات على الروابط. وهذه هي أفضل طريقة للقيام بذلك.

ل وفي وقت سابق طريقة لطيفة للقيام بذلك هي من خلال التصنيف الفرعي UIApplication والكتابة -(BOOL)openURL:(NSURL *)url

@interface MyApplication : UIApplication {

}

@end

@implementation MyApplication


-(BOOL)openURL:(NSURL *)url{
    if  ([self.delegate openURL:url])
         return YES;
    else
         return [super openURL:url];
}
@end

ستحتاج إلى التنفيذ openURL: في المندوب الخاص بك.

الآن ، لتبدأ التطبيق بالفئة الفرعية الجديدة الخاصة بك UIApplication, ، حدد موقع الملف الرئيسي في مشروعك. في هذا الملف الصغير الذي يمسك التطبيق الخاص بك ، عادة ما يكون هناك هذا السطر:

int retVal = UIApplicationMain(argc, argv, nil, nil);

المعلمة الثالثة هي اسم الفصل لتطبيقك. لذلك ، استبدال هذا الخط لـ:

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

هذا فعل الخدعة لي.

نصائح أخرى

في iOS 7 أو بعد ذلك

يمكنك استخدام طريقة مندوب uitextview التالية:

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

يقوم عرض النص باستدعاء هذه الطريقة إذا كان المستخدم ينقر أو يضغط على رابط عنوان URL الطويل. تنفيذ هذه الطريقة اختياري. بشكل افتراضي ، يفتح عرض النص التطبيق المسؤول عن التعامل مع نوع عنوان URL ويمرر عنوان URL. يمكنك استخدام هذه الطريقة لإجراء إجراء بديل ، مثل عرض محتوى الويب في عنوان URL في عرض ويب داخل التطبيق الحالي.

الأهمية:

تكون الروابط في طرق العرض النصية تفاعلية فقط إذا كانت طريقة عرض النص قابلة للتحديد ولكنها غير قابلة للحفر. أي إذا كانت قيمة uitextview ، فإن الخاصية القابلة للاختيار هي نعم ، والخاصية القابلة للاتصال هي لا.

لسرعة 3

textView.delegate = self

extension MyTextView: UITextViewDelegate 

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

        GCITracking.sharedInstance.track(externalLink: URL)
        return true
    }
}

أو إذا كان الهدف> = iOS 10

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

النسخة السريعة:

يجب أن يبدو إعداد uitextview القياسي الخاص بك شيء من هذا القبيل ، لا تنسى المندوب و 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)

بعد انتهاء فصلك ، أضف هذه القطعة:

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 5 و iOS 12 ، يمكنك استخدام أحد الأنماط الثلاثة التالية من أجل التفاعل مع الروابط في أ UITextView.


#1. استخدام UITextViewdataDetectorTypes منشأه.

أبسط طريقة للتفاعل مع أرقام الهواتف أو عناوين URL أو العناوين في أ UITextView هو للاستخدام dataDetectorTypes منشأه. يوضح رمز العينة أدناه كيفية تنفيذه. باستخدام هذا الرمز ، عندما ينقر المستخدم على رقم الهاتف ، أ UIAlertController إعلان منبثق.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let textView = UITextView()
        textView.text = "Phone number: +33687654321"
        textView.isUserInteractionEnabled = true
        textView.isEditable = false
        textView.isSelectable = true
        textView.dataDetectorTypes = [.phoneNumber]
        textView.isScrollEnabled = false

        textView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(textView)
        textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        textView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
    }

}

#2. استخدام UITextViewDelegatetextView(_:shouldInteractWith:in:interaction:) طريقة

إذا كنت ترغب في تنفيذ بعض الإجراءات المخصصة بدلاً من صنع ملف UIAlertController تنبثق عند النقر على رقم الهاتف أثناء الاستخدام dataDetectorTypes, ، عليك أن تجعل UIViewController تتفق مع UITextViewDelegate بروتوكول وتنفيذ textView(_:shouldInteractWith:in:interaction:). يوضح الرمز أدناه كيفية تنفيذه:

import UIKit

class ViewController: UIViewController, UITextViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let textView = UITextView()
        textView.delegate = self
        textView.text = "Phone number: +33687654321"
        textView.isUserInteractionEnabled = true
        textView.isEditable = false
        textView.isSelectable = true
        textView.dataDetectorTypes = [.phoneNumber]
        textView.isScrollEnabled = false

        textView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(textView)
        textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        textView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
    }

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        /* perform your own custom actions here */
        print(URL) // prints: "tel:+33687654321"

        return false // return true if you also want UIAlertController to pop up
    }

}

#3. استخدام NSAttributedString و NSAttributedString.Key.link

كبديل ، يمكنك استخدام NSAttributedString وتعيين أ URL لها NSAttributedString.Key.link Attribute.the يعرض رمز العينة أدناه تنفيذًا محتملًا له. باستخدام هذا الرمز ، عندما ينقر المستخدم على السلسلة المنسوبة ، أ UIAlertController إعلان منبثق.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let attributedString = NSMutableAttributedString(string: "Contact: ")
        let phoneUrl = NSURL(string: "tel:+33687654321")! // "telprompt://+33687654321" also works
        let attributes = [NSAttributedString.Key.link: phoneUrl]
        let phoneAttributedString = NSAttributedString(string: "phone number", attributes: attributes)
        attributedString.append(phoneAttributedString)

        let textView = UITextView()
        textView.attributedText = attributedString
        textView.isUserInteractionEnabled = true
        textView.isEditable = false
        textView.isSelectable = true
        textView.isScrollEnabled = false

        textView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(textView)
        textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        textView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
    }

}

لم أحاول ذلك بنفسي ولكن يمكنك محاولة التنفيذ application:handleOpenURL: الطريقة في مندوب التطبيق الخاص بك - يبدو كل شيء openURL طلب تمرير من خلال هذا رد الاتصال.

لست متأكدًا من كيفية اعتراض رابط البيانات المكتشف ، أو نوع الوظيفة التي تحتاج إلى تشغيلها. ولكن قد تكون قادرًا على الاستفادة من طريقة ملعب TextField لإجراء اختبار/مسح من خلال ملعب Textfield إذا كنت تعرف ما الذي تبحث عنه .. مثل مقارنة السلاسل النصية التي تلبي ###-###- أو ابدأ بـ "www". للاستيلاء على هذه الحقول ، ولكن ستحتاج إلى كتابة رمز صغير لاستنشاق سلسلة TextFields ، وإعادة ما تحتاجه ، ثم استخراجه لاستخدام وظيفتك. لا أعتقد أن هذا سيكون صعبًا ، بمجرد تضييقك بالضبط ما تريده ، ثم ركزت على IF () تصفية () تصفية النمط المطابق المحدد للغاية لما تحتاجه.

من Couse هذا يعني أن المستخدم سوف يلمس مربع النص من أجل تنشيط deBeginediting (). إذا لم يكن هذا هو نوع تفاعل المستخدم الذي كنت تبحث عنه ، فيمكنك فقط استخدام مؤقت الزناد ، فإن ذلك يبدأ في ViewDidAppear () أو غيره بناءً على الحاجة وتمر عبر سلسلة TextFields ، ثم في نهاية سلسلة Textfield الطرق التي قمت بإنشائها ، يمكنك فقط إيقاف المؤقت.

application:handleOpenURL: يتم استدعاؤه عند فتح تطبيق آخر لك التطبيق عن طريق فتح عنوان URL مع مخطط يدعم تطبيقك. لا يسمى عندما يبدأ تطبيقك في فتح عنوان URL.

أعتقد أن الطريقة الوحيدة للقيام بما يريده فلاديمير هي استخدام UIWEBView بدلاً من uitextview. اجعل وحدة تحكم العرض الخاصة بك تنفذ UIWebViewDelegate ، وقم بتعيين مندوب UIWEBView على وحدة التحكم في العرض ، وفي تطبيق وحدة التحكم في العرض webView:shouldStartLoadWithRequest:navigationType: لفتح [request URL] في عرض بدلاً من الإقلاع عن تطبيقك وفتحه في Safari للجوال.

سويفت 4:

1) قم بإنشاء الفئة التالية (UITEXTVIEW الفرعية):

import Foundation

protocol QuickDetectLinkTextViewDelegate: class {
    func tappedLink()
}

class QuickDetectLinkTextView: UITextView {

    var linkDetectDelegate: QuickDetectLinkTextViewDelegate?

    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)

    }

    required init?(coder aDecoder: NSCoder) {
         super.init(coder: aDecoder)
    }

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let glyphIndex: Int? = layoutManager.glyphIndex(for: point, in: textContainer, fractionOfDistanceThroughGlyph: nil)
        let index: Int? = layoutManager.characterIndexForGlyph(at: glyphIndex ?? 0)
        if let characterIndex = index {
            if characterIndex < textStorage.length {
                if textStorage.attribute(NSLinkAttributeName, at: characterIndex, effectiveRange: nil) != nil {
                    linkDetectDelegate?.tappedLink()
                    return self
                }
            }
        }

        return nil
    }
}


2) أينما قمت بإعداد TextView الخاص بك ، افعل هذا:

//init, viewDidLoad, etc
textView.linkDetectDelegate = self

//outlet
@IBOutlet weak var textView: QuickDetectLinkTextView!

//change ClassName to your class
extension ClassName: QuickDetectLinkTextViewDelegate {
    func tappedLink() {
        print("Tapped link, do something")
    }
}


إذا كنت تستخدم لوحة العمل ، فتأكد من أن TextView تبدو هكذا في مفتش هوية الجزء الأيمن:
enter image description here



هاهو! الآن تحصل على الرابط انقر على الفور بدلاً من متى يجب أن يكون عنوان URL

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top