iOS - UITextview的简单使用

UITextView继承于UIScrollView,所以它也是一个可滚动控件。UITextView是我们开发过程中显示多行文本的首选,它支持显示大量文本内容,并且支持使用自定义样式信息和编辑功能。


首先我们创建一个UITextView,并设置部分属性

class ViewController: UIViewController {
    lazy var textView: UITextView = {
        let tv = UITextView()
        // 背景颜色
        tv.backgroundColor = UIColor.gray
        // 文本内容
        tv.text = "患难可以试验一个人的品格;非常的境遇才可以显出非常的气节;,风平浪静的海面,所有的船只都可以并驱竞争;命运的铁拳击中要害的时候,只有大勇大智的人才能够处之泰然。——莎士比亚"
        // 文本颜色
        tv.textColor = UIColor.white
        // 文本字体大小
        tv.font = UIFont.systemFont(ofSize: 18.0)
        // 文本对齐方式
        tv.textAlignment = .center
        return tv
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        addTextView()
    }
    
    func addTextView() {
        view.addSubview(textView)
        textView.snp.makeConstraints { (make) in
            make.left.top.right.bottom.equalToSuperview().inset(50)
        }
    }
}

效果如下:


iOS - UITextview的简单使用_第1张图片

常用属性


是否可以选中操作

textView.isSelectable = true

默认是true,可以选中,一旦设置为false,将不能够进行选中操作,默认可选中效果



iOS - UITextview的简单使用_第2张图片


富文本,可以通过设置attributedText属性设置文本样式,如:

  // 创建可变属性字符串
  let attribute = NSMutableAttributedString(string: textView.text)
  // 设置段落样式
  let paragraphStyle = NSMutableParagraphStyle()
  paragraphStyle.alignment = .center
  paragraphStyle.lineSpacing = 10
  // 设置属性字典
  let dic = [NSAttributedStringKey.foregroundColor: UIColor.red,
             NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 22.0),
             NSAttributedStringKey.paragraphStyle: paragraphStyle]
  // 添加属性字典
  attribute.addAttributes(dic, range: NSMakeRange(16, textView.text.count - 16))
  // 设置textView的attributedText
  textView.attributedText = attribute


iOS - UITextview的简单使用_第3张图片


输入视图

func addInputVeiw() {
    let inputView = UIView(frame: CGRect(x: 0, y: 0, width: view.bounds.size.width, height: 200))
    inputView.backgroundColor = UIColor.red
    textView.inputView = inputView
}


iOS - UITextview的简单使用_第4张图片


输入键盘附属视图

func addInputAccessoryView(){
    let inputAccessoryView = UIView(frame: CGRect(x: 0, y: 0, width: view.bounds.size.width, height: 100))
    inputAccessoryView.backgroundColor = UIColor.red
    textView.inputAccessoryView = inputAccessoryView
}
iOS - UITextview的简单使用_第5张图片



获得焦点后选中现有文本内容,输入内容时清除当前选中文本内容

textView.clearsOnInsertion = true

iOS - UITextview的简单使用_第6张图片


文本内容与边界的间距

textView.textContainerInset = UIEdgeInsetsMake(20, 20, 20, 20)

iOS - UITextview的简单使用_第7张图片


设置光标颜色

textView.tintColor = UIColor.red


代理函数


对于textView的输入进行监听,我们经常设置delegate,相关方法如下:

extension ViewController: UITextViewDelegate {
    //将要开始编辑
    func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
        return true
    }
    //将要开始编辑
    func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
        return true
    }
    //已经开始编辑
    func textViewDidBeginEditing(_ textView: UITextView) {
    }
    //结束编辑
    func textViewDidEndEditing(_ textView: UITextView) {
    }
    //文本将要改变
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        return true
    }
    //文本发生改变
    func textViewDidChange(_ textView: UITextView) {
    }
    //焦点发生改变
    func textViewDidChangeSelection(_ textView: UITextView) {
    }
    //是否允许对文本中的URL进行操作
    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
        return true
    }
    //是否允许对文本中的富文本进行操作
    func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange) -> Bool {
      return true
    }
}

通知

extension NSNotification.Name {
    
    public static let UITextViewTextDidBeginEditing: NSNotification.Name

    public static let UITextViewTextDidChange: NSNotification.Name

    public static let UITextViewTextDidEndEditing: NSNotification.Name
}


常用功能


1)UITextView显示边框

textView.layer.borderColor = UIColor.cyan.cgColor
textView.layer.borderWidth = 2.0

iOS - UITextview的简单使用_第8张图片

2)根据textView的内容计算textView的大小,参考

首先设置textView不可滚动,否则每次换行都会滚动一下

func addTextView() {
    view.addSubview(textView)
    textView.snp.makeConstraints { (make) in
        make.left.top.right.equalToSuperview().inset(50)
        make.height.equalTo(40)
    }
    textView.isScrollEnabled = false
}

然后在文本改变的代理方法中计算

 //文本发生改变
  func textViewDidChange(_ textView: UITextView) {
      let fixedWidth = textView.frame.size.width
      let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.infinity))
      //更新高度约束
      textView.snp.updateConstraints { (make) in
          make.height.equalTo(newSize.height)
      }
 }

iOS - UITextview的简单使用_第9张图片


3)限制文字输入的个数,参考这里

 func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
     if(textView.text.count > 20 && range.length == 0) {
        print("Please summarize in 20 characters or less")
            return false
     }
   return true
}

