Reputation: 381
I have a uiview with a couple of elements that I use for a comment function in my app. There is a text field, button, and line separator. Everything renders fine however when I click submit the app crashes and I get this error.
'NSInvalidArgumentException', reason: '-[UIButton copyWithZone:]: unrecognized selector sent to instance 0x7fe58c459620'
I don't see anything wrong with my implementation so this error is a little confusing to me. This is the class for my UIView
import UIKit
protocol CommentInputAccessoryViewDelegate {
func handleSubmit(for comment: String?)
}
class CommentInputAccessoryView: UIView, UITextFieldDelegate {
var delegate: CommentInputAccessoryViewDelegate?
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
fileprivate let submitButton: UIButton = {
let submitButton = UIButton(type: .system)
submitButton.setTitle("Submit", for: .normal)
submitButton.setTitleColor(.black, for: .normal)
submitButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
submitButton.addTarget(self, action: #selector(handleSubmit), for: .touchUpInside)
//submitButton.isEnabled = false
return submitButton
}()
lazy var commentTextField: UITextField = {
let textField = UITextField()
textField.placeholder = "Add a comment"
textField.delegate = self
textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
return textField
}()
override init(frame: CGRect) {
super.init(frame: frame)
// backgroundColor = .red
addSubview(submitButton)
submitButton.anchor(top: topAnchor, left: nil, bottom: bottomAnchor, right:rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 12, width: 50, height: 0)
addSubview(commentTextField)
commentTextField.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: submitButton.leftAnchor, paddingTop: 0, paddingLeft: 12, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
setupLineSeparatorView()
}
fileprivate func setupLineSeparatorView(){
let lineSeparatorView = UIView()
lineSeparatorView.backgroundColor = UIColor.rgb(red: 230, green: 230, blue: 230)
addSubview(lineSeparatorView)
lineSeparatorView.anchor(top:topAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0.5)
}
@objc func handleSubmit(for comment: String?){
guard let commentText = commentTextField.text else{
return
}
delegate?.handleSubmit(for: commentText)
}
@objc func textFieldDidChange(_ textField: UITextField) {
let isCommentValid = commentTextField.text?.count ?? 0 > 0
if isCommentValid {
submitButton.isEnabled = true
}else{
submitButton.isEnabled = false
}
}
func clearCommentTextField(){
commentTextField.text = nil
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
This is the accompanying class that ultimately handles the submission through a protocol method
//allows you to gain access to the input accessory view that each view controller has for inputting text
lazy var containerView: CommentInputAccessoryView = {
let frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 50)
let commentInputAccessoryView = CommentInputAccessoryView(frame:frame)
commentInputAccessoryView.delegate = self
return commentInputAccessoryView
}()
@objc func handleSubmit(for comment: String?){
guard let comment = comment, comment.count > 0 else{
return
}
let userText = Comments(content: comment, uid: User.current.uid, profilePic: User.current.profilePic!,eventKey: eventKey)
sendMessage(userText)
// will clear the comment text field
self.containerView.clearCommentTextField()
}
extension NewCommentsViewController {
func sendMessage(_ message: Comments) {
ChatService.sendMessage(message, eventKey: eventKey)
}
}
Upvotes: 0
Views: 58
Reputation: 285082
The associated method for the target/action #selector(handleSubmit)
must be
@objc func handleSubmit(_ sender: UIButton) { ...
or
@objc func handleSubmit() { ...
Other forms are not supported.
Does the code compile at all?
Actually you can't use self
in the initializer let submitButton: UIButton = { .. }()
Upvotes: 1
Reputation: 269
The problem seems to be that UIButton doesn't have a copyWithZone method and that you can't define delegates for UIButtons:
what are the delegate methods available with uibutton
Upvotes: 0