UIButton 无法以编程方式在 UIKit 中工作

UIButton will not work in UIKit programmatically

提问人:willd 提问时间:11/1/2023 最后编辑:General Grievancewilld 更新时间:11/14/2023 访问量:54

问:

我一直在 swift UIKit 中以编程方式构建绘图应用程序。我已经能够为我在枚举中定义的每个案例创建。我可以看到每个按钮都出现在每个.我的问题是我创建了一个名为的函数,该函数应该分配与每个按钮相对应的颜色,但是当我单击它时,它不起作用,甚至没有在检测到单击事件的控制台中打印。UIButtonsPencilPencil.color@objbuttonClicked

以下是保存铅笔画笔属性的变量:

 var lastPoint = CGPoint.zero
    var color = UIColor.black
    var brushWidth: CGFloat = 10.0
    var opacity: CGFloat = 1.0
    var swiped = false

这是我分配每种颜色的函数:buttonClicked

  @objc func buttonClicked(_ sender: UIButton){
        guard let pencil = Pencil(tag: sender.tag) else {
          return
        }
        
        color = pencil.color
     
        if pencil == .eraser {
          opacity = 1.0
        }
        print("button Clicked")
    }

为每个按钮创建按钮的函数Pencil.color

    func createColorButton() -> [UIButton]{
        
        var buttons: [UIButton] = []
        for pencilCase in Pencil.allCases {
            let button = UIButton(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
            button.backgroundColor = pencilCase.color
            button.tag = pencilCase.hashValue
            button.addTarget(self, action: #selector(self.buttonClicked(_:)), for: .touchUpInside)

            buttons.append(button)
        }
     return buttons
    }

这里只是为了提供上下文,这是我的枚举的参考Pencil

enum Pencil: CaseIterable {
    
    case black
    case grey
    case red
    case darkblue
    case lightBlue
    case darkGreen
    case lightGreen
    case brown
    case orange
    case yellow
    case eraser
    
    init?(tag: Int) {
        switch tag {
        case 1:
          self = .black
        case 2:
          self = .grey
        case 3:
          self = .red
        case 4:
          self = .darkblue
        case 5:
          self = .lightBlue
        case 6:
          self = .darkGreen
        case 7:
          self = .lightGreen
        case 8:
          self = .brown
        case 9:
          self = .orange
        case 10:
          self = .yellow
        case 11:
          self = .eraser
        default:
          return nil
        }
      }
    // cases for penil.color 
    var color: UIColor {
      switch self {
      case .black:
        return .black
      case .grey:
        return UIColor(white: 105/255.0, alpha: 1.0)
      case .red:
        return UIColor(red: 1, green: 0, blue: 0, alpha: 1.0)
      case .darkblue:
        return UIColor(red: 0, green: 0, blue: 1, alpha: 1.0)
      case .lightBlue:
        return UIColor(red: 51/255.0, green: 204/255.0, blue: 1, alpha: 1.0)
      case .darkGreen:
        return UIColor(red: 102/255.0, green: 204/255.0, blue: 0, alpha: 1.0)
      case .lightGreen:
        return UIColor(red: 102/255.0, green: 1, blue: 0, alpha: 1.0)
      case .brown:
        return UIColor(red: 160/255.0, green: 82/255.0, blue: 45/255.0, alpha: 1.0)
      case .orange:
        return UIColor(red: 1, green: 102/255.0, blue: 0, alpha: 1.0)
      case .yellow:
        return UIColor(red: 1, green: 1, blue: 0, alpha: 1.0)
      case .eraser:
        return .white
      }
    }
}

我试图在里面调用addTarget,但这也不起作用,所以这是我的代码的第一个版本viewDidLoad

override func viewDidLoad() {
        super.viewDidLoad()
        
      
        let buttons = createColorButton()
        stackView.spacing = 5
        for button in buttons {
            stackView.addArrangedSubview(button)
                       button.layer.borderWidth = 1
                       button.layer.borderColor = UIColor.blue.cgColor
            
                       button.layer.cornerRadius = 10
                
            }
        view.addSubview(stackView)
        NSLayoutConstraint.activate([
            stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 200)
            ])
        
        setupImageViews()
        
    }

我还能做些什么来完成这项工作?createColorButton

Swift UIKIT UIBuint AddTarget

评论

1赞 MadProgrammer 11/1/2023
就个人而言,我会看看,因为我怀疑是否会返回您期望的值。相反,我要么在 上实现一个属性来控制每个情况的返回值,要么让枚举扩展,以便您可以直接使用button.tag = pencilCase.hashValuehashValuetagenumIntrawValue
0赞 HangarRash 11/1/2023
如果未调用按钮处理程序,则很可能按钮被其上视图剪裁。使用 Xcode 的“调试视图层次结构”功能进行验证。我注意到您没有为堆栈视图提供任何水平约束。或者正在调用处理程序,但它未到达 print 语句。@MadProgrammer的评论涵盖了可能的原因。
0赞 willd 11/1/2023
@MadProgrammer @HangarRash 因此,在调试视图层次结构后,我发现它没有被 superview 剪裁,然后我尝试在“guard let”语句中添加 print 语句,我在控制台中看到了 print 语句(我知道这不是我刚刚为测试目的所做的正确语法),我知道它是通过视图结构正确调用的,但是我仍然无法更改我的 当我单击UI按钮时。什么。我仍然应该尝试在枚举上实现标签属性,或者我还能尝试什么?color
1赞 MadProgrammer 11/1/2023
打印视图的标记并将其与枚举进行比较

答:

0赞 DonMag 11/3/2023 #1

有多种方法可以处理枚举...对于您的情况,它易于使用,并将按钮标签设置为索引:Pencil.allCases.enumerated()

class ColorButtonsVC: UIViewController {
    
    var color: UIColor = .white
    var opacity: CGFloat = 1.0

    let cLabel = UILabel()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        let buttons = createColorButton()
        let stackView = UIStackView()
        stackView.spacing = 5
        for button in buttons {
            stackView.addArrangedSubview(button)
            button.layer.borderWidth = 1
            button.layer.borderColor = UIColor.blue.cgColor
            
            button.layer.cornerRadius = 10
            
        }
        stackView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(stackView)
        NSLayoutConstraint.activate([
            stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 200),
            stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        ])
        
        cLabel.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(cLabel)
        NSLayoutConstraint.activate([
            cLabel.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 8.0),
            cLabel.widthAnchor.constraint(equalToConstant: 200.0),
            cLabel.heightAnchor.constraint(equalToConstant: 60.0),
            cLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        ])
        cLabel.text = "Color"
        cLabel.textAlignment = .center
        //setupImageViews()
        
    }
    
    func createColorButton() -> [UIButton]{
        var buttons: [UIButton] = []
        for (idx, pencilCase) in Pencil.allCases.enumerated() {
            let button = UIButton(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
            button.backgroundColor = pencilCase.color
            // the Pencil enum starts at 1 instead of Zero
            //  so add 1 to the index
            button.tag = idx + 1
            button.addTarget(self, action: #selector(self.buttonClicked(_:)), for: .touchUpInside)
            buttons.append(button)
        }
        return buttons
    }
    
    @objc func buttonClicked(_ sender: UIButton){

        guard let pencil = Pencil(tag: sender.tag) else {
            return
        }
        
        color = pencil.color
        
        if pencil == .eraser {
            opacity = 1.0
        }
        print("button Clicked:", sender.tag)
        
        cLabel.backgroundColor = color
    }
}