【问题标题】:Swift - Add URL with AttributedString to UITextViewSwift - 将带有 AttributedString 的 URL 添加到 UITextView
【发布时间】:2017-03-29 10:02:53
【问题描述】:

当我按下按钮时,我正在尝试向我的 uitextview 添加一个链接。

到目前为止,我已经做到了,但是如果我开始在 UITextView 中编辑文本,它会继续作为链接。

我有很多人设法通过为属性文本添加一个范围来进行排序,这很有效,但是如果我返回并删除例如 URL(attributedString) 文本现在又是一个属性字符串(link) ...

这是我的一些代码:

  @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) {
        }


     }

【问题讨论】:

  • 可能在选择更改时设置typingAttributes span>
  • @Larme 我实际上在 5 分钟前阅读了一篇关于 typingAttributed 的帖子,但不确定它是如何工作的,你认为这可行吗?

标签: ios swift uitextview


【解决方案1】:

您需要使用 UITextView 委托功能:

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>

【讨论】:

  • 刚刚测试过好像还可以,我会把它放在我的应用程序中,稍后试试,非常感谢现在+1!
  • 是的,我已经测试过了,到目前为止效果很好,但唯一的问题是,它改变了所有的文本字体。例如:我的文本视图中有一些粗体文本和斜体文本,但是在插入链接后,所有文本都被设置回正常的系统字体。知道为什么吗?
  • 你可以在这一行设置你的属性: let attributesString = NSMutableAttributedString(string: text, attributes: nil)
  • 当我插入 url 链接时它会被重置,但不会留出空间
  • 知道为什么会这样吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-18
  • 2021-07-16
  • 1970-01-01
  • 1970-01-01
  • 2016-10-03
  • 2012-10-27
相关资源
最近更新 更多