Rbar Rbar - 7 days ago 6
Swift Question

Show UIView/UIImage/UITextView while function is running

OBJECTIVE



I am trying to display a UIView, UIImage, and UITextView when a function is running in order to let a user know it is processing (similar to an Activity Indicator, but more customized).

PROBLEM



When the code below is processing, the UIView, UIImage, and UITextView don't display until a moment before the function finishes running (instead of showing as soon the function starts running and hiding when the function finishes).

CURRENT APPROACH:



I have created a UIView (loadingView) which contains and image (loadingIcon) and a textView (loadingText) explaining to the user that the app is processing.

I have also created a function called isLoading, which displays or hides all 3, rather than repeating these lines multiple times. I have tested setting isLoading to true and false in the viewDidLoad to make sure that it is working properly.

@IBOutlet weak var loadingView: UIView!
@IBOutlet weak var loadingIcon: UIView!
@IBOutlet weak var loadingText: UIView!

override func viewDidLoad() {
super.viewDidLoad()
isLoading(false)
}


func isLoading(_ loadStatus: Bool) {
if loadStatus == true {
loadingView.isHidden = false
loadingIcon.isHidden = false
loadingText.isHidden = false
} else {
loadingView.isHidden = true
loadingIcon.isHidden = true
loadingText.isHidden = true
}
}

@IBAction func sendButtonPressed(_ sender: AnyObject) {
isLoading(true)

... //process information, which takes some time

isLoading(false)
}


Any help, suggestions, or thoughts are immensely appreciated. Thank you.

Answer

You are running the process on the main queue so your UI appears to hang until it is finished. You need to process the information in the background. A common pattern you might use would be:

@IBAction func sendButtonPressed(_ sender: AnyObject) {
    isLoading(true)

    // Do the processing in the background    
    DispatchQueue.global(qos: .userInitiated).async {
        ... //process information, which takes some time

        // And update the UI on the main queue
        DispatchQueue.main.async {
            isLoading(false)
        }
    }
}
Comments