使文本视图响应用户输入的文本 [英] Making a text view respond to text typed by the user

查看:20
本文介绍了使文本视图响应用户输入的文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序中有一个文本视图,允许用户在其中输入任何内容.我希望文本视图在键入时检测几个单词并更改其颜色.

I have a text view in my app which allows the user to type anything in it. I want the text view to detect a few words when they are typed and change their colour.

例如,如果用户输入-我最喜欢的颜色是红色",那么我希望红色"一词获得文本颜色红色".但因此应该在句子中输入红色这个词后立即发生.我应该如何实施?

For example, if the user types- "My favourite colour is red", then I want the word 'red' to get the text colour 'red'. But thus should happen immediately after the word red is typed in the sentence. How should I implement this?

推荐答案

你需要三件事:

  • 在界面构建器中,您需要使用其中一种委托方法.我认为editingChanged"在这里是最好的.使用ctrl"从文本字段拖动到您的文档.

  • In the interface builder you need to use one of the delegate methods. I think "editingChanged" is the best here. Drag from the textfield with "ctrl" to you document.

您需要一种方法来遍历文本字段中的字符串并检测单词.

You need a way to go over the string from textfield and detect words.

componentsSeparatedByCharactersInSet

您需要一种方法来为句子中的一个词设置样式.

You need a way to style one word in a sentence.

NSMutableAttributedString

也很有趣:如何在不删除分隔符的情况下分隔字符串

部分代码(把它扔到操场上):

Part of the code (throw this in a playground) :

这将找到所有要更改的单词,但删除分隔符.需要做更多的工作来完成代码.

This will find all the words to change, but remove separators. More work is needed to complete the code.

var strSeperator : NSCharacterSet = NSCharacterSet(charactersInString: ",.:;?! ")

var strArray = str.componentsSeparatedByCharactersInSet(strSeperator)

var styledText = NSMutableAttributedString()

for i in 0..<strArray.count {

    let currentWord = strArray[i]
    var currentBoolFoundInControl : Bool = false

    for iB in 0..<colorTheseStrings.count {

        let controlWord = colorTheseStrings[iB]

        if controlWord == currentWord {
            currentBoolFoundInControl = true
            // add to mutable attributed string in a color
        }

    }

    var attrString1 = NSMutableAttributedString(string: "\(strArray[i]) ")

    if currentBoolFoundInControl == true {

        var range = (strArray[i] as NSString).rangeOfString(strArray[i])
        if strArray[i] == "red" {
            attrString1.addAttribute(NSForegroundColorAttributeName, value: UIColor(red: 0.5, green: 0.0, blue: 0.0, alpha: 1.0), range: range)
        } else if strArray[i] == "blue" {
            attrString1.addAttribute(NSForegroundColorAttributeName, value: UIColor(red: 0.0, green: 0.0, blue: 0.5, alpha: 1.0), range: range)

        }
    }

    styledText.appendAttributedString(attrString1)
}

myTextField.attributedText = styledText

另一种方式:

在此处下载

我认为这种方式是最健壮、最酷、最高效的.代码可以稍微清理一下,可以使用更多的风格/天赋.这对于像天蓝色"这样的东西确实有问题,因为它会首先找到蓝色"并替换它.但我不得不留下一些改进的空间.;)

I think this way is the most robust and the coolest and the most efficient. Code could be cleaned up a bit and could use a bit more style/flair. This does have trouble with things like the "sky blue" because it will find "blue" first and replace it. But I had to leave some room for improvement. ;)

我忍不住了,所以我解决了最后一个问题.

And I couldn't help myself, so I fixed that last issue.

再一次,我修复了,我的修复.现在更高效,更准确.

And again, I fixed, my fix. More efficient and actually correct now.

第一部分是 HighLighter 类,将其放在单独的文档中.

The first part is the HighLighter class, drop this in a separate document.

// text hightlighter

class SyntaxGroup {

    var wordCollection : [String] = []
    var type : String = ""
    var color : UIColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)

    init(wordCollection_I : [String], type_I : String, color_I: UIColor) {

        wordCollection = wordCollection_I
        type = type_I
        color = color_I

    }
}

class SyntaxDictionairy {

    var collections : [SyntaxGroup] = []

}

class SyntaxRange {

    var range : NSRange
    var color : UIColor

    init (color_I : UIColor, range_I : NSRange) {
        color = color_I
        range = range_I
    }

}

