ios - Swift - 将带有 AttributedString 的 URL 添加到 UITextView

标签 ios swift uitextview

当我按下按钮时,我试图向我的 uitextview 添加链接。

到目前为止,我已经成功做到了这一点,但如果我开始编辑 UITextView 中的文本,它会继续作为链接。

我有很多人设法通过添加属性文本的范围来进行排序,这是有效的,但是如果我返回并删除例如 URL(attributedString),则文本现在再次全部是属性字符串(链接) ...

这是我的一些代码:

  @IBAction func webLink(_ sender: Any) {
        let alertController = UIAlertController(title: "Insert Link", message: "", preferredStyle: .alert)


        alertController.addTextField { (textField) in
            textField.placeholder = "URL"
            textField.keyboardType = .URL

        }

        alertController.addTextField { (textField) in
            textField.placeholder = "Link name"
            textField.keyboardType = .default
        }

        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
            self.dismiss(animated: true, completion: nil)
        }

        let insertAction = UIAlertAction(title: "Insert", style: .default) { (action) in


            let systemFont = self.Text.font!
            let linkAttributes = [
                NSFontAttributeName : systemFont,
                NSLinkAttributeName: NSURL(string: alertController.textFields![0].text!)!] as [String : Any]

            let myAttributes2 = [ NSForegroundColorAttributeName: customGreen ]
            let attributedString = NSMutableAttributedString(string: "\(alertController.textFields![1].text!)   ")

            // Set the 'click here' substring to be the link
            attributedString.setAttributes(linkAttributes, range: NSMakeRange(0, 3))

            self.Text.linkTextAttributes = myAttributes2
            self.Text.textStorage.insert(attributedString, at: self.Text.selectedRange.location)

            let cursor = NSRange(location: self.Text.selectedRange.location + "\(alertController.textFields![1].text!)   ".characters.count, length: 0)
            self.Text.selectedRange = cursor
            self.Text.font = systemFont

        }

        alertController.addAction(cancelAction)
        alertController.addAction(insertAction)


        self.present(alertController, animated: true) {
        }


     }

最佳答案

您需要使用 UITextView 委托(delegate)函数:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {...}

在该函数中,您不能用您的属性覆盖插入“”(空格)字符。

About string attributes

Swift 3 中的完整示例

ViewController.swift

import UIKit

class ViewController: UIViewController, UITextViewDelegate {

@IBOutlet var textView: UITextView!

override func viewDidLoad() {
    super.viewDidLoad()
    self.textView.delegate = self
}

@IBAction func webLink(_ sender: AnyObject) {
    let alertController = UIAlertController(title: "Insert Link", message: "", preferredStyle: .alert)

    alertController.addTextField { (textField) in
        textField.placeholder = "URL"
        textField.keyboardType = .URL
    }

    alertController.addTextField { (textField) in
        textField.placeholder = "Link name"
        textField.keyboardType = .default
    }

    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
        self.dismiss(animated: true, completion: nil)
    }

    let insertAction = UIAlertAction(title: "Insert", style: .default) { (action) in

        if let urlName = alertController.textFields![1].text {

            let systemFont = self.textView.font!
            let linkAttributes = [
                NSFontAttributeName : systemFont,
                NSLinkAttributeName: NSURL(string: alertController.textFields![0].text!)!] as [String : Any]

            let myAttributes2 = [ NSForegroundColorAttributeName: UIColor.green]

            let attributedString = NSMutableAttributedString(string: urlName)

            // Set the 'click here' substring to be the link
            attributedString.setAttributes(linkAttributes, range: NSMakeRange(0, urlName.characters.count))

            self.textView.linkTextAttributes = myAttributes2
            self.textView.textStorage.insert(attributedString, at: self.textView.selectedRange.location)

            let cursor = NSRange(location: self.textView.selectedRange.location + urlName.characters.count, length: 0)
            self.textView.selectedRange = cursor
            self.textView.font = systemFont
        }
    }

    alertController.addAction(cancelAction)
    alertController.addAction(insertAction)

    self.present(alertController, animated: true) {}
}
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

    if text == " " {
        let attributes = [NSForegroundColorAttributeName: UIColor.black, NSFontAttributeName: self.textView.font!] as [String : Any]
        let attributedString = NSMutableAttributedString(string: text, attributes: attributes)
        self.textView.textStorage.insert(attributedString, at: range.location)
        let cursor = NSRange(location: self.textView.selectedRange.location+1, length: 0)
        textView.selectedRange = cursor
        return false
    }
    return true
}
}

Main.storyboard

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<dependencies>
    <deployment identifier="iOS"/>
    <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
    <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
    <!--View Controller-->
    <scene sceneID="tne-QT-ifu">
        <objects>
            <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="stackoverflow_40611248" customModuleProvider="target" sceneMemberID="viewController">
                <layoutGuides>
                    <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                    <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
                </layoutGuides>
                <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                    <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                    <subviews>
                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MAb-bM-rda">
                            <state key="normal" title="Button"/>
                            <connections>
                                <action selector="webLink:" destination="BYZ-38-t0r" eventType="touchUpInside" id="lEW-xK-QqL"/>
                            </connections>
                        </button>
                        <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="NfR-7H-lIY">
                            <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                            <constraints>
                                <constraint firstAttribute="width" constant="240" id="oZX-gx-ivA"/>
                            </constraints>
                            <string key="text">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.</string>
                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
                            <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
                        </textView>
                    </subviews>
                    <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                    <constraints>
                        <constraint firstItem="MAb-bM-rda" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="EUe-Ac-j39"/>
                        <constraint firstItem="NfR-7H-lIY" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="162" id="LtY-X7-xvc"/>
                        <constraint firstItem="MAb-bM-rda" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="XWA-IA-8Bd"/>
                        <constraint firstItem="MAb-bM-rda" firstAttribute="top" secondItem="NfR-7H-lIY" secondAttribute="bottom" constant="8" symbolic="YES" id="cUB-uR-AvM"/>
                        <constraint firstItem="NfR-7H-lIY" firstAttribute="centerX" secondItem="MAb-bM-rda" secondAttribute="centerX" id="pyb-a7-lJG"/>
                    </constraints>
                </view>
                <connections>
                    <outlet property="textView" destination="NfR-7H-lIY" id="vYj-cp-6P8"/>
                </connections>
            </viewController>
            <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
        </objects>
    </scene>
</scenes>
</document>

关于ios - Swift - 将带有 AttributedString 的 URL 添加到 UITextView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40611248/

相关文章:

ios - 最小正浮点值是多少?

iphone - iOS 中带有建议列表的 Textview

iOS 11 - 禁用智能引号

ios - 递归调用viewDidLoad,崩溃

ios - 为 Apple 的 DeviceCheck API 生成 JWT

swift - 我无法使用 ubuntu14.04 在 docker 中快速运行

ios - 为什么没有列出 UITableViewCell 的 Separator View?

ios - Swift 字符串中的换行符和/或回车符

ios - 自定义键盘返回标题设置 IOS8

macos - Parse.com 刷新用户信息