كيفية اعتراض انقر على الرابط في uitextview؟
-
23-09-2019 - |
سؤال
هل من الممكن إجراء إجراء مخصص عند لمس المستخدم رابط الهاتف المكتسب تلقائيًا في UITextView. من فضلك لا تنصح باستخدام UIWEBView بدلاً من ذلك.
ويرجى عدم تكرار النص فقط من مرجع فصول Apple - بالتأكيد لقد قرأته بالفعل.
شكرًا.
المحلول
تحديث: من iOS10,
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction;
من عند دائرة الرقابة الداخلية 7 و لاحقا UITextView
لديه طريقة المندوب:
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange *NS_DEPRECATED_IOS(7_0, 10_0, "Use textView:shouldInteractWithURL:inRange:forInteractionType: instead");*
لاعتراض النقرات على الروابط. وهذه هي أفضل طريقة للقيام بذلك.
ل iOS6 وفي وقت سابق طريقة لطيفة للقيام بذلك هي من خلال التصنيف الفرعي 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. استخدام UITextView
'س dataDetectorTypes
منشأه.
أبسط طريقة للتفاعل مع أرقام الهواتف أو عناوين 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. استخدام UITextViewDelegate
'س textView(_: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 تبدو هكذا في مفتش هوية الجزء الأيمن:
هاهو! الآن تحصل على الرابط انقر على الفور بدلاً من متى يجب أن يكون عنوان URL