我想制作一个自定义按钮并在自定义按钮类内的选择器中给出输入,但它给了我一个错误按摩。 我该如何修复它
我在操场上测试了它,因为当我跑到模拟器时,应用程序崩溃了。 这是操场上出现的错误
终止与未捕获的 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,以便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)
并且不要忘记用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")
}