Swift 使用NSRange 查找字符多次出现的位置处理

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-23 06:34   92   0

NSRange是个使用频率比较高的对象,尤其是在设置富文本(AttributedString)的地方。自带的 rangeOfString 就可以查找某字符所在字符串中的位置。但如果要获取多次出现的位置信息就需要另辟蹊径了。如下代码实现了,获取多次出现的位置信息的方法,参考如下:

    /// 获取字符出现的位置信息(支持多次位置获取)
    /// - Parameter string: 原始文本
    /// - Parameter inString: 需要查找的字符
    private func rangeOfString(string:NSString,
                               andInString inString:String) -> [NSRange] {
        
        var arrRange = [NSRange]()
        var _fullText = string
        var rang:NSRange = _fullText.range(of: inString)
        
        while rang.location != NSNotFound {
            var location:Int = 0
            if arrRange.count > 0 {
                if arrRange.last!.location + arrRange.last!.length < string.length {
                     location = arrRange.last!.location + arrRange.last!.length
                }
            }

            _fullText = NSString.init(string: _fullText.substring(from: rang.location + rang.length))

            if arrRange.count > 0 {
                  rang.location += location
            }
            arrRange.append(rang)
            
            rang = _fullText.range(of: inString)
        }
        
        return arrRange
    }

Swift 中本身有 Range 对象,由于对其使用方法和特性不甚了解,故使用NSRange 对象。

引申一下,批量设置AttributedString,就需要使用到如上代码,具体参考代码如下:

    /// 批量设置富文本
    /// - Parameter textFont: 默认文本
    /// - Parameter textColor: 默认文本颜色
    /// - Parameter changeTexts: 需要改变的文本
    /// - Parameter changFonts: 需要改变的字体
    /// - Parameter changeColors: 需要改变的颜色
    /// - Parameter isLineThrough: 是否下划线
    func setAttributeStringTexts(FullTextFont textFont:UIFont,
                                 andFullTextColor textColor:UIColor,
                                 withChangeTexts changeTexts:[String],
                                 withChangeFonts changFonts:[UIFont],
                                 withChangeColors changeColors:[UIColor],
                                 isLineThrough:Bool = false) -> NSAttributedString{
        
        let strFullText:String = self
        
        var range:NSRange?
        var dicAttr:[NSAttributedString.Key:Any]?
        let attributeString = NSMutableAttributedString.init(string: strFullText)
        
        //不需要改变的文本
        range = NSString.init(string: strFullText).range(of: String.init(strFullText))
        
        dicAttr = [
            NSAttributedString.Key.font:textFont,
            NSAttributedString.Key.foregroundColor:textColor,
        ]
        attributeString.addAttributes(dicAttr!, range: range!)
        
        //需要改变的文本
        var index:Int = 0
        for item in changeTexts {
            //range = NSString.init(string: strFullText).range(of: item)
            let ranges = self.rangeOfString(string: NSString.init(string: strFullText), andInString: item)

            for range in ranges {
                dicAttr = [
                    NSAttributedString.Key.font:changFonts.count > index ? changFonts[index] : changFonts.first as Any,
                    NSAttributedString.Key.foregroundColor:changeColors.count > index ? changeColors[index] : changeColors.first as Any,
                ]
                
                if isLineThrough {
                    dicAttr?[NSAttributedString.Key.strikethroughStyle] = NSNumber.init(value: 1)
                }

                if range.location + range.length <= fullString.length {
                    attributeString.addAttributes(dicAttr!, range: range)
                }
            }
            
            index += 1
        }
        
        return attributeString
    }

以上代码使用效果详见如下图片:

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP