使用一个功能程序触发多个按钮Maticali swift

使用一个功能程序触发多个按钮Maticali swift,swift,uibutton,selector,uistackview,Swift,Uibutton,Selector,Uistackview,试图总结我的代码。问题是我收到“newCalculator[2861:53607]-[UIButton buttonClicked:]:无法识别的选择器发送到实例0x7fd912651e50”错误,并试图理解我需要做什么?我研究了一些改变选择器语法的解决方案,但是这个问题仍然存在。我想要的是;在stackview中,我添加了多个带有订单的按钮,所有按钮在单击时都应该调用相同的函数 o// // ViewController.swift // newCalculator // // C

试图总结我的代码。问题是我收到“newCalculator[2861:53607]-[UIButton buttonClicked:]:无法识别的选择器发送到实例0x7fd912651e50”错误,并试图理解我需要做什么?我研究了一些改变选择器语法的解决方案,但是这个问题仍然存在。我想要的是;在stackview中,我添加了多个带有订单的按钮,所有按钮在单击时都应该调用相同的函数

   o//
//  ViewController.swift
//  newCalculator
//
//  Created by taylank on 17.10.2019.
//  Copyright © 2019 TKT. All rights reserved.
//

import UIKit
var stackViews = [UIStackView]()
class ViewController: UIViewController {


    override func viewDidLoad() {
        super.viewDidLoad()

        //Layer 1
        let containerStackView1 = UIStackView()
        containerStackView1.translatesAutoresizingMaskIntoConstraints = false
        containerStackView1.axis = .vertical
        containerStackView1.distribution = .fillEqually
        containerStackView1.spacing = 1

        //Layer 2
        let topHalfView2 = UIView()
        topHalfView2.translatesAutoresizingMaskIntoConstraints = false
        topHalfView2.backgroundColor = .white
        let botHalfView2 = UIView()
        botHalfView2.translatesAutoresizingMaskIntoConstraints = false


        //Layer 3
        let topLabel3 = UILabel()
        topLabel3.translatesAutoresizingMaskIntoConstraints = false
        topLabel3.text = "0"
        topLabel3.font = UIFont.boldSystemFont(ofSize: 40)

        let containerStackView3 = UIStackView()
        containerStackView3.translatesAutoresizingMaskIntoConstraints = false
        containerStackView3.axis = .vertical
        containerStackView3.distribution = .fillEqually
        containerStackView3.spacing = 1

        //Layer 4
        stackViews = createStackViews(from: 0, to: 4, align: "h")
        let yamaView = UIView()
        yamaView.translatesAutoresizingMaskIntoConstraints = false
        yamaView.backgroundColor = .black

        //ADDING VIEWS TO SCENE .VIEW->Contstckview1->Top-BotHalfView->contstckview2-ResultLabel->horzstackviews
        containerStackView1.addArrangedSubview(topHalfView2)
        containerStackView1.addArrangedSubview(botHalfView2)
        view.addSubview(containerStackView1)
        topHalfView2.addSubview(topLabel3)
        botHalfView2.addSubview(containerStackView3)

        containerStackView3.addArrangedSubview(stackViews[0])
        view.addSubview(yamaView)

        //stackViews[0].topAnchor.constraint(equalTo: containerStackView3.topAnchor, constant: 0).isActive = true

        for a in 1...stackViews.count-1{
              containerStackView3.addArrangedSubview(stackViews[a])

           // stackViews[a].leadingAnchor.constraint(equalTo: stackViews[0].leadingAnchor, constant: 0).isActive = true
            // stackViews[a].trailingAnchor.constraint(equalTo: stackViews[0].trailingAnchor, constant: 0).isActive = true



            }
        //stackViews[0].leadingAnchor.constraint(equalTo: containerStackView3.leadingAnchor, constant: 0).isActive = true
      //  stackViews[0].trailingAnchor.constraint(equalTo: containerStackView3.trailingAnchor, constant: 0).isActive = true

        //Uiheight--v:?--uibottom--uifillequ

        //ConstraintsStackView1
        containerStackView1.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
        containerStackView1.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
        containerStackView1.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
        containerStackView1.heightAnchor.constraint(equalToConstant: view.frame.height).isActive = true

        //TopHalfView2
        topHalfView2.topAnchor.constraint(equalTo: containerStackView1.topAnchor, constant: 0).isActive = true
        topHalfView2.leadingAnchor.constraint(equalTo: containerStackView1.leadingAnchor, constant: 0).isActive = true
        topHalfView2.trailingAnchor.constraint(equalTo: containerStackView1.trailingAnchor, constant: 0).isActive = true
       // topHalfView2.heightAnchor.constraint(equalToConstant: containerStackView1.frame.height/2).isActive = true
        //creates problem conflicts with other constraint fill equally?


        //BotHalfView2
        botHalfView2.bottomAnchor.constraint(equalTo: containerStackView1.bottomAnchor, constant: 0).isActive = true
        botHalfView2.leadingAnchor.constraint(equalTo: containerStackView1.leadingAnchor, constant: 0).isActive = true
        botHalfView2.trailingAnchor.constraint(equalTo: containerStackView1.trailingAnchor, constant: 0).isActive = true
       // botHalfView2.heightAnchor.constraint(equalToConstant: containerStackView1.frame.height/2).isActive = true

         //topLabel3
        topLabel3.bottomAnchor.constraint(equalTo: topHalfView2.bottomAnchor, constant: 0).isActive = true
        topLabel3.trailingAnchor.constraint(equalTo: topHalfView2.trailingAnchor, constant: -5).isActive = true

        //ConstraintsStackView3
            containerStackView3.leadingAnchor.constraint(equalTo: botHalfView2.leadingAnchor, constant: 0).isActive = true
            containerStackView3.trailingAnchor.constraint(equalTo: botHalfView2.trailingAnchor, constant: 0).isActive = true
            containerStackView3.topAnchor.constraint(equalTo: botHalfView2.topAnchor, constant: 0).isActive = true
            containerStackView3.bottomAnchor.constraint(equalTo: botHalfView2.bottomAnchor, constant: 0).isActive = true


        //constraint button

       stackViews[4].arrangedSubviews[2].widthAnchor.constraint(equalTo: stackViews[4].arrangedSubviews[1].widthAnchor,multiplier: 1).isActive = true //sonbutton bir yandakine
        stackViews[4].arrangedSubviews[1].widthAnchor.constraint(equalTo: stackViews[4].arrangedSubviews[0].widthAnchor,multiplier: 0.5).isActive = true // ortadaki buton en soldakine

        yamaView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        yamaView.topAnchor.constraint(equalTo: stackViews[4].bottomAnchor).isActive = true
        yamaView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
       yamaView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true


    }


}
func createButtons(_ named: String...)->[UIButton]{
    var c = 0
return named.map { name in

        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitle(name, for: .normal)
        button.backgroundColor = UIColor.gray
        button.setTitleColor(.white, for: .normal)
        button.layer.cornerRadius = 1
       button.addTarget(button, action: #selector(buttonClicked) ,for:.touchUpInside)


        return button


}



}
@objc func buttonClicked(_ sender:UIButton){

      print("clicked")
  }

func createStackViews(from x: Int,to y:Int, align type: String)->[UIStackView]{
    // use tag instead of name---
    //use dictionary..keys name values



    if (type == "v"){


        for a in x...y{

            let stackVertical = UIStackView()
                stackVertical.translatesAutoresizingMaskIntoConstraints = false
                stackVertical.axis = .vertical
                stackVertical.spacing = 1
                stackVertical.distribution = .fillEqually
                stackVertical.tag = a

        }





    }
    else if(type=="h"){
        var counter = 0
        for a in x...y{
                    counter += 1

                    switch counter{
                    case 1: let stackHorizontal = UIStackView(arrangedSubviews:createButtons("Clear","+/-","%","÷"))

                    stackHorizontal.translatesAutoresizingMaskIntoConstraints = false
                    stackHorizontal.axis = .horizontal
                    stackHorizontal.spacing = 1
                    stackHorizontal.distribution = .fillEqually
                    stackHorizontal.tag = 90+a
                    stackViews.append(stackHorizontal)

                    case 2: let stackHorizontal = UIStackView(arrangedSubviews:createButtons("7","8","9","x"))

                    stackHorizontal.translatesAutoresizingMaskIntoConstraints = false
                    stackHorizontal.axis = .horizontal
                    stackHorizontal.spacing = 1
                    stackHorizontal.distribution = .fillEqually
                    stackHorizontal.tag = 100 + a
                    stackViews.append(stackHorizontal)

                    case 3: let stackHorizontal = UIStackView(arrangedSubviews:createButtons("4","5","6","-"))

                    stackHorizontal.translatesAutoresizingMaskIntoConstraints = false
                    stackHorizontal.axis = .horizontal
                    stackHorizontal.spacing = 1
                    stackHorizontal.distribution = .fillEqually
                    stackHorizontal.tag = 110+a
                    stackViews.append(stackHorizontal)

                    case 4: let stackHorizontal = UIStackView(arrangedSubviews:createButtons("1","2","3","+"))

                     stackHorizontal.translatesAutoresizingMaskIntoConstraints = false
                     stackHorizontal.axis = .horizontal
                     stackHorizontal.spacing = 1
                     stackHorizontal.distribution = .fillEqually
                     stackHorizontal.tag = 120 + a
                     stackViews.append(stackHorizontal)

                    case 5: let stackHorizontal = UIStackView(arrangedSubviews:createButtons("0",",","="))

                     stackHorizontal.translatesAutoresizingMaskIntoConstraints = false
                     stackHorizontal.axis = .horizontal
                     stackHorizontal.spacing = 1
                    stackHorizontal.distribution = .fillProportionally
                     stackHorizontal.tag = 130 + a
                     stackViews.append(stackHorizontal)
                    default:
                        break
            }

             }


        return stackViews
    }



    return [UIStackView.init()]
 }
------------解决方案-------

所有函数都在viewcontroller类中 替换

button.addTarget(button, action: "buttonClicked:" ,for:.touchUpInside)




您有几个问题:

您的选择器需要是
选择器(按钮点击(:)
,所以

button.addTarget(self, action: #selector(buttonClicked(:)) ,for:.touchUpInside)

函数
buttonClicked(:)
createButtons()
需要在视图控制器类中。实际上,
buttonClicked(:)
是一个全局函数,这意味着它不能成为目标/操作的一部分。(操作方法需要位于目标对象(通常是拥有按钮的视图控制器)内。

问题是;不能使用self(未解决的标识符)“#selector”的参数不能引用全局函数“buttonClicked”,最后一个参数是objc只能用于类的成员、objc协议和类的具体扩展。我想我遗漏了一些东西。我的函数不在viewcontroller类CreateStacksView内,createButtons在类外。请共享它存在的位置?您还应该按照Sh_Khan和我的建议进行操作,并将
addTarget(u∶action:)
方法更改为使用
action:#selector(buttonClicked(:)
表单来指定操作的选择器。您的代码使用
action:“buttonClicked:”
将操作指定为字符串,编译器无法验证此类方法是否存在。这就是您崩溃的原因。(您的目标对象不包含指定的方法。)如果使用
#选择器()
用于指定操作的选择器的语法,编译器可以验证您是否有与选择器签名匹配的方法。我上面评论中的操作位应该是
action:#selector(buttonClicked(35;))
。我缺少匿名参数的下划线。
button.addTarget(self, action: #selector(buttonClicked) ,for:.touchUpInside)
@objc func buttonClicked(_ sender:UIButton){
import UIKit
var stackViews = [UIStackView]()
class ViewController: UIViewController {


    override func viewDidLoad() {
        super.viewDidLoad()

        //Layer 1
        let containerStackView1 = UIStackView()
        containerStackView1.translatesAutoresizingMaskIntoConstraints = false
        containerStackView1.axis = .vertical
        containerStackView1.distribution = .fillEqually
        containerStackView1.spacing = 1

        //Layer 2
        let topHalfView2 = UIView()
        topHalfView2.translatesAutoresizingMaskIntoConstraints = false
        topHalfView2.backgroundColor = .white
        let botHalfView2 = UIView()
        botHalfView2.translatesAutoresizingMaskIntoConstraints = false


        //Layer 3
        let topLabel3 = UILabel()
        topLabel3.translatesAutoresizingMaskIntoConstraints = false
        topLabel3.text = "0"
        topLabel3.font = UIFont.boldSystemFont(ofSize: 40)

        let containerStackView3 = UIStackView()
        containerStackView3.translatesAutoresizingMaskIntoConstraints = false
        containerStackView3.axis = .vertical
        containerStackView3.distribution = .fillEqually
        containerStackView3.spacing = 1

        //Layer 4
        stackViews = createStackViews(from: 0, to: 4, align: "h")
        let yamaView = UIView()
        yamaView.translatesAutoresizingMaskIntoConstraints = false
        yamaView.backgroundColor = .black

        //ADDING VIEWS TO SCENE .VIEW->Contstckview1->Top-BotHalfView->contstckview2-ResultLabel->horzstackviews
        containerStackView1.addArrangedSubview(topHalfView2)
        containerStackView1.addArrangedSubview(botHalfView2)
        view.addSubview(containerStackView1)
        topHalfView2.addSubview(topLabel3)
        botHalfView2.addSubview(containerStackView3)

        containerStackView3.addArrangedSubview(stackViews[0])
        view.addSubview(yamaView)

        //stackViews[0].topAnchor.constraint(equalTo: containerStackView3.topAnchor, constant: 0).isActive = true

        for a in 1...stackViews.count-1{
              containerStackView3.addArrangedSubview(stackViews[a])

           // stackViews[a].leadingAnchor.constraint(equalTo: stackViews[0].leadingAnchor, constant: 0).isActive = true
            // stackViews[a].trailingAnchor.constraint(equalTo: stackViews[0].trailingAnchor, constant: 0).isActive = true



            }
        //stackViews[0].leadingAnchor.constraint(equalTo: containerStackView3.leadingAnchor, constant: 0).isActive = true
      //  stackViews[0].trailingAnchor.constraint(equalTo: containerStackView3.trailingAnchor, constant: 0).isActive = true

        //Uiheight--v:?--uibottom--uifillequ

        //ConstraintsStackView1
        containerStackView1.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
        containerStackView1.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
        containerStackView1.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
        containerStackView1.heightAnchor.constraint(equalToConstant: view.frame.height).isActive = true

        //TopHalfView2
        topHalfView2.topAnchor.constraint(equalTo: containerStackView1.topAnchor, constant: 0).isActive = true
        topHalfView2.leadingAnchor.constraint(equalTo: containerStackView1.leadingAnchor, constant: 0).isActive = true
        topHalfView2.trailingAnchor.constraint(equalTo: containerStackView1.trailingAnchor, constant: 0).isActive = true
       // topHalfView2.heightAnchor.constraint(equalToConstant: containerStackView1.frame.height/2).isActive = true
        //creates problem conflicts with other constraint fill equally?


        //BotHalfView2
        botHalfView2.bottomAnchor.constraint(equalTo: containerStackView1.bottomAnchor, constant: 0).isActive = true
        botHalfView2.leadingAnchor.constraint(equalTo: containerStackView1.leadingAnchor, constant: 0).isActive = true
        botHalfView2.trailingAnchor.constraint(equalTo: containerStackView1.trailingAnchor, constant: 0).isActive = true
       // botHalfView2.heightAnchor.constraint(equalToConstant: containerStackView1.frame.height/2).isActive = true

         //topLabel3
        topLabel3.bottomAnchor.constraint(equalTo: topHalfView2.bottomAnchor, constant: 0).isActive = true
        topLabel3.trailingAnchor.constraint(equalTo: topHalfView2.trailingAnchor, constant: -5).isActive = true

        //ConstraintsStackView3
            containerStackView3.leadingAnchor.constraint(equalTo: botHalfView2.leadingAnchor, constant: 0).isActive = true
            containerStackView3.trailingAnchor.constraint(equalTo: botHalfView2.trailingAnchor, constant: 0).isActive = true
            containerStackView3.topAnchor.constraint(equalTo: botHalfView2.topAnchor, constant: 0).isActive = true
            containerStackView3.bottomAnchor.constraint(equalTo: botHalfView2.bottomAnchor, constant: 0).isActive = true


        //constraint button

       stackViews[4].arrangedSubviews[2].widthAnchor.constraint(equalTo: stackViews[4].arrangedSubviews[1].widthAnchor,multiplier: 1).isActive = true //sonbutton bir yandakine
        stackViews[4].arrangedSubviews[1].widthAnchor.constraint(equalTo: stackViews[4].arrangedSubviews[0].widthAnchor,multiplier: 0.5).isActive = true // ortadaki buton en soldakine

        yamaView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        yamaView.topAnchor.constraint(equalTo: stackViews[4].bottomAnchor).isActive = true
        yamaView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
       yamaView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true


    }



func createButtons(_ named: String...)->[UIButton]{
    var c = 0
return named.map { name in

        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitle(name, for: .normal)
        button.backgroundColor = UIColor.gray
        button.setTitleColor(.white, for: .normal)
        button.layer.cornerRadius = 1
       button.addTarget(self, action: #selector(buttonClicked) ,for:.touchUpInside)


        return button


}



}
@objc func buttonClicked(_ sender:UIButton){

      print("clicked")
  }

func createStackViews(from x: Int,to y:Int, align type: String)->[UIStackView]{
    // use tag instead of name---
    //use dictionary..keys name values



    if (type == "v"){


        for a in x...y{

            let stackVertical = UIStackView()
                stackVertical.translatesAutoresizingMaskIntoConstraints = false
                stackVertical.axis = .vertical
                stackVertical.spacing = 1
                stackVertical.distribution = .fillEqually
                stackVertical.tag = a

        }





    }
    else if(type=="h"){
        var counter = 0
        for a in x...y{
                    counter += 1

                    switch counter{
                    case 1: let stackHorizontal = UIStackView(arrangedSubviews:createButtons("Clear","+/-","%","÷"))

                    stackHorizontal.translatesAutoresizingMaskIntoConstraints = false
                    stackHorizontal.axis = .horizontal
                    stackHorizontal.spacing = 1
                    stackHorizontal.distribution = .fillEqually
                    stackHorizontal.tag = 90+a
                    stackViews.append(stackHorizontal)

                    case 2: let stackHorizontal = UIStackView(arrangedSubviews:createButtons("7","8","9","x"))

                    stackHorizontal.translatesAutoresizingMaskIntoConstraints = false
                    stackHorizontal.axis = .horizontal
                    stackHorizontal.spacing = 1
                    stackHorizontal.distribution = .fillEqually
                    stackHorizontal.tag = 100 + a
                    stackViews.append(stackHorizontal)

                    case 3: let stackHorizontal = UIStackView(arrangedSubviews:createButtons("4","5","6","-"))

                    stackHorizontal.translatesAutoresizingMaskIntoConstraints = false
                    stackHorizontal.axis = .horizontal
                    stackHorizontal.spacing = 1
                    stackHorizontal.distribution = .fillEqually
                    stackHorizontal.tag = 110+a
                    stackViews.append(stackHorizontal)

                    case 4: let stackHorizontal = UIStackView(arrangedSubviews:createButtons("1","2","3","+"))

                     stackHorizontal.translatesAutoresizingMaskIntoConstraints = false
                     stackHorizontal.axis = .horizontal
                     stackHorizontal.spacing = 1
                     stackHorizontal.distribution = .fillEqually
                     stackHorizontal.tag = 120 + a
                     stackViews.append(stackHorizontal)

                    case 5: let stackHorizontal = UIStackView(arrangedSubviews:createButtons("0",",","="))

                     stackHorizontal.translatesAutoresizingMaskIntoConstraints = false
                     stackHorizontal.axis = .horizontal
                     stackHorizontal.spacing = 1
                    stackHorizontal.distribution = .fillProportionally
                     stackHorizontal.tag = 130 + a
                     stackViews.append(stackHorizontal)
                    default:
                        break
            }

             }


        return stackViews
    }



    return [UIStackView.init()]
 }


 }
button.addTarget(self, action: #selector(buttonClicked(:)) ,for:.touchUpInside)