завершается с неперехваченным исключением типа NSException при создании пользовательского UIButton - PullRequest
0 голосов
/ 26 декабря 2018

Я хочу создать пользовательскую кнопку и дать ввод внутри селектора внутри класса пользовательских кнопок, но это дает мне сообщение об ошибке.как я могу это исправить

Я тестировал его на игровой площадке, поскольку при запуске симулятора приложение зависало.это ошибка, отображаемая на детской площадке

, оканчивающаяся необработанным исключением типа NSException

это мой код на детской площадке

class customButton: UIButton {

let titleName: String
let selectorName: String

init(titleName: String, selectorName: String) {
    self.titleName = titleName
    self.selectorName = selectorName
    super.init(frame: .zero)

    self.setTitle(titleName, for: .normal)
    self.addTarget(self, action: Selector(selectorName), for: .touchUpInside)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
}

class viewController: UIViewController {

override func loadView() {
    super.loadView()

    let testButton = customButton(titleName: "Test", selectorName: "handleButton")
    testButton.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(testButton)
    testButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    testButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}

func handleButton() {
    print("Pressed")
  }
}

newпроблема

Невозможно преобразовать тип значения (viewController) -> () ожидаемый тип аргумента UIViewController

I make a custom UIButton with target selector as an input, when I try to add input in the custom button it show in Xcode

Невозможно преобразовать значение типа '(ProfileController) -> () -> (ProfileController) 'к ожидаемому типу аргумента' UIViewController

это мой код в моем ProfileController и моя настраиваемая кнопка

class CustomButton: UIButton {

let imageName: UIImage
let selectorName: String
let target: UIViewController

init(imageName: UIImage, selectorName: String, target: UIViewController) {
    self.imageName = imageName
    self.selectorName = selectorName
    self.target = target
    super.init(frame: .zero)

    self.setImage(imageName.withRenderingMode(.alwaysOriginal), for: .normal)
    self.addTarget(target, action: Selector(selectorName), for: .touchUpInside)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
}

class ProfileController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

let profileID = "profileID"

let profileImageView: UIImageView = {
    let iv = UIImageView()
    iv.image = #imageLiteral(resourceName: "581010.jpg-r_1280_720-f_jpg-q_x-xxyxx").withRenderingMode(.alwaysOriginal)
    iv.contentMode = .scaleAspectFill
    iv.clipsToBounds = true
    return iv
}()

let pickerImage = CustomButton(imageName: #imageLiteral(resourceName: "user-6"), selectorName: "handleImagePicker", target: self) //this is the error message show up in the target: self

Ответы [ 5 ]

0 голосов
/ 26 декабря 2018

In Swift 4.2 ,

Пожалуйста, используйте,

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

И для handleButton требуется среда выполнения Obj-C для поиска методареализация для данного селектора,

@objc func handleButton() {
  print("handle button selected")
}
0 голосов
/ 26 декабря 2018

Эта строка вызовет сбой:

self.addTarget(self, action: Selector(selectorName), for: .touchUpInside)

В этой строке вы говорите, что customButton имеет метод с именем selectorName, но на самом деле этот метод находится в viewController.

если вы добавите это внутри customButton класса, то

class customButton: UIButton {

let titleName: String
let selectorName: String

  init(titleName: String, selectorName: String) {
    self.titleName = titleName
    self.selectorName = selectorName
    super.init(frame: .zero)

    self.setTitle(titleName, for: .normal)
    self.addTarget(self, action: Selector("handleTap"), for: .touchUpInside)
  }

   required init?(coder aDecoder: NSCoder) {
     fatalError("init(coder:) has not been implemented")
   }
   @objc func handleButton() {
      print("Pressed")
   }
}

ИЛИ добавьте цель добавления в класс ViewController, например,

let testButton = customButton(titleName: "Test", selectorName: "handleButton")
testButton.addTarget(self, action: Selector("handleButton"), for: .touchUpInside)
0 голосов
/ 26 декабря 2018

Вы должны удалить селектор в качестве аргумента инициализатора.Вы должны установить цель, где бы вы ни создавали кнопку.Также вам нужно поставить @objc для handleButton, который будет вызываться Selector.Ваша установка будет выглядеть следующим образом:

class customButton: UIButton {

    let titleName: String

    init(titleName: String) {
        self.titleName = titleName
        super.init(frame: .zero)

        self.setTitle(titleName, for: .normal)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class viewController: UIViewController {

override func loadView() {
    super.loadView()

    let testButton = customButton(titleName: "Test")
    testButton.translatesAutoresizingMaskIntoConstraints = false
    testButton.addTarget(self, action: Selector("handleButton"), for: .touchUpInside)
    view.addSubview(testButton)
    testButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    testButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}

@objc func handleButton() {
    print("Pressed")
  }
}

В последних Swift вы должны изменить Selector("handleButton") на #selector(handleButton)


Если вы хотите сохранить текущую реализацию,вам нужно взять аргумент target в инициализаторе customButton, как показано ниже,

init(titleName: String, selectorName: String, target: UIViewController) {
    self.titleName = titleName
    self.selectorName = selectorName
    super.init(frame: .zero)

    self.setTitle(titleName, for: .normal)
    self.addTarget(target, action: Selector(selectorName), for: .touchUpInside)
}

Теперь вы передадите ссылку ViewController, как это,

let testButton = customButton(titleName: "Test", selectorName: "handleButton", target: self)

И нене забудьте пометить handleButton с objc как,

@objc func handleButton() {
0 голосов
/ 26 декабря 2018

Удалить

self.addTarget(self, action: Selector(selectorName), for: .touchUpInside)

из класса customButton.И добавить

testButton.addTarget(self, action: Selector(handleButton), for: .touchUpInside)

в методе viewDidLoad ().Также добавьте метод селектора в классе viewController

@objc func handleButton() {
    print("Pressed")
}
0 голосов
/ 26 декабря 2018

Приложение аварийно завершает работу, потому что в нижней строке вы установили цель на self в customButton классе

self.addTarget(self, action: Selector(selectorName), for: .touchUpInside)

и customButton классе, не имеющем метод handleButton

handleButton находится в viewcontroller, поэтому вы должны установить целевое значение для viewcontroller

, поэтому вам нужно внести небольшие изменения в ваш код, как показано ниже

class customButton: UIButton {

let titleName: String
let selectorName: String
let ViewController:UIViewController

init(titleName: String, selectorName: String,ViewController:UIViewController) {
self.titleName = titleName
self.selectorName = selectorName
self.ViewController = ViewController
super.init(frame: .zero)

self.setTitle(titleName, for: .normal)
self.addTarget(ViewController, action: Selector(selectorName), for: .touchUpInside)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

class viewController: UIViewController {

override func loadView() {
super.loadView()

let testButton = customButton(titleName: "Test", selectorName: "handleButton",ViewController:self)
testButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(testButton)
testButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
testButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}

func handleButton() {
print("Pressed")
 }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...