或者使用如下方法进行更准确控制,输入到最大数量之后无法输入:

 func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        let selectedRange = textView.markedTextRange
        var pos: UITextPosition? = nil
        if let _sel = selectedRange {
            pos = textView.position(from: _sel.start, offset: 0)
        }
        if selectedRange != nil, pos != nil {
            let startOffset = textView.offset(from: textView.beginningOfDocument, to: selectedRange!.start)
            if startOffset < maxCount {
                return true
            } else {
                return false
            }
        }

        let comcatStr = (textView.text as NSString).replacingCharacters(in: range, with: text)
        let canInputLen = maxCount - comcatStr.length

        if canInputLen >= 0 {
            return true
        } else {
            let len = text.length + canInputLen
            let rg = NSRange.init(location: 0, length: max(len, 0))

            if rg.length > 0 {
                var s = ""
                if text.canBeConverted(to: .ascii) {
                    s = (text as NSString).substring(with: rg)
                } else {
                    var idx = 0
                    var trimString = ""
                    (text as NSString).enumerateSubstrings(in: NSRange(location: 0, length: text.length), options: .byComposedCharacterSequences, using: { (subString, _, _, stop) in
                        if idx >= rg.length {
                            stop.pointee = true
                            return
                        }
                        trimString = (trimString as NSString).appending(subString ?? "")
                        idx += 1
                    })
                    s = trimString
                }
                textView.text = (textView.text as NSString).replacingCharacters(in: range, with: s)
            }
            return false
        }
    }

    func textViewDidChange(_ textView: UITextView) {
        let selectedRange = textView.markedTextRange
        var pos: UITextPosition? = nil
        if let _sel = selectedRange {
            pos = textView.position(from: _sel.start, offset: 0)
        }
        if selectedRange != nil, pos != nil {
            return
        }

        let textViewText: String = textView.text
        let existTextNum = textViewText.length
        if existTextNum > maxCount {
            let s = (textViewText as NSString).substring(to: maxCount)
            textView.text = s
        }
    }

4)添加默认文字placeholder

方法一,添加一个label,通过监听是否输入内容来控制是否显示

首先创建一个label

 lazy var palceholderLabel: UILabel = {
        let label = UILabel(frame: CGRect(origin: CGPoint(x: 5, y: 5), size: CGSize.zero))
        label.text = "input some..."
        label.textColor = UIColor.lightGray
        label.sizeToFit()
        return label
    }()
添加到textView上

 textView.addSubview(palceholderLabel)
根据输入的内容控制是否显示

func textViewDidChange(_ textView: UITextView) {
    palceholderLabel.isHidden = !textView.text.isEmpty
}

iOS - UITextview的简单使用_第10张图片


其他的方式,可以看这里


5)自定义选择内容菜单栏

我们再看新闻的时候,常常在点选文字后会弹出菜单进行选择,复制等操作。这里我们也可以自己在菜单栏上添加一些其他内容,比如:分享到朋友圈,邮件。

  func customMenu() {
        let mail = UIMenuItem(title: "邮件", action: #selector(ViewController.onMail))
        let weixin = UIMenuItem(title: "分享到朋友圈", action: #selector(ViewController.shareToWeiChat))
        let menu = UIMenuController()
        menu.menuItems = [mail,weixin]
    }
    
    @objc func onMail(){
        print("mail")
    }
    
    @objc func shareToWeiChat(){
        print("shareToWeiChat")
    }

iOS - UITextview的简单使用_第11张图片

6)使用textView显示html内容,参考

func addHtml() {
    let htmlString = "" +
            "" +
            "" +
            "" +
            "" +
            "

A title

" + "

A paragraph

" + "bold text" + "" let htmlData = NSString(string: htmlString).data(using: String.Encoding.unicode.rawValue) let options = [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html] let attributedString = try! NSAttributedString(data: htmlData!, options: options, documentAttributes: nil) textView.attributedText = attributedString }

iOS - UITextview的简单使用_第12张图片


7)获取选中的文本内容

 //焦点发生改变
    func textViewDidChangeSelection(_ textView: UITextView) {
        if let selectedRange = textView.selectedTextRange {
            let selectedText = textView.text(in: selectedRange)
        }
    }

8)修改光标的位置,主要是对selectedRange属性进行修改,设置开始的位置,如,从第三个文字开始显示光标

textView.selectedRange = NSRange(location: 3, length: 0)
textView.becomeFirstResponder()


iOS - UITextview的简单使用_第13张图片


9)为textView添加文字间距

如果是为静态显示的textView的内容设置行间距,操作方法跟label一样

  let paragraphStyle = NSMutableParagraphStyle()
  paragraphStyle.lineSpacing = 10
  let attributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 20),
                    NSAttributedStringKey.paragraphStyle: paragraphStyle]
  textView.attributedText = NSAttributedString(string: "人找到生活的意义才是幸福的。时间是大公无私的语言。", attributes: attributes)

对于动态输入,想要改变行间距,实现代理方法即可

 func textViewDidChange(_ textView: UITextView) {
      // 判断是否有候选字符,如果不为nil,代表有候选字符,那么不执行操作
      if textView.markedTextRange == nil {
            // 这里可以自行加判断,设置一次行间距即可,没必要反复设置
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = 10
            let attributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 20),
                              NSAttributedStringKey.paragraphStyle: paragraphStyle]
            textView.attributedText = NSAttributedString(string: textView.text, attributes: attributes)
        }
  }








你可能感兴趣的:(iOS,常用UI控件)