在创建自定义 UIButton 时以未捕获的 NSException 类型异常终止



我想制作一个自定义按钮并在自定义按钮类内的选择器中给出输入,但它给了我一个错误按摩。 我该如何修复它

我在操场上测试了它,因为当我跑到模拟器时,应用程序崩溃了。 这是操场上出现的错误

终止与未捕获的 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")
  }
}

新问题是

无法转换值类型 (

视图控制器) -> () 预期的参数类型 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

无法将类型"(配置文件控制器)-> () -> (配置文件控制器)"的值转换为预期的参数类型"UIView控制器"

这是我在配置文件控制器和自定义按钮中的代码

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

应删除选择器作为初始值设定项参数。应在创建按钮的任何位置设置目标。您还需要放置@objc,以便handleButtonSelector调用。您的设置将如下所示,

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)

并且不要忘记用objc标记handleButton

@objc func handleButton() {

删除

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

来自自定义按钮类。并添加

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

in viewDidLoad() 方法。还在视图控制器类中添加选择器方法

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

应用程序崩溃,因为在下面一行中,您已将目标设置为customButton类中的self

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

并且customButton类没有方法handleButton

handleButton在视图控制器中,因此您必须将目标设置为视图控制器

所以你必须对代码进行轻微的修改,如下所示

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")
 }
}

此行将导致崩溃:

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")
   }
}

或者将添加目标放在视图控制器类中,例如,

let testButton = customButton(titleName: "Test", selectorName: "handleButton")
testButton.addTarget(self, action: Selector("handleButton"), for: .touchUpInside)

Swift 4.2 中,

请使用,

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

对于handleButton,需要 Obj-C 运行时才能查找给定选择器的方法实现,

@objc func handleButton() {
  print("handle button selected")
}

相关内容

最新更新