为了账号安全,请及时绑定邮箱和手机立即绑定

MGTextView

标签:
Swift
//
//  MGTextView.swift
//  MGSDKDemo
//
//  Created by Nicky Y M LIU_SP on 2021/3/9.
//  Copyright © 2021 Nicky Y M LIU_SP. All rights reserved.
//

import UIKit

class MGTextView: UITextView {
    public var placeHolderTextColor = UIColor.lightGray {
        didSet {
            placeHolderLabel.textColor = placeHolderTextColor
        }
    }
    public var placeHolderText = "请输入你的文字" {
        didSet {
            placeHolderLabel.text = placeHolderText
        }
    }
    private let placeHolderLabel = UILabel()
    
    
    public var linkTextColor: UIColor = UIColor.blue
    
    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
                
        self.linkTextAttributes = [:]
        placeHolderLabel.text = "写下你的问题或建议,我们将及时跟进解决(建议上传截图帮助我们解决问题,感谢!)"
        placeHolderLabel.numberOfLines = 0
        placeHolderLabel.font = UIFont.systemFont(ofSize: 15)
        placeHolderLabel.textColor = UIColor.lightGray
        placeHolderLabel.sizeToFit()
        self.addSubview(placeHolderLabel)
        self.setValue(placeHolderLabel, forKeyPath: "_placeholderLabel")
        self.font = placeHolderLabel.font
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @discardableResult
    func setTextWithLinkAttribute(text: String) -> NSMutableAttributedString? {
        
        // 正则匹配网址
        let regulaStr = "((http[s]{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)"
       
        let regularExpression = try? NSRegularExpression(pattern: regulaStr, options: NSRegularExpression.Options.caseInsensitive)
        
        guard let arrayOfAllMatches: [NSTextCheckingResult] = regularExpression?.matches(in: text, options: NSRegularExpression.MatchingOptions.init(rawValue: 0), range: NSMakeRange(0, text.count)) else { return nil }
        var resultArr = [String]()
        var rangeArr = [NSValue]()
        
        for match in arrayOfAllMatches  {
            
            if let range = text.range(from: match.range) {
                let substringForMatch = text.substring(with: range)
                resultArr.append(substringForMatch)
            }
        }
        
        let subStr = text
        for str in resultArr {
            if let value = self.rangesOfString(searchString: str, inString: subStr) {
                rangeArr.append(value)
            }
        }
        
        let attributedText = NSMutableAttributedString(string: subStr)
        for value in rangeArr {

            guard let index = rangeArr.firstIndex(of: value) else {
                continue
            }
            let range = value.rangeValue
            attributedText.addAttributes([NSAttributedString.Key.link: URL(string: resultArr[index])], range: range)
//            self.linkTextAttributes = [NSAttributedString.Key.foregroundColor: self.linkTextColor]
            attributedText.addAttributes([NSAttributedString.Key.foregroundColor: self.linkTextColor], range: range)
       }
        self.attributedText = attributedText
        return attributedText
    }
    
    // 获取查找字符串在母串中的NSRange
    
    func rangesOfString(searchString: String, inString: String) -> NSValue? {
        let searchRange = NSMakeRange(0, inString.count)
//        var range?
        let range = (inString as NSString).range(of: searchString, options: NSString.CompareOptions.init(rawValue: 0), range: searchRange)
        if range.location != NSNotFound {
            return NSValue(range: range)
        }
        return nil
    }
	
	/// 使用下标截取字符串 例: "示例字符串"[0..<2] 结果是 "示例"
    subscript (r: Range<Int>) -> String {
        get {
            if (r.lowerBound > count) || (r.upperBound > count) { return "截取超出范围" }
            let startIndex = self.index(self.startIndex, offsetBy: r.lowerBound)
            let endIndex = self.index(self.startIndex, offsetBy: r.upperBound)
            return String(self[startIndex..<endIndex])
        }set {
            if (r.lowerBound > count) || (r.upperBound > count) { return }
            let startIndex = self.index(self.startIndex, offsetBy: r.lowerBound)
            let endIndex = self.index(self.startIndex, offsetBy: r.upperBound)
            self.replaceSubrange(startIndex..<endIndex, with: newValue)
        }
    }
}


// MARK: - 
public extension String {
    /// range转换为NSRange
    func nsRange(from range: Range<String.Index>) -> NSRange {
        return NSRange(range, in: self)
    }

    /// NSRange转化为range
    func range(from nsRange: NSRange) -> Range<String.Index>? {
        guard
            let from16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location, limitedBy: utf16.endIndex),
            let to16 = utf16.index(from16, offsetBy: nsRange.length, limitedBy: utf16.endIndex),
            let from = String.Index(from16, within: self),
            let to = String.Index(to16, within: self)
            else { return nil }
        return from ..< to
    }
}

使用

override func viewDidLoad() {
        super.viewDidLoad()
        
        let ideaTextView = MGTextView()
        ideaTextView.placeHolderTextColor = UIColor.red
        ideaTextView.placeHolderText = "1234567890"
        ideaTextView.delegate = self
//        ideaTextView.isEditable = false
        ideaTextView.isSelectable = true
        ideaTextView.dataDetectorTypes = [.phoneNumber, .link]
        ideaTextView.backgroundColor = UIColor.orange
        ideaTextView.frame =  CGRect(x: 20, y: 200, width: 300, height: 200)
        ideaTextView.linkTextColor = UIColor.white
//        ideaTextView.text = "谷歌搜索好用http://www.google.com搜索用什么https://www.baidu.com百度一下你知道"
        ideaTextView.attributedText = NSMutableAttributedString(string: "谷歌搜索好用 http://www.google.com 搜索用什么 https://www.baidu.com 百度一下你知道3453555")
        ideaTextView.setTextWithLinkAttribute(text: "谷歌搜索好用http://www.google.com搜索用什么https://www.baidu.com百度一下你知道345355")
        self.view.addSubview(ideaTextView)
        
    }
	
	func addClick() {
		// 将UITextView中的内容进行调整(主要是在光标所在的位置进行字符串截取,再拼接你需要插入的文字即可)
        let content = ideaTextView.text!;
        let result = content[0..<location] + "MG123" + content[location..<content.count]
        // 将调整后的字符串添加到UITextView上面
        ideaTextView.text = result
	}
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消