Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用UPPERCase在UITextView中显示文本,并从ShouldChangeText中获取新文本,以保留原始文本和输入文本的大小写_Ios_Swift - Fatal编程技术网

Ios 使用UPPERCase在UITextView中显示文本,并从ShouldChangeText中获取新文本,以保留原始文本和输入文本的大小写

Ios 使用UPPERCase在UITextView中显示文本,并从ShouldChangeText中获取新文本,以保留原始文本和输入文本的大小写,ios,swift,Ios,Swift,我有一个UITextView,有时需要在所有大写字母中显示,有时需要在原始情况下显示。这一部分很简单,但是当用户开始编辑文本时,我需要用更改更新原始字符串,同时保留字符串的原始大小写。因此,我无法使用textdichange,而是使用shouldChangeTextIn并更改原始字符串。大多数情况下,一切都按预期进行,除非选择了多个单词,并且您在键盘上轻触一个预测单词。可能还有其他东西会断裂。修复此问题的最佳方法是在显示变异字符串的同时保留原始字符串。这里是一个最小的例子 import UIKi

我有一个UITextView,有时需要在所有大写字母中显示,有时需要在原始情况下显示。这一部分很简单,但是当用户开始编辑文本时,我需要用更改更新原始字符串,同时保留字符串的原始大小写。因此,我无法使用textdichange,而是使用shouldChangeTextIn并更改原始字符串。大多数情况下,一切都按预期进行,除非选择了多个单词,并且您在键盘上轻触一个预测单词。可能还有其他东西会断裂。修复此问题的最佳方法是在显示变异字符串的同时保留原始字符串。这里是一个最小的例子

import UIKit

class ViewController: UIViewController {

    lazy var textView : UITextView = {
        let txtv = UITextView(frame: CGRect(x: 0, y:40, width: self.view.frame.width, height: 200))
        txtv.autoresizingMask = [.flexibleWidth,.flexibleHeight]
        txtv.delegate = self
        txtv.font = UIFont.systemFont(ofSize: 22)
        return txtv
    }()

    lazy var button : UIButton = {
        let btn = UIButton(frame: CGRect(x: 0, y:250, width: self.view.frame.width - 40, height: 50))
        btn.autoresizingMask = [.flexibleWidth,.flexibleHeight]

        btn.setTitleColor(UIColor.blue, for: .normal)
        btn.setTitle("SHOW TEXT", for: .normal)
        btn.addTarget(self, action: #selector(changeState), for: .touchUpInside)
        return btn
    }()

    var textString = "This is a test to see how we are doing"
    var shouldCapitalize : Bool = true
    private var hack_shouldIgnorePredictiveInput = false

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(textView)
        self.view.addSubview(button)
        //get things going
        updateTextView()
    }

    func updateTextView(){
        //we could change font size here or size of textview
        var textToShow = self.textString
        if shouldCapitalize == true{
            textToShow = textToShow.uppercased()
        }
        textView.text = textToShow
        print("the text string we really care about is::::: \(textString)")
    }

    @objc func changeState(){
        shouldCapitalize = !shouldCapitalize
        updateTextView()
    }
}

extension ViewController : UITextViewDelegate{

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

        if hack_shouldIgnorePredictiveInput {
            hack_shouldIgnorePredictiveInput = false
            return false
        }

        hack_shouldIgnorePredictiveInput = true

        //how do i replace the characters or text changging without changing the case of the original string
        print("the textview text is \(textView.text)")
        print("the textview text is \((textView.text as NSString).length)")
        print("the range is \(range)")
        print("the text is \(text)")

        let selectedRange = self.textView.selectedRange

