如何修复我的活动指示器不出现/冻结?

Posted

技术标签:

【中文标题】如何修复我的活动指示器不出现/冻结?【英文标题】: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 值,启动指示器动画 【参考方案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()
            
        
    
    
    

【讨论】:

完美运行,谢谢!

以上是关于如何修复我的活动指示器不出现/冻结?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复视图居中之谜?

如何在导航栏中设置活动指示器?

每次我的平面列表数据更改时,如何显示活动指示器?

如何使用 swift 在 WKWebView 的页面中间显示活动指示器?

加载网页时活动指示器不隐藏

如何在 tableView 加载时显示活动指示器?