如何快速突出显示UITextView的文本? [英] How to highlight a UITextView's text line by line in swift?

查看:64
本文介绍了如何快速突出显示UITextView的文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在UITextView中逐行突出显示文本.我想遍历每行并突出显示该行以供用户查看,然后我想删除突出显示效果以为下一行做准备.我尝试创建解决方案失败了,这是我目前最好的机会.

I am trying to highlight line by line the text in a UITextView. I want to iterate over each line and highlight that one for the user to see, then I want to remove the highlighting effect in preparation for the next line. I have tried and failed to create a solution and this is my best chance right now.

这是到目前为止我一直在努力的工作,由于某种原因,它目前在UITextView中用"NSBackgroundColor 1101"填充,我不知道为什么.

Here is some of what I have been working on so far, it currently fills the UITextView with "NSBackgroundColor 1101" for some reason and I do not know why that is.

func highlight() {
        let str = "This is\n some placeholder\n text\nwith newlines."
        var newStr = NSMutableAttributedString(string: "")
        var arr:[String] = str.components(separatedBy: "\n")

        var attArr:[NSMutableAttributedString] = []

        for i in 0..<arr.count {
            attArr.append(NSMutableAttributedString(string: arr[i]))
        }

        for j in 0..<attArr.count {
            let range = NSMakeRange(0, attArr[j].length)
            attArr[j].addAttribute(.backgroundColor, value: UIColor.yellow, range: range)
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5){
                for m in 0..<attArr.count {
                    newStr = NSMutableAttributedString(string: "\(attArr[m])\n")
                    self.textView.attributedText = newStr

                }
            }
            attArr[j].removeAttribute(.backgroundColor, range: range)
            //remove from texview here
        }
    }

如您所见,该算法应该剥离textView文本,并通过用新行定界符分隔每行将其放置到数组中. 接下来要做的是创建一个填充了相同文本但可变属性字符串的数组,以开始添加Highlight属性. 每次出现突出显示的行时,都会有一个小的延迟,直到下一行开始突出显示为止.如果有人可以帮助或指出正确的方向来开始正确实施此方法,那将极大地帮助您,

As you can see this algorithm is supposed to strip the textView text and place that into an array by separating each line the new line delimiter. The next thing done is to create an array filled with the same text but as mutable attributed string to begin adding the highlight attribute. Each time a highlighted line appears there is a small delay until the next line begins to highlight. If anyone can help or point me in to the right direction to begin implementing this correctly it would help immensely,

谢谢!

推荐答案

所以你想要这个:

您需要文本视图的内容始终为完整的字符串,并突出显示一行,但是您的代码将其设置为仅突出显示的行.您的代码还将所有突出显示安排在同一时间(.now() + 0.5)而不是在不同的时间进行.

You need the text view's contents to always be the full string, with one line highlighted, but your code sets it to just the highlighted line. Your code also schedules all the highlights to happen at the same time (.now() + 0.5) instead of at different times.

这是我的建议:

  1. 创建一个范围数组,每行一个范围.

  1. Create an array of ranges, one range per line.

使用该数组通过根据需要删除并添加.backgroundColor属性以突出显示和取消突出显示线条来修改文本视图的textStorage.

Use that array to modify the text view's textStorage by removing and adding the .backgroundColor attribute as needed to highlight and unhighlight lines.

突出显示第n行时,安排第n+1行的突出显示.这有两个优点:如果需要的话,提前取消动画会更容易,更有效;并且如果需要的话,可以使动画无休止地重复播放.

When you highlight line n, schedule the highlighting of line n+1. This has two advantages: it will be easier and more efficient to cancel the animation early if you need to, and it will be easier to make the animation repeat endlessly if you need to.

我使用这个游乐场创建了上面的演示:

I created the demo above using this playground:

import UIKit
import PlaygroundSupport

let text = "This is\n some placeholder\n text\nwith newlines."
let textView = UITextView(frame: CGRect(x: 0, y:0, width: 200, height: 100))
textView.backgroundColor = .white
textView.text = text

let textStorage = textView.textStorage

// Use NSString here because textStorage expects the kind of ranges returned by NSString,
// not the kind of ranges returned by String.
let storageString = textStorage.string as NSString
var lineRanges = [NSRange]()
storageString.enumerateSubstrings(in: NSMakeRange(0, storageString.length), options: .byLines, using: { (_, lineRange, _, _) in
    lineRanges.append(lineRange)
})

func setBackgroundColor(_ color: UIColor?, forLine line: Int) {
    if let color = color {
        textStorage.addAttribute(.backgroundColor, value: color, range: lineRanges[line])
    } else {
        textStorage.removeAttribute(.backgroundColor, range: lineRanges[line])
    }
}

func scheduleHighlighting(ofLine line: Int) {
    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
        if line > 0 { setBackgroundColor(nil, forLine: line - 1) }
        guard line < lineRanges.count else { return }
        setBackgroundColor(.yellow, forLine: line)
        scheduleHighlighting(ofLine: line + 1)
    }
}

scheduleHighlighting(ofLine: 0)

PlaygroundPage.current.liveView = textView

这篇关于如何快速突出显示UITextView的文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