Search code examples
iosswiftxcodenstimer

iOS - How to start a new line in UITextView while streaming from remote service


In my ios application, I am streaming text from a remote service to a UITextView.

 @IBOutlet weak var streamingResult: UITextView!

 // Store streaming results in a String called results
 var results : String = ""

I don't know when text is coming in or not. But whenever there is a pause, I want to start a new line on the UILabel.

So I have resorted to using a NSTimer to detect when there is no text for 3 seconds like this:

var timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, 
selector: "pauseExists", userInfo: nil, repeats: false)

My selector is hit as expected when there is no text coming in, and I tried to add a new line character like this:

@objc func pauseExists() {
    print("No stream for 3 seconds")

    guard let currentText = self.streamingResult.text else { return }
    if !currentText.isEmpty {
       self.results.append("\n")
       self.streamingResult.text = self.results
    } 
}

This doesn't work, the next result gets added right after the previous one. What is the right way to do this?


Solution

  • Here is a better example for you. Use UITextView instead. It is better and comes with a free UIScroll.

    let label : UITextView = {
            let label = UITextView()
            label.backgroundColor = .red
            label.isEditable = false
            return label
    }()
    
    lazy var appendButton : UIButton = {
        let button = UIButton()
        button.setTitle("Append", for: .normal)
        button.backgroundColor = .red
        return button
    }()
    
    var foo : String = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.view.addSubview(appendButton)
        appendButton.translatesAutoresizingMaskIntoConstraints = false
        appendButton.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
        appendButton.heightAnchor.constraint(equalToConstant: 100).isActive = true
        appendButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
        appendButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
        appendButton.addTarget(self, action: #selector(appendButtonPressed), for: .touchUpInside)
    
    
        self.view.addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
        label.widthAnchor.constraint(equalToConstant: 200).isActive = true
        label.heightAnchor.constraint(equalToConstant: 200).isActive = true
    
        var timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.pauseExists), userInfo: nil, repeats: true)
    }
    
    @objc func pauseExists() {
        print("No stream for 1 second")
        foo.append("\n")
        label.text = foo
    }
    
    @objc func appendButtonPressed (sender: UIButton!) {
        foo.append("New Line")
        label.text = foo
    }
    

    Run this code in an empty project and you will see how new lines get appended every time you press the Append button. Hope it helps