【问题标题】:UIButton not refresh when updating更新时UIButton不刷新
【发布时间】:2020-09-21 05:51:40
【问题描述】:

我有一个大问题,我在手动单击按钮时创建了一个串行 UIbutton,我更改了背景颜色和填充颜色,并取消单击正常状态的颜色更改。

但是当我的程序选择一个随机按钮时,顺序很好,但是按钮没有实时改变,看不到选择了什么按钮(没有背景颜色,没有填充颜色)我不明白为什么,我在其他问题上看到了 setNeedsDisplay、setEnable、...的可能性。但不适用于我的...

你解决了这个刷新问题吗?我如何刷新按钮(button.setNeedsDisplay() 不起作用)

查看我的程序,当我的 mp3 结束播放时,我使用 soundEnd 布尔值,当我的按钮处于正常状态时,我使用 nextSound 布尔值。睡眠用于慢循环并等待 mp3 播放结束,如果不是多选则不起作用......我找到了这个解决方案,但不适用于背景和填充颜色

谢谢!

//
//  ViewController.swift
//  test
//
//  Created by Thierry on 03/06/2020.
//  Copyright © 2020 Thierry  All rights reserved.
//

import UIKit
let squareSize  = 100
let borderSpace = 20

class ViewController: UIViewController {
    


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        let zone3 = UIView(frame: CGRect(x: 10, y: 10, width: view.frame.width-20, height: view.frame.height-20))
        zone3.backgroundColor = .red
        view.addSubview(squareDraw(contentView: zone3))
        
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
        for randomInt in 1..<13 {
        print(randomInt)
        let subview = self.view.viewWithTag(randomInt)
        let button = subview as! UIButton
        
            button.sendActions(for: .touchDown)

            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            button.sendActions(for: .touchUpInside)
            }
            
