如何修复我的 Activity 指标而不是 Appearing/Freezing?

How Do I Fix My Activity Indicator From Not Appearing/Freezing?

@IBOutlet weak var Input: UITextField!
@IBOutlet weak var Heads: UILabel!
@IBOutlet weak var working: UIActivityIndicatorView!

@IBAction func Toss(_ sender: Any) {
    
    DispatchQueue.global().sync {
        //set up variables and method
        var input = 0
        func integer(from textField: UITextField) -> Int {
            guard let text = textField.text, let number = Int(text) else {
                return 0
            }
            return number
        }
        var runningTotal = 0
        
        //collect input
        input = integer(from: Input)
        
        //start loading symbol
        DispatchQueue.main.async() { [self] in
            working.startAnimating()
        }
        
        //do math
        for _ in 0..<input {
            let currentTrial = Int.random(in: 0...1)
            if(currentTrial == 1) {
            runningTotal += 1
            }
        }

        DispatchQueue.main.async { [self] in
            
            //set output
            Heads.text = String(runningTotal)
            
            //stop loading symbol
            working.stopAnimating()
        }
    }
}

本程序计算抛x次硬币(由用户指定)时正面朝上的次数。我的 activity 微调器根本没有显示,即使它被设置为在动画时显示。如有任何帮助,我们将不胜感激!

所以,首先去看看 documentation for DispatchQueue

sync 函数读取...

func sync(execute: () -> Void)
Submits a block object for execution and returns after that block finishes executing.

这不是您想要的,这将阻塞主线程并阻止 UI 更新。

相反,您要使用的是 async 变体之一,例如...

func async(group: DispatchGroup?, qos: DispatchQoS, flags: DispatchWorkItemFlags, execute: () -> Void)
Schedules a block asynchronously for execution and optionally associates it with a dispatch group.

您还应该在 运行 后台线程之前获取 input 值,因为您应该避免访问主线程上下文之外的组件。

可运行示例...

class ViewController: UIViewController {
    
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var working: UIActivityIndicatorView!
    
    @IBOutlet weak var headsLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        headsLabel.isHidden = true
    }
    
    @IBAction func doStuff(_ sender: Any) {
        var input = 0
        func integer(from textField: UITextField) -> Int {
            guard let text = textField.text, let number = Int(text) else {
                return 0
            }
            return number
        }
        input = integer(from: textField)
        
        working.startAnimating()
        
        DispatchQueue.global(qos: .userInitiated).async {
            //set up variables and method
            var runningTotal = 0
            
            //do math
            for _ in 0..<input {
                let currentTrial = Int.random(in: 0...1)
                if(currentTrial == 1) {
                    runningTotal += 1
                }
            }
            
            DispatchQueue.main.async { [self] in
                
                headsLabel.isHidden = false
                //set output
                headsLabel.text = String(runningTotal)
                
                //stop loading symbol
                working.stopAnimating()
            }
        }
    }
    
    
}