class HighLighter {

    var ranges : [SyntaxRange] = []
    var baseString : NSMutableString = NSMutableString()
    var highlightedString : NSMutableAttributedString = NSMutableAttributedString()
    var syntaxDictionairy : SyntaxDictionairy

    init (syntaxDictionairy_I : SyntaxDictionairy) {

        syntaxDictionairy = syntaxDictionairy_I

    }

    func run(string : String?, completion: (finished: Bool) -> Void) {

        ranges = [] // reset the ranges, else it crashes when you change a previous part of the text
        highlightedString = NSMutableAttributedString() // make sure all strings start fresh
        baseString = NSMutableString() // make sure all strings start fresh

        // multi threading to prevent locking up the interface with large libraries.
        let qualityOfServiceClass = QOS_CLASS_DEFAULT
        let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
        dispatch_async(backgroundQueue) { () -> Void in

            if string != nil && string != "" {

                self.highlightedString = NSMutableAttributedString(string: string!)

                for i in 0..<self.syntaxDictionairy.collections.count {

                    for iB in 0..<self.syntaxDictionairy.collections[i].wordCollection.count {

                        let currentWordToCheck = self.syntaxDictionairy.collections[i].wordCollection[iB]
                        self.baseString = NSMutableString(string: string!)

                        while self.baseString.containsString(self.syntaxDictionairy.collections[i].wordCollection[iB]) {

                            let nsRange = (self.baseString as NSString).rangeOfString(currentWordToCheck)
                            let newSyntaxRange = SyntaxRange(color_I: self.syntaxDictionairy.collections[i].color, range_I: nsRange)
                            self.ranges.append(newSyntaxRange)

                            var replaceString = ""
                            for _ in 0..<nsRange.length {
                                replaceString += "§" // secret unallowed character
                            }
                            self.baseString.replaceCharactersInRange(nsRange, withString: replaceString)
                        }
                    }
                }
                for i in 0..<self.ranges.count {

                    self.highlightedString.addAttribute(NSForegroundColorAttributeName, value: self.ranges[i].color, range: self.ranges[i].range)

                }
            }

            dispatch_sync(dispatch_get_main_queue()) { () -> Void in

                completion(finished: true)
            }

        }
    }
}

在视图控制器中:这是您将用于 UITextfield 的代码.首先创建荧光笔的实例并设置单词和相应颜色的字典.然后在需要的时候启动run函数.

In the ViewController : This is the code you will use with the UITextfield. First create an instance of the highlighter and set up your dictionary of words and corresponding colours. Then start the run function when needed.

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var myTextfield: UITextField!

    var syntaxHighLighter : HighLighter! // declare highlighter

    override func viewDidLoad() {
        super.viewDidLoad()
        setUpHighLighter()
    }
    // this is just a little function to put the set up for the highlighter outside of viewDidLoad()
    func setUpHighLighter() {

        // build a dict of words to highlight
        let redColor = UIColor(red: 0.5, green: 0.0, blue: 0.0, alpha: 1.0)
        let blueColor = UIColor(red: 0.0, green: 0.0, blue: 0.5, alpha: 1.0)
        let greenColor = UIColor(red: 0.0, green: 0.5, blue: 0.0, alpha: 1.0)

        let redGroup = SyntaxGroup(wordCollection_I: ["red","bordeaux"], type_I: "Color", color_I: redColor)
        let blueGroup = SyntaxGroup(wordCollection_I: ["coralblue","blue","skyblue","azur"], type_I: "Color", color_I: blueColor)
        let greenGroup = SyntaxGroup(wordCollection_I: ["green"], type_I: "Color", color_I: greenColor)

        let dictionairy : SyntaxDictionairy = SyntaxDictionairy()
        dictionairy.collections.append(blueGroup)
        dictionairy.collections.append(greenGroup)
        dictionairy.collections.append(redGroup)

        syntaxHighLighter = HighLighter(syntaxDictionairy_I: dictionairy)

    }
    // this is where the magic happens, place the code from inside the editingChanged inside your function that responds to text changes.
    @IBAction func editingChanged(sender: UITextField) {

        syntaxHighLighter.run(myTextfield.text) { (finished) -> Void in
            self.myTextfield.attributedText = self.syntaxHighLighter.highlightedString
        }
    }
}

这篇关于使文本视图响应用户输入的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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