【问题标题】:How Do I Fix My Activity Indicator From Not Appearing/Freezing?如何修复我的活动指示器不出现/冻结?
【发布时间】:2021-10-17 21:18:51
【问题描述】:
@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 次掷硬币时翻转的正面数(由用户指定)。我的活动微调器根本不显示,即使它设置为在动画时出现。任何帮助将不胜感激!

【问题讨论】:

  • 尝试使用DispatchQueue.global(qos: .userInitiated).async { 而不是DispatchQueue.global().sync {。另外,在启动后台进程之前,从主线程中的文本字段中获取 int 值,启动指示器动画

标签: swift grand-central-dispatch uiactivityindicatorview dispatch-queue


【解决方案1】:

所以,先去看看documentation for DispatchQueue

sync 函数读取...

func sync(execute: () -> Void)
提交一个块对象执行 并在该块执行完毕后返回。

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

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

func async(group: DispatchGroup?, qos: DispatchQoS, flags: DispatchWorkItemFlags,执行:() -> Void)
调度一个块 异步执行,并可选择将其与 调度组。

您还应该在运行后台线程之前获取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()
            }
        }
    }
    
    
}

【讨论】:

  • 完美运行,谢谢!
猜你喜欢
  • 2013-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-19
相关资源
最近更新 更多