web-dev-qa-db-ja.com

swiftを使用したUILabelのNSAttributedStringクリックイベント

AttributedStringがあるとします:「すでにアカウントをお持ちですか?サインイン!」この文字列をUILabelに配置しています。これで、ユーザーが「サインイン!」をクリックすると、現在のviewControllerが別のviewControllerに移動するか、サインインをクリックしているときにいくつかの関数が呼び出されます。

コードや提案は問題ありません。

8
Rishu Agrawal

一部の回答では、別のジェスチャー認識機能を使用する必要はありません。代わりに、属性付きテキストをUITextViewDelegateの-​​ textView:shouldInteractWithURL:inRange:interaction: メソッドと組み合わせて使用​​して、これを実現できます。例:

class ViewController: UIViewController, UITextViewDelegate {

    @IBOutlet weak var textView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let text = NSMutableAttributedString(string: "Already have an account? ")
        text.addAttribute(NSAttributedString.Key.font, value: UIFont.systemFont(ofSize: 12), range: NSMakeRange(0, text.length))

        let selectablePart = NSMutableAttributedString(string: "Sign in!")
        selectablePart.addAttribute(NSAttributedString.Key.font, value: UIFont.systemFont(ofSize: 12), range: NSMakeRange(0, selectablePart.length))
        // Add an underline to indicate this portion of text is selectable (optional)
        selectablePart.addAttribute(NSAttributedString.Key.underlineStyle, value: 1, range: NSMakeRange(0,selectablePart.length))
        selectablePart.addAttribute(NSAttributedString.Key.underlineColor, value: UIColor.black, range: NSMakeRange(0, selectablePart.length))
        // Add an NSLinkAttributeName with a value of an url or anything else
        selectablePart.addAttribute(NSAttributedString.Key.link, value: "signin", range: NSMakeRange(0,selectablePart.length))

        // Combine the non-selectable string with the selectable string
        text.append(selectablePart)

        // Center the text (optional)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = NSTextAlignment.center
        text.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, text.length))

        // To set the link text color (optional)
        textView.linkTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor.black, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12)]
        // Set the text view to contain the attributed text
        textView.attributedText = text
        // Disable editing, but enable selectable so that the link can be selected
        textView.isEditable = false
        textView.isSelectable = true
        // Set the delegate in order to use textView(_:shouldInteractWithURL:inRange)
        textView.delegate = self
    }

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

        // **Perform sign in action here**

        return false
    }
}
14
Lyndsey Scott

@ Lindsey Scott 回答に基づく言語の更新:)

Swift 4

class ViewController: UIViewController, UITextViewDelegate {

    @IBOutlet weak var textView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let text = NSMutableAttributedString(string: "Already have an account? ")
        text.addAttribute(NSAttributedStringKey.font,
                          value: UIFont.systemFont(ofSize: 12),
                          range: NSRange(location: 0, length: text.length))

        let interactableText = NSMutableAttributedString(string: "Sign in!")
        interactableText.addAttribute(NSAttributedStringKey.font,
                                      value: UIFont.systemFont(ofSize: 12),
                                      range: NSRange(location: 0, length: interactableText.length))

        // Adding the link interaction to the interactable text
        interactableText.addAttribute(NSAttributedStringKey.link,
                                      value: "SignInPseudoLink",
                                      range: NSRange(location: 0, length: interactableText.length))

        // Adding it all together
        text.append(interactableText)

        // Set the text view to contain the attributed text
        textView.attributedText = text

        // Disable editing, but enable selectable so that the link can be selected
        textView.isEditable = false
        textView.isSelectable = true
        textView.delegate = self
    }

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

        //Code to the respective action

        return false
    }
}
3

Labelの代わりに、textviewを使用してView Controllerを開くか、部分文字列をクリック可能にすることができます

  1. クリック可能にしたい文字列の属性を作成する

    let linkAttributes = [
        NSLinkAttributeName: NSURL(string: "https://www.Apple.com")!,
        NSForegroundColorAttributeName: UIColor.blue
        ] as [String : Any]
    
  2. 文字列を属性付き文字列にします

    let attributedString = NSMutableAttributedString(string:"My name is Jarvis")
    attributedString.setAttributes(linkAttributes, range: NSMakeRange(5, 10))
    

    ここでカスタム範囲を指定できます。

  3. テキストビューに属性付きテキストを追加する

    YourTextView.attributedText = attributedString 
    
  4. 次に、次のtextviewのデリゲートメソッドを実装して、Urlの相互作用を実装します。

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
    // here write your code of navigation 
    return false 
    }
    
  5. ラベルでそれをしたい場合は、ここをクリックしてください( aのNSAttributedStringでクリック可能なリンクを作成する方法

3

ラベル/ビューにタップジェスチャーレコグナイザーを追加するか、カスタムURLプロトコルを使用してリンクを属性付き文字列に埋め込み、UITextViewを使用して、リンク検出をオンにすることができます。次に、リンクに応答するためにUITextViewデリゲートメソッドを実装する必要があります。

編集:

UITextViewにクリック可能なリンクを実装する DatesInSwift (link)というデモプロジェクトがGithubにあります。 _ViewController.Swift_のUITextViewデリゲートメソッドtextView(_:shouldInteractWithURL:inRange)をご覧ください。これは、URLに応答する必要があることをテキストビューに伝えるメソッドです。

次に、UIApplicationDelegateメソッドを実装して、URLを処理する必要があります。サンプルアプリは、iOS 9で廃止されたapplication(_:openURL:sourceApplication:annotation)を使用します。新しい開発では、代わりにapplication(_:openURL:options:)を使用する必要があります。

埋め込みURLをクリックしてアプリを呼び出すには、CFBundleURLTypes/CFBundleURLSchemesエントリをinfo.plistに追加して、カスタムURLスキーム(_myompany.myapp.loginURL_など)を登録する必要もあります。

2
Duncan C