Updating Label Takes Too Long (Swift)

Updating label takes too long (swift)

What happens is that code is probably run on a secondary thread. Any UI changes you make should be made on the main thread. So try this:

dispatch_async(dispatch_get_main_queue()) {
// update label
}

This should update your label instantly.

Updating Label Text several times while a Button is pressed in Swift

You can run all of your long-running tasks in a background queue, and make the label updates in the main queue. The key is to call the next function only when the first is finished, or they will run in parallel, and could all update at the same time. Here's an example

func doSomething1() {
// as good a way as any to simulate a long-running process
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text1"
}
DispatchQueue.global(qos: .background).async {
self.doSomething2()
}
}
func doSomething2() {
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text2"
}
DispatchQueue.global(qos: .background).async {
self.doSomething3()
}
}
func doSomething3() {
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text3"
}
DispatchQueue.global(qos: .background).async {
self.doSomething4()
}
}
func doSomething4() {
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text4"
}
}

@IBAction func cmdDoStuff(_ sender: UIButton) {

DispatchQueue.global(qos: .background).async {
self.doSomething1()
}
}

Swift Update Label (with HTML content) takes 1min

Usual problem of updating UI in a secondary thread:

Your closure is obviously not running on the main thread, as the URL task is asynchronous. So updating the label on the closure will have to wait for the main thread to run its update loop. The way to fix it is to wrap the .text = call to force it to run on the main thread (which is where the UI stuff should run anyway):

        dispatch_async(dispatch_get_main_queue()) {
self.LBoutput.text = "test6"
}

Updating UILabel.text is slow

There's not a whole lot to go on in the code you posted, but it sounds like you're doing your label updates directly in your web service callback, which usually runs on a background thread. All UI work needs to be done on the main thread or you'll run in to problems like this. If so, running that switch statement on the main thread using GCD's dispatch_async will fix your problem:

dispatch_async(dispatch_get_main_queue()) {
switch currentTemp {
case 80..<180:
self.riskType.text = "Heat Index:"
self.perceivedTemperatureValue.text = "\(currentHeatIndex)"
case -100..<50:
self.riskType.text = "Wind Chill:"
self.perceivedTemperatureValue.text = "\(currentWindChill)"
default:
self.riskType.text = "Temperature:"
println(currentTemp)
self.perceivedTemperatureValue.text = "\(currentTemp)"
}
}

iOS - Swift 5 - Label Text Not Updating within Loop

You didn't explain what the problem is, but I'm going to guess that nothing happens and then the label gets update (finally) to the last value.

That's because sceneTapped is a gesture recognizer, which mean it's running on the main thread. (All UI code and event handling runs on the main thread.)

So sceneTapped is spinning in a loop, on the main thread, queuing up blocks to run on the main thread. But the main thread is busy running sceneTapped so none of those blocks execute.

Finally, sceneTapped returns, and all of those queued blocks suddenly execute, one after the other.

If this for loop is a long running loop, it needs to be running in its own thread. As a rule, you never want to have any code that takes a significant amount to time to execute to be running on the main thread. Any code that blocks the main thread freezes your UI and all user interaction.

So basically you should have something like this:

@objc func sceneTapped(recognizer: UITapGestureRecognizer) {
// ...
DispatchQueue.global().async {
// execute long running code in a background thread
for i in 0...geodesic.count-1 {
// ...

//print(String("\(aircraft.position.x)"))
DispatchQueue.main.async {
//self.dataLabel.setNeedsDisplay()
self.dataLabel.text = String("\(aircraft.position.x)")
}
}
}
}

You want the bulk of the action to run in a background thread, doing its thing, calculating stuff, blocking, waiting, whatever.

When it has something to do with the UI, it can queue a block to run on the main thread, which is still (independently) running, handling events, updating views, recalculating layouts, and generally keeping your app responsive.

Finally, you have to be sure that everything in that background thread is thread safe.

iOS Swift Update text label after 1 second

You shouldn't use the sleep() function as this will suspend the main thread and cause your app to become non-responsive. NSTimer is one way to achieve this. It will dispatch a function at a specified time in the future.

For example -

var countdown=0
var myTimer: NSTimer? = nil

override func viewDidAppear(animated: Bool) {
countdown=5
myTimer = NSTimer(timeInterval: 1.0, target: self, selector:"countDownTick", userInfo: nil, repeats: true)
countdownLabel.text = "\(countdown)"
}

func countDownTick() {
countdown--

if (countdown == 0) {
myTimer!.invalidate()
myTimer=nil
}

countdownLabel.text = "\(countdown)"
}

Speed Up Label Text change in iOS

Changing the label text should happen "almost instantly", and when it takes this long it is usually caused by not updating the label text on the main thread. It is a UIKit object, therefore it must only be modified on the main thread.

Use:

dispatch_async(dispatch_get_main_queue(), ^{
self.label.text = myString;
});

Delayed response when changing label text (Swift)

You have to handle the imageFound==false case similar to the true case in terms of dispatch_async:

if !imageFound {
dispatch_async(dispatch_get_main_queue()) {
self.faceImageView.alpha = 0
self.realLoadingLbl.text = "No Results Found. Check your spelling and try again."
print("NO RESULTS!!!!!")
self.faceImageView.alpha = 0
}
}


Related Topics



Leave a reply



Submit