        if let str = textView.text as? NSString{
            if range.length == 0 && text == ""{
                print("the ext is empty")

                textString = ""
                updateTextView()
            }
            if let tracker = textString as? NSString{
                if range.location == tracker.length{
                    print("adding")
                    print("the lenght of the tracker is \(tracker.length)")
                    let newRange = NSMakeRange(tracker.length, range.length)
                    print("the new range is \(newRange)")
                    let newString = tracker.replacingCharacters(in: newRange, with: text)
                    print("the new text is \(newString)")

                    textString = newString
                    updateTextView()
                }else if range.location < tracker.length{
                    let newString = tracker.replacingCharacters(in: range, with: text)
                    print("the new text is \(newString)")

                    textString = newString
                    updateTextView()
                    if (newString as NSString).length > tracker.length{
                        print("setting cursor \(NSMakeRange(range.location + range.length, 0))")
                        self.textView.selectedRange = NSMakeRange(range.location + range.length + 1, 0)
                    }else{
                        self.textView.selectedRange = NSMakeRange(range.location, 0)
                    }



                }else{
                   //the problem seems to be in here
                    print("maybe adding")
                    print("the lenght of the tracker is \(tracker.length)")
                    let newRange = NSMakeRange(tracker.length, range.length)
                    print("the new range is \(newRange)")
                    let newString = str.replacingCharacters(in: newRange, with: text)
                    print("the new text is \(newString)")
                    textString = newString
                    updateTextView()
                }
            }
        }

        hack_shouldIgnorePredictiveInput = false
        return false
    }

}
导入UIKit
类ViewController:UIViewController{
惰性变量textView:UITextView={
设txtv=UITextView(帧:CGRect(x:0,y:40,宽度:self.view.frame.width,高度:200))
txtv.autoresizingMask=[.flexibleWidth、.flexibleHeight]
txtv.delegate=self
txtv.font=UIFont.systemFont(大小:22)
返回txtv
}()
惰性变量按钮:UIButton={
设btn=ui按钮(帧:CGRect(x:0,y:250,宽度:self.view.frame.width-40,高度:50))
btn.autoresizingMask=[.flexibleWidth、.flexibleHeight]
btn.setTitleColor(UIColor.blue,表示:。正常)
btn.setTitle(“显示文本”,用于:。正常)
btn.addTarget(self,action:#选择器(changeState),for:.touchUpInside)
返回btn
}()
var textString=“这是一个测试,看看我们做得如何”
var应资本化:Bool=true
私有变量hack_应忽略预测输入=false
重写func viewDidLoad(){
super.viewDidLoad()
self.view.addSubview(textView)
self.view.addSubview(按钮)
//开动
updateTextView()
}
func updateTextView(){
//我们可以在这里更改字体大小或文本视图的大小
var textToShow=self.textString
如果shouldCapitalize==true{
textToShow=textToShow.uppercased()
}
textView.text=textToShow
print(“我们真正关心的文本字符串是:::\(textString)”)
}
@objc func变更状态(){
shouldCapitalize=!shouldCapitalize
updateTextView()
}
}
扩展视图控制器:UITextViewDelegate{
func textView(textView:UITextView,shouldChangeTextIn范围:NSRange,replacementText:String)->Bool{
如果hack_应该忽略预测输入{
hack_shouldinorpredictiveinput=false
返回错误
}
hack_shouldinorpredictiveInput=true
//如何在不更改原始字符串大小写的情况下替换字符或文本变化
打印(“textview文本为\(textview.text)”)
打印(“textview文本为\((textview.text作为NSString.length)”)
打印(“范围为\(范围)”)
打印(“文本为\(文本)”)
让selectedRange=self.textView.selectedRange
如果让str=textView.text作为?NSString{
如果range.length==0&&text==“”{
打印(“文本为空”)
textString=“”
updateTextView()
}
如果let tracker=textString as?NSString{
如果range.location==tracker.length{
打印(“添加”)
打印(“跟踪器的长度为\(tracker.length)”)
让newRange=NSMakeRange(tracker.length,range.length)
打印(“新范围为\(新范围)”)
让newString=tracker.replacingCharacters(在:newRange中,带:text)
打印(“新文本为\(新闻字符串)”)
textString=newString
updateTextView()
}否则,如果range.locationtracker.length{
打印(“设置光标\(NSMakeRange(range.location+range.length,0)))
self.textView.selectedRange=NSMakeRange(range.location+range.length+1,0)
}否则{
self.textView.selectedRange=NSMakeRange(range.location,0)
}
}否则{
//问题似乎就在这里
打印(“可能添加”)
打印(“跟踪器的长度为\(tracker.length)”)
让newRange=NSMakeRange(tracker.length,range.length)
打印(“新范围为\(新范围)”)
让newString=str.replacingCharacters(在:newRange中,带:text)
打印(“新文本为\(新闻字符串)”)
textString=newString
updateTextView()
}
}
}
hack_shouldinorpredictiveinput=false
返回错误
}
}

因此,似乎调用了my bottom else,因为文本被设置为清空all,这是因为委托有时被调用两次以输入空格。jimmyg的评论帮助我看到他是对的,最后一个不应该被击中,这是我写函数时的想法。幸运的是,这有助于解释为什么会出现空文本。如果你在这里,我建议你投票表决这个答案。我还建议将其向上投票,这有助于使用预测文本停止一些不必要的调用,并且可以在我的代码中看到。最后,所有的逻辑似乎都到位了,而且更加简单,在UITextView中在预期文本和转换文本之间的切换正在工作

import UIKit

class ViewController: UIViewController {

    lazy var textView : UITextView = {
        let txtv = UITextView(frame: CGRect(x: 0, y:40, width: self.view.frame.width, height: 200))
        txtv.autoresizingMask = [.flexibleWidth,.flexibleHeight]
        txtv.delegate = self
        txtv.font = UIFont.systemFont(ofSize: 22)
        return txtv
    }()

    lazy var button : UIButton = {
        let btn = UIButton(frame: CGRect(x: 0, y:250, width: self.view.frame.width - 40, height: 50))
        btn.autoresizingMask = [.flexibleWidth,.flexibleHeight]
        btn.setTitleColor(UIColor.blue, for: .normal)
        btn.setTitle("SHOW TEXT", for: .normal)
        btn.addTarget(self, action: #selector(changeState), for: .touchUpInside)
        return btn
    }()

    var textString = "This is a test to see how we are doing"
    var shouldCapitalize : Bool = true
    private var hack_shouldIgnorePredictiveInput = false

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(textView)
        self.view.addSubview(button)
        //get things going
        updateTextView()
    }

    func updateTextView(){
        //we could change font size here or size of textview
        var textToShow = self.textString
        if shouldCapitalize == true{
            textToShow = textToShow.uppercased()
        }
        textView.text = textToShow
        print("realString:: \(textString)")
        print("textView showing:: \(textView.text)")
    }


    @objc func changeState(){
        shouldCapitalize = !shouldCapitalize
        updateTextView()
    }
}

extension ViewController : UITextViewDelegate{

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

        if hack_shouldIgnorePredictiveInput {
            hack_shouldIgnorePredictiveInput = false
            return false
        }

        hack_shouldIgnorePredictiveInput = true

            if range.length == 0 && text == "" && self.textString.count > 0 && range.length == self.textString.count{
                textString = ""
                updateTextView()
            }
            let tracker = (textString as NSString)
            if range.location == tracker.length{
                let newRange = NSMakeRange(tracker.length, range.length)
                let newString = tracker.replacingCharacters(in: newRange, with: text)
                textString = newString
                updateTextView()
            }else if range.location < tracker.length{
                if text.isEmpty && range.length == 0 && range.location > 0{
                    let newString = tracker.replacingCharacters(in:range, with: text)
                    textString = newString
                    updateTextView()

                    self.textView.selectedRange = NSMakeRange(range.upperBound, 0)
                }else{
                    let newString = tracker.replacingCharacters(in: range, with: text)
                    textString = newString
                    updateTextView()
                   self.textView.selectedRange = NSMakeRange(range.upperBound - tracker.length + (newString as NSString).length , 0)
                }
            }

        hack_shouldIgnorePredictiveInput = false
        return false
    }
}