            sleep(3)
        
        }
        }
    }
        
        func squareDraw(contentView : UIView) ->UIView {
                
                    let widthScreen: Int = Int(contentView.bounds.width)
                    let heightScreen: Int  = Int(contentView.bounds.height)
                
                    let scaleFactorX = (widthScreen*100/((3 * squareSize) + (4 * borderSpace)))
                    let scaleFactorY = (heightScreen*100/((4 * squareSize) + (5 * borderSpace)))
                
                    let squareSizeScaleX = (squareSize * scaleFactorX)/100
                    let squareSizeScaleY = (squareSize * scaleFactorY)/100
                    
                    let borderSpaceScaleX = (borderSpace * scaleFactorX)/100
                    let borderSpaceScaleY = (borderSpace * scaleFactorY)/100
                
                
                let originY = 0
                var Tag = 0
                for yCoord in 1...4 {
                    for xCoord in 1...3 {
                        Tag = Tag + 1
                        let k = button(CGRect(x: xCoord * (squareSizeScaleX + borderSpaceScaleX) - squareSizeScaleX, y: originY + (yCoord * (squareSizeScaleY + borderSpaceScaleY) - squareSizeScaleY), width: squareSizeScaleX, height: squareSizeScaleY), tag: Tag)
                        contentView.addSubview(k)

                    }
                }
                return contentView

            }
            
        func button(_ rect: CGRect, tag: Int) ->UIView {

                let myButton = UIButton(type: .system)
                myButton.frame = CGRect(x:CGFloat(rect.minX), y:CGFloat(rect.minY), width:CGFloat(rect.width), height:CGFloat(rect.height))
                myButton.tag = tag
                myButton.backgroundColor = .white
                myButton.layer.borderWidth = 5
                myButton.layer.borderColor = UIColor.white.cgColor
                myButton.addTarget(self, action: #selector(buttonSelected), for: .touchUpInside)
                myButton.addTarget(self, action: #selector(buttonReleased), for: .touchDown )
                return myButton
                
        }
        
      
    @objc func buttonSelected(sender: UIButton) {
                let button = sender
                
                if button.isSelected == true {
                   
                } else {
             
                      button.layer.borderWidth = 5
                      button.layer.borderColor = UIColor.white.cgColor
                               
                }
            
            }
        
    @objc func buttonReleased(sender: UIButton) {
              
                let button = sender
             
                if button.isEnabled == true {

                    button.layer.borderWidth = 5
                    button.layer.borderColor = UIColor.black.cgColor
          
                } else {
                    
                }
            }

 
        
  


}

【问题讨论】:

  • 如果你在主线程上运行它,你可能会遇到很多问题。如果这是在后台线程上运行,则需要在主线程上执行任何 UI 更新。
  • @DonMag 感谢您的回复!我没有其他问题,只有颜色不会在 UIButton 上实时更改,所有更改都在循环结束时可见,我没有发现每次更改结果后如何刷新我的视图与 11 中的 randomInt 循环相同..
  • 很难确切地知道你的代码在做什么或者是什么影响了它。你能把minimal reproducible example放在一起吗?
  • @DonMag 我在我的第一个问题代码中进行了更新,例如,如果按钮中没有 addTarget,它会在 xcode 新项目中自动运行,如果您对此问题有解决方案?谢谢!
  • OK - 你对sleep(2) 的使用是个大问题。这会“冻结”您的代码执行 2 秒。如果删除该行,则在视图加载 3 秒后,所有白色方块都会出现黑色边框。您是否尝试每 3 秒更改 一个 边框?

标签: ios xcode uibutton refresh ios12


【解决方案1】:

首先,您从不想使用sleep(2) - 它会冻结您的程序 2 秒钟,并且不会发生其他任何事情。有罕见例外,但您绝对不希望这里出现。

你真正想做的事情仍然有点令人困惑。您的问题是 “当我的 mp3 结束播放时 soundEnd 布尔值”

所以,这是一个示例 - 使用您的一些代码。

  • viewDidLoad()
    • 在红色背景上绘制一个由 12 个白色按钮组成的网格
  • viewDidAppear()
    • 开始播放声音
    • 将第一个按钮的边框设置为黑色
  • 当声音停止时
    • 将按钮边框设置回白色
    • 开始第二个声音
    • 将第二个按钮的边框设置为黑色

这将循环播放您拥有的声音片段的数量:

class SoundTestViewController: UIViewController, AVAudioPlayerDelegate {

    let squareSize  = 100
    let borderSpace = 20

    var myPlayer: AVAudioPlayer = AVAudioPlayer()

    // start at -1 so first call to "play next" will increment it to 0
    var soundNumber: Int = -1

    // replace with your mp3 file names
    let mp3FileNames: [String] = [
        "clip1",
        "clip2",
        "clip3",
        "clip4",
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        let zone3 = UIView(frame: CGRect(x: 10, y: 10, width:   view.frame.width-20, height: view.frame.height-20))
        zone3.backgroundColor = .red
        view.addSubview(squareDraw(contentView: zone3))
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        playNextSoundFile()
    }

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        player.stop()
        if let subview = self.view.viewWithTag(soundNumber + 1) as? UIButton {
            subview.layer.borderColor = UIColor.white.cgColor
        }
        playNextSoundFile()
    }

    func playNextSoundFile() {
        soundNumber += 1
        if soundNumber > mp3FileNames.count - 1 {
            soundNumber = 0
        }

        guard let url = Bundle.main.url(forResource: mp3FileNames[soundNumber], withExtension: ".mp3") else {
            // mp3 file not found in bundle
            return
        }

        do {
            if let subview = self.view.viewWithTag(soundNumber + 1) as? UIButton {
                subview.layer.borderColor = UIColor.black.cgColor
            }

            let sound = try AVAudioPlayer(contentsOf: url)

            self.myPlayer = sound

            // set the audio player delegate to self
            sound.delegate = self

            sound.numberOfLoops = 0
            sound.prepareToPlay()
            sound.play()
        } catch {
            print("error initializing audio player")
        }
    }


    func squareDraw(contentView : UIView) ->UIView {

        let widthScreen: Int = Int(contentView.bounds.width)
        let heightScreen: Int  = Int(contentView.bounds.height)

        let scaleFactorX = (widthScreen*100/((3 * squareSize) + (4 * borderSpace)))
        let scaleFactorY = (heightScreen*100/((4 * squareSize) + (5 * borderSpace)))

        let squareSizeScaleX = (squareSize * scaleFactorX)/100
        let squareSizeScaleY = (squareSize * scaleFactorY)/100

        let borderSpaceScaleX = (borderSpace * scaleFactorX)/100
        let borderSpaceScaleY = (borderSpace * scaleFactorY)/100

        let originY = 0
        var Tag = 0
        for yCoord in 1...4 {
            for xCoord in 1...3 {
                Tag = Tag + 1
                let k = button(CGRect(x: xCoord * (squareSizeScaleX + borderSpaceScaleX) - squareSizeScaleX, y: originY + (yCoord * (squareSizeScaleY + borderSpaceScaleY) - squareSizeScaleY), width: squareSizeScaleX, height: squareSizeScaleY), tag: Tag)
                contentView.addSubview(k)

            }
        }

        return contentView
    }

    func button(_ rect: CGRect, tag: Int) ->UIView {

        let myButton = UIButton(type: .system)
        myButton.frame = CGRect(x:CGFloat(rect.minX), y:CGFloat(rect.minY), width:CGFloat(rect.width), height:CGFloat(rect.height))
        myButton.tag = tag
        myButton.backgroundColor = .white
        myButton.layer.borderWidth = 5
        myButton.layer.borderColor = UIColor.white.cgColor

        return myButton
    }

}

如果这不是你真正想要做的,也许它至少会让你朝着正确的方向前进。

【讨论】:

  • 非常好,正是我想要的,我会看看我的错误在哪里,非常感谢您的帮助!
猜你喜欢
  • 2013-04-20
  • 1970-01-01
  • 2020-07-10
  • 2015-11-22
  • 2012-10-19
  • 2012-10-25
  • 2018-10-15
  • 2013-03-12
  • 1970-01-01
相关资源
最近更新 更多