Программное действие UIButton не вызывается - PullRequest
0 голосов
/ 24 августа 2018

Я создал класс, который будет создавать / управлять несколькими кнопками и метками и добавлять их в представление, но я не могу получить действия от запускаемых кнопок.

Вот простая версиякода без 'MakerClass', который работает нормально (код находится в основном ViewController):

@objc func pressed(_ sender: UIButton!) {
    print("pressed")
}
    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


    let backgroundButton = UIButton()
    backgroundButton.backgroundColor = UIColor.green
    backgroundButton.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
    self.view.addSubview(backgroundButton)

    backgroundButton.addTarget(self, action: #selector(pressed(_:)), for: .touchUpInside)

}

А вот версия, в которой я поместил создание кнопки в другой класс

ViewController

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


    MakerClass(intoView: self.view)                
}

MakerClass

class MakerClass {


    var backgroundButton: UIButton = UIButton()


    @objc func iwastouched(_ sender: UIButton!) {
        print("touched")
    }

    init(intoView: UIView){

        backgroundButton.backgroundColor = UIColor.red
        backgroundButton.frame = CGRect(x: 0, y: 200, width: 100, height: 100)
        intoView.addSubview(backgroundButton)
        backgroundButton.addTarget(self, action: #selector(iwastouched(_:)), for: .touchUpInside)

    }


}

Проект, который я использовал для игры с этим, можно загрузить с здесь

Возможно, я поступаю неправильно, поскольку я новичок в программировании на iOS

1 Ответ

0 голосов
/ 24 августа 2018

Проблема в том, что, поскольку вы не сохраняете MakerClass, цель для кнопки установлена ​​на NSNull()

. Это можно увидеть, добавив…

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

    let buttons = view.subviews as! [UIButton]
    for button in buttons {

        print(button)
        print("Target :", button.allTargets.first!)
    }
}
<UIButton: 0x7ff89fd04110; frame = (0 0; 100 100); opaque = NO; layer = <CALayer: 0x60000257bac0>>
Target : <TestProgrammaticButton.ViewController: 0x7ff89ff08050>
<UIButton: 0x7ff89fd05020; frame = (0 200; 100 100); opaque = NO; layer = <CALayer: 0x60000257bb40>>
Target : <null>

Если вы хотите, чтобы кнопка запускала метод действия в вашем контроллере вида, вы можете сделать ...

class MakerClass {
    init(intoView: UIView, with viewController: ViewController) {
        // configure
        backgroundButton.addTarget(viewController, action: #selector(iwastouched(_:)), for: .touchUpInside)
    }
}

Но это связывает ваш MakerClass с этим конкретным ViewControllerclass.

Вместо этого MakerClass может вернуть отформатированную кнопку и затем установить цель / действие в контроллере представления.


Обновление

Согласно комментарию @ RakeshaShastri ниже, так как цель установлена ​​на NSNull(), приложение будет идти вверх по цепочке респондента в поисках UIResponder (обычно UIView или UIViewController) с правильной сигнатурой функции.Цепочка респондента в вашем случае:…

backgroundButton -> ViewController.view -> ViewController -> UIWindow

Вы можете проверить это, добавив

@objc func iwastouched(_ sender: UIButton!) {
    print("touched")
}

к вашему ViewController классу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...