调用 addTarget 时 UIView class 中的“无法识别的选择器发送到实例”
“Unrecognized selector sent to instance” in UIView class when calling addTarget
我正在尝试创建一个 DropDownMenu class,但是当我尝试对其中一个按钮调用 addTarget 时,会出现此错误。
unrecognized selector sent to instance 0x7fd167f06120' terminating with uncaught exception of type NSException
非常感谢任何帮助,没有答案是不好的!
这是我的全部class
class DropDownMenu: UIView {
// Main button or Pre
var main: UIButton! = UIButton(frame: CGRect(x: 0, y: 0, width: 46, height: 30))
var view: UIView!
// Title
var buttonTitles: [String]! = [""]
var titleColor: UIColor! = UIColor.black
var font: UIFont! = UIFont.systemFont(ofSize: 18)
// Individual Button
var buttonsBorderWidth: CGFloat! = 0
var buttonsBorderColor: UIColor? = UIColor.white
var buttonsCornerRadius: CGFloat! = 0
var color: UIColor! = UIColor.clear
// Button Images
var buttonsImageEdgeInsets: UIEdgeInsets? = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
var images: [UIImage]? = nil
// Onclick stuff
var target: UIViewController!
private var currentSelected: String? = nil
private var optionsStack = UIStackView()
init(main: UIButton) {
self.main = main
super.init(frame: CGRect())
}
func createDropDownMenu() {
main.addTarget(target, action: #selector(DropDownMenu.openDropdown(_:)), for: .touchUpInside)
print("Button Target?: \(main.allTargets), self.target: \(String(describing: target))")
let mainFrame = main.frame
optionsStack.frame = CGRect(x: mainFrame.minX, y: mainFrame.maxY, width: mainFrame.width, height: CGFloat(buttonTitles.count) * mainFrame.height)
optionsStack.axis = .vertical
view.addSubview(optionsStack)
var y: CGFloat! = 0
for title in buttonTitles {
let button = UIButton(frame: CGRect(x: 0, y: y, width: mainFrame.width, height: mainFrame.height))
button.setTitle(title, for: .normal)
button.setTitleColor(titleColor, for: .normal)
button.backgroundColor = color
button.titleLabel?.font = font
button.addTarget(target, action: #selector(DropDownMenu.onclick), for: .touchUpInside)
y += mainFrame.height
optionsStack.addArrangedSubview(button)
}
for button in optionsStack.arrangedSubviews {
button.isHidden = true
button.alpha = 0
}
}
@objc private func openDropdown(_ sender: UIButton) {
print("sender: \(String(describing: sender))")
optionsStack.arrangedSubviews.forEach { (button) in
UIView.animate(withDuration: 0.7) {
button.isHidden = !button.isHidden
button.alpha = button.alpha == 0 ? 1 : 0
self.view.layoutIfNeeded()
}
}
}
@objc private func onclick(_ sender: UIButton) {
let title = sender.titleLabel!.text
print(title as Any)
main.setTitle(title, for: .normal)
optionsStack.arrangedSubviews.forEach { (button) in
UIView.animate(withDuration: 0.7) {
button.isHidden = true
button.alpha = 0
}
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
这里是ViewController
中对象的代码和创建
let grade = UIButton(frame: CGRect(x: 50, y: 300, width: 80, height: 30))
grade.layer.borderWidth = 1
grade.setTitle("Grade", for: .normal)
grade.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
grade.setTitleColor(UIColor.black, for: .normal)
let gradeDP = DropDownMenu(main: main)
gradeDP.buttonTitles = ["Title 1", "Title 2", "Title 3"]
gradeDP.color = UIColor.gray
gradeDP.target = self
gradeDP.titleColor = UIColor.white
gradeDP.view = view
view.addSubview(grade)
gradeDP.createDropDownMenu()
createDropDownMenu() 函数中的第一个打印语句打印...
Button Target?: [AnyHashable(<HomeworkHelp.DropDownMenu: 0x7ffb555200b0; frame = (0 0; 0 0); layer = <CALayer: 0x600002bdf5c0>>)], self.target: Optional(<HomeworkHelp.CreateAccountViewController: 0x7ffb5550a7b0>)
在 mightknow 的帮助下编辑后,我想到了这个 class。它里面的 mainButton 没有任何 onclick 动作。
class DropDownMenu: UIStackView {
var options: [String]! = [] // Labels for all of the options
var titleButton: UIButton! = UIButton() // The Main Title Button
init(options: [String]) {
self.options = options
let mainFrame = titleButton.frame
super.init(frame: CGRect(x: mainFrame.minX, y: mainFrame.maxY, width: mainFrame.width, height: mainFrame.height * CGFloat(options.count)))
var y: CGFloat = 0
for title in self.options {
let button = UIButton(frame: CGRect(x: 0, y: y, width: self.frame.width, height: mainFrame.height))
button.setTitle(title, for: .normal)
button.setTitleColor(titleButton.titleLabel?.textColor, for: .normal)
button.backgroundColor = titleButton.backgroundColor
button.addTarget(self, action: #selector(dropDownOptionClicked(_:)), for: .touchUpInside)
button.isHidden = true
button.alpha = 0
self.addArrangedSubview(button)
y += 1
}
}
@objc func openDropDown(_ sender: UIButton) {
print("Open DropDownMenu")
for button in self.arrangedSubviews {
UIView.animate(withDuration: 0.7) {
button.isHidden = !button.isHidden
button.alpha = button.alpha == 0 ? 1 : 0
self.layoutIfNeeded()
self.superview?.layoutIfNeeded()
}
}
}
@objc private func dropDownOptionClicked(_ sender: UIButton) {
print(sender.titleLabel?.text as Any)
}
init() {
super.init(frame: CGRect.zero)
}
required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
而且我的 ViewController 是...
let dp = DropDownMenu(options: ["Label 1", "Label 2", "Label 3"])
let titleButton = UIButton(frame: CGRect(x: 100, y: 300, width: 180, height: 40))
titleButton.backgroundColor = UIColor.white
titleButton.setTitle("DropDownMenu", for: .normal)
titleButton.setTitleColor(UIColor.black, for: .normal)
titleButton.layer.borderWidth = 2
titleButton.addTarget(self, action: #selector(dp.openDropDown(_:)), for: .touchUpInside)
dp.titleButton = titleButton
错误...
Button Target?: [AnyHashable(<HomeworkHelp.DropDownMenu: 0x7ffb555200b0; frame = (0 0; 0 0); layer = <CALayer: 0x600002bdf5c0>>)], self.target: Optional(<HomeworkHelp.CreateAccountViewController: 0x7ffb5550a7b0>)
仍然出现,我不知道为什么。
当您调用的方法实际上是 DropDownMenu
class 的方法时,您将目标设置为 UIViewController
。您需要做的是将目标设置为 self
而不是 target
属性:
main.addTarget(self, action: #selector(DropDownMenu.openDropdown(_:)), for: .touchUpInside)
编辑:为了回应您的评论,这是我用来测试它的代码。我做了一些 layout/color 的选择只是为了让我清楚,但这有效:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let main = UIButton(frame: CGRect(x: 0, y: 100, width: 80, height: 30))
main.layer.borderWidth = 1
main.setTitle("Grade", for: .normal)
main.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
main.setTitleColor(UIColor.black, for: .normal)
let gradeDP = DropDownMenu(main: main)
gradeDP.buttonTitles = ["Title 1", "Title 2", "Title 3"]
gradeDP.color = UIColor.gray
gradeDP.target = self
gradeDP.titleColor = UIColor.white
gradeDP.view = UIView()
self.view.addSubview(gradeDP)
let b = self.view.bounds
gradeDP.frame = CGRect(x: b.minX, y: b.minY, width: b.width, height: b.height/2)
gradeDP.backgroundColor = UIColor.purple
gradeDP.target = self
gradeDP.addSubview(gradeDP.main)
gradeDP.createDropDownMenu()
}}
至于你的代码,我假设你在问题的第二部分添加的代码在你的 ViewController 的 viewDidLoad()
方法中,并且 main
您用来初始化 DropDownMenu
的变量是 ViewController 的一个实例变量,因为我在范围内的其他任何地方都看不到它。如果是这样的话,肯定有一些问题。他们是:
您实际上从未将 gradeDP
添加到您的视图层次结构中。如果那是行 gradeDP.view = view
应该做的,那不是。该代码实际做的是将 gradeDP
的 view
属性 设置为对 ViewController 的 view
属性 的引用。而且,除非您的 DropDownMenu class 中有您未包含的代码,否则您实际上并没有将该引用用于任何事情。因此,您可以完全删除该行,以及 DropDownMenu
class 中的 view
属性。如果您想要做的是将 ViewController 的视图设置为 gradeDP
,则该代码将是 self.view = gradeDP
,但实际上我不建议这样做。 UIViewController
的 view
属性 用于某些特殊功能,可能不应该被弄得太多。您可能想添加 gradeDP
作为子视图,就像我在上面的代码中所做的那样。
您创建的 grade
按钮未被您的 DropDownMenu 使用。我猜你打算用它来初始化而不是 main
变量(这超出了你的代码范围),就像这样:
let gradeDP = DropDownMenu(main: grade)
简而言之,除非在其他地方有您未共享的代码,否则您上面的代码所做的是创建一个标有“Grade”的 UIButton,该按钮可见但实际上不执行任何操作(并且不是你的 DropDownMenu) 和一个实际上不可见的 DropDownMenu,但会有一个 main
按钮调用 openDropdown(_:)
如果它是。我猜这不是它应该如何工作的。不过,希望我上面提供的代码可以帮助您到达想要的位置。
关于重建 class 以使其正常工作的建议,您可能希望从这样的事情开始:
class DropDownMenu : UIView {
var dropdownOptions : [String] = []
private var titleButton : UIButton = UIButton()
private var optionsStack : UIStackView = UIStackView()
private var optionsButtons : [UIButton] = []
@objc private func openDropdown(_ sender: UIButton) {
// Add code to make dropdown options appear. There are multiple ways of doing this. For instance, the optionsButtons could be hidden and then unhidden when it's clicked, or they could be created only once the button is clicked.
}
@objc private func selectedOption(_ sender: UIButton) {
// Code here for when option is selected
}
init(options: [String]) {
self.dropdownOptions = options
super.init(frame: CGRect.zero)
// Customize all of your subviews here, and add them to your DropDownMenu (as subviews)
// Add openDropdown(_:) target to self.titleButton
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
}
您已经为 class 的原始版本编写的很多代码都可以放在那里的函数中。另外,您的原始版本中有很多不必要的代码。例如,修复原始错误问题后,target
变量未被使用,view
变量已过时,并且 createDropDownMenu()
函数是不必要的,因为所有这些代码都可以在init(options:) 或 openDropdown(_:) 函数。
然后,如果您选择使用该模板构建 class,您将在 ViewController 的 viewDidLoad()
方法中使用以下代码实现它:
let dropdown = DropDownMenu(titles: ["Title 1", "Title 2", "Title 3"])
self.view.addSubview(dropdown)
// Follow that with layout code that ensures it's the proper size and in the proper location
我希望结合我的评论是有意义的,有帮助的,并且不会太过分。我建议做的是开始一个新的空项目(或目标)并构建您的 class 并将其添加到 ViewController 中,其中没有任何其他内容。这是隔离它并检查并确保一切看起来和工作正常的好方法。如果您想要关于如何构建 class 的替代建议,您实际上可以尝试将 DropDownMenu 设为 UIStackView
的子 class(而不是 UIView
)按钮和所有选项按钮都被安排在子视图中。这实际上可能更简单,因为如果您愿意的话,它可以减少中间人,并且当 opening/closing 下拉列表是 .arrangedSubviews
add/remove 视图时,您需要做的所有事情 属性.
同样重要的是,如果您的视图需要将信息(例如选择了哪个选项)传递回 ViewController,请确保对 ViewController 的引用标记为 weak
所以你不创建一个保留周期。
最后一点,如果您对没有快速修复让原始 class 正常工作感到失望并想继续尝试,那么 可能 是一种拼凑解决方案的方法(比如我第一个答案中的代码,它确实有效......),但最终它可能只会导致更多问题。所以,祝你一切顺利。
我终于明白了!目标必须是 DropDownMenu。
titleButton.addTarget(dp, action: #selector(dp.openDropDown(_:)), for: .touchUpInside)
这是剩余的代码...
let titleButton = UIButton(frame: CGRect(x: 50, y: 290, width: 100, height: 40))
titleButton.backgroundColor = UIColor.white
titleButton.setTitle("Grade", for: .normal)
titleButton.setTitleColor(UIColor.black, for: .normal)
titleButton.layer.borderWidth = 2
titleButton.layer.cornerRadius = 10
let dp = DropDownMenu(options: ["1", "Freshman", "Sophomore", "Junior", "Senior", "College"])
dp.titleButton = titleButton
dp.target = self
dp.borderWidth = 2
dp.spacing = 5
dp.cornerRadius = 10
dp.bgColor = UIColor.white
正在将其添加到子视图并创建它...
view.addSubview(titleButton)
view.addSubview(dp)
dp.createDropDownMenu()
我正在尝试创建一个 DropDownMenu class,但是当我尝试对其中一个按钮调用 addTarget 时,会出现此错误。
unrecognized selector sent to instance 0x7fd167f06120' terminating with uncaught exception of type NSException
非常感谢任何帮助,没有答案是不好的!
这是我的全部class
class DropDownMenu: UIView {
// Main button or Pre
var main: UIButton! = UIButton(frame: CGRect(x: 0, y: 0, width: 46, height: 30))
var view: UIView!
// Title
var buttonTitles: [String]! = [""]
var titleColor: UIColor! = UIColor.black
var font: UIFont! = UIFont.systemFont(ofSize: 18)
// Individual Button
var buttonsBorderWidth: CGFloat! = 0
var buttonsBorderColor: UIColor? = UIColor.white
var buttonsCornerRadius: CGFloat! = 0
var color: UIColor! = UIColor.clear
// Button Images
var buttonsImageEdgeInsets: UIEdgeInsets? = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
var images: [UIImage]? = nil
// Onclick stuff
var target: UIViewController!
private var currentSelected: String? = nil
private var optionsStack = UIStackView()
init(main: UIButton) {
self.main = main
super.init(frame: CGRect())
}
func createDropDownMenu() {
main.addTarget(target, action: #selector(DropDownMenu.openDropdown(_:)), for: .touchUpInside)
print("Button Target?: \(main.allTargets), self.target: \(String(describing: target))")
let mainFrame = main.frame
optionsStack.frame = CGRect(x: mainFrame.minX, y: mainFrame.maxY, width: mainFrame.width, height: CGFloat(buttonTitles.count) * mainFrame.height)
optionsStack.axis = .vertical
view.addSubview(optionsStack)
var y: CGFloat! = 0
for title in buttonTitles {
let button = UIButton(frame: CGRect(x: 0, y: y, width: mainFrame.width, height: mainFrame.height))
button.setTitle(title, for: .normal)
button.setTitleColor(titleColor, for: .normal)
button.backgroundColor = color
button.titleLabel?.font = font
button.addTarget(target, action: #selector(DropDownMenu.onclick), for: .touchUpInside)
y += mainFrame.height
optionsStack.addArrangedSubview(button)
}
for button in optionsStack.arrangedSubviews {
button.isHidden = true
button.alpha = 0
}
}
@objc private func openDropdown(_ sender: UIButton) {
print("sender: \(String(describing: sender))")
optionsStack.arrangedSubviews.forEach { (button) in
UIView.animate(withDuration: 0.7) {
button.isHidden = !button.isHidden
button.alpha = button.alpha == 0 ? 1 : 0
self.view.layoutIfNeeded()
}
}
}
@objc private func onclick(_ sender: UIButton) {
let title = sender.titleLabel!.text
print(title as Any)
main.setTitle(title, for: .normal)
optionsStack.arrangedSubviews.forEach { (button) in
UIView.animate(withDuration: 0.7) {
button.isHidden = true
button.alpha = 0
}
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
这里是ViewController
中对象的代码和创建let grade = UIButton(frame: CGRect(x: 50, y: 300, width: 80, height: 30))
grade.layer.borderWidth = 1
grade.setTitle("Grade", for: .normal)
grade.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
grade.setTitleColor(UIColor.black, for: .normal)
let gradeDP = DropDownMenu(main: main)
gradeDP.buttonTitles = ["Title 1", "Title 2", "Title 3"]
gradeDP.color = UIColor.gray
gradeDP.target = self
gradeDP.titleColor = UIColor.white
gradeDP.view = view
view.addSubview(grade)
gradeDP.createDropDownMenu()
createDropDownMenu() 函数中的第一个打印语句打印...
Button Target?: [AnyHashable(<HomeworkHelp.DropDownMenu: 0x7ffb555200b0; frame = (0 0; 0 0); layer = <CALayer: 0x600002bdf5c0>>)], self.target: Optional(<HomeworkHelp.CreateAccountViewController: 0x7ffb5550a7b0>)
在 mightknow 的帮助下编辑后,我想到了这个 class。它里面的 mainButton 没有任何 onclick 动作。
class DropDownMenu: UIStackView {
var options: [String]! = [] // Labels for all of the options
var titleButton: UIButton! = UIButton() // The Main Title Button
init(options: [String]) {
self.options = options
let mainFrame = titleButton.frame
super.init(frame: CGRect(x: mainFrame.minX, y: mainFrame.maxY, width: mainFrame.width, height: mainFrame.height * CGFloat(options.count)))
var y: CGFloat = 0
for title in self.options {
let button = UIButton(frame: CGRect(x: 0, y: y, width: self.frame.width, height: mainFrame.height))
button.setTitle(title, for: .normal)
button.setTitleColor(titleButton.titleLabel?.textColor, for: .normal)
button.backgroundColor = titleButton.backgroundColor
button.addTarget(self, action: #selector(dropDownOptionClicked(_:)), for: .touchUpInside)
button.isHidden = true
button.alpha = 0
self.addArrangedSubview(button)
y += 1
}
}
@objc func openDropDown(_ sender: UIButton) {
print("Open DropDownMenu")
for button in self.arrangedSubviews {
UIView.animate(withDuration: 0.7) {
button.isHidden = !button.isHidden
button.alpha = button.alpha == 0 ? 1 : 0
self.layoutIfNeeded()
self.superview?.layoutIfNeeded()
}
}
}
@objc private func dropDownOptionClicked(_ sender: UIButton) {
print(sender.titleLabel?.text as Any)
}
init() {
super.init(frame: CGRect.zero)
}
required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
而且我的 ViewController 是...
let dp = DropDownMenu(options: ["Label 1", "Label 2", "Label 3"])
let titleButton = UIButton(frame: CGRect(x: 100, y: 300, width: 180, height: 40))
titleButton.backgroundColor = UIColor.white
titleButton.setTitle("DropDownMenu", for: .normal)
titleButton.setTitleColor(UIColor.black, for: .normal)
titleButton.layer.borderWidth = 2
titleButton.addTarget(self, action: #selector(dp.openDropDown(_:)), for: .touchUpInside)
dp.titleButton = titleButton
错误...
Button Target?: [AnyHashable(<HomeworkHelp.DropDownMenu: 0x7ffb555200b0; frame = (0 0; 0 0); layer = <CALayer: 0x600002bdf5c0>>)], self.target: Optional(<HomeworkHelp.CreateAccountViewController: 0x7ffb5550a7b0>)
仍然出现,我不知道为什么。
当您调用的方法实际上是 DropDownMenu
class 的方法时,您将目标设置为 UIViewController
。您需要做的是将目标设置为 self
而不是 target
属性:
main.addTarget(self, action: #selector(DropDownMenu.openDropdown(_:)), for: .touchUpInside)
编辑:为了回应您的评论,这是我用来测试它的代码。我做了一些 layout/color 的选择只是为了让我清楚,但这有效:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let main = UIButton(frame: CGRect(x: 0, y: 100, width: 80, height: 30))
main.layer.borderWidth = 1
main.setTitle("Grade", for: .normal)
main.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
main.setTitleColor(UIColor.black, for: .normal)
let gradeDP = DropDownMenu(main: main)
gradeDP.buttonTitles = ["Title 1", "Title 2", "Title 3"]
gradeDP.color = UIColor.gray
gradeDP.target = self
gradeDP.titleColor = UIColor.white
gradeDP.view = UIView()
self.view.addSubview(gradeDP)
let b = self.view.bounds
gradeDP.frame = CGRect(x: b.minX, y: b.minY, width: b.width, height: b.height/2)
gradeDP.backgroundColor = UIColor.purple
gradeDP.target = self
gradeDP.addSubview(gradeDP.main)
gradeDP.createDropDownMenu()
}}
至于你的代码,我假设你在问题的第二部分添加的代码在你的 ViewController 的 viewDidLoad()
方法中,并且 main
您用来初始化 DropDownMenu
的变量是 ViewController 的一个实例变量,因为我在范围内的其他任何地方都看不到它。如果是这样的话,肯定有一些问题。他们是:
您实际上从未将
gradeDP
添加到您的视图层次结构中。如果那是行gradeDP.view = view
应该做的,那不是。该代码实际做的是将gradeDP
的view
属性 设置为对 ViewController 的view
属性 的引用。而且,除非您的 DropDownMenu class 中有您未包含的代码,否则您实际上并没有将该引用用于任何事情。因此,您可以完全删除该行,以及DropDownMenu
class 中的view
属性。如果您想要做的是将 ViewController 的视图设置为gradeDP
,则该代码将是self.view = gradeDP
,但实际上我不建议这样做。UIViewController
的view
属性 用于某些特殊功能,可能不应该被弄得太多。您可能想添加gradeDP
作为子视图,就像我在上面的代码中所做的那样。您创建的
grade
按钮未被您的 DropDownMenu 使用。我猜你打算用它来初始化而不是main
变量(这超出了你的代码范围),就像这样:let gradeDP = DropDownMenu(main: grade)
简而言之,除非在其他地方有您未共享的代码,否则您上面的代码所做的是创建一个标有“Grade”的 UIButton,该按钮可见但实际上不执行任何操作(并且不是你的 DropDownMenu) 和一个实际上不可见的 DropDownMenu,但会有一个 main
按钮调用 openDropdown(_:)
如果它是。我猜这不是它应该如何工作的。不过,希望我上面提供的代码可以帮助您到达想要的位置。
关于重建 class 以使其正常工作的建议,您可能希望从这样的事情开始:
class DropDownMenu : UIView {
var dropdownOptions : [String] = []
private var titleButton : UIButton = UIButton()
private var optionsStack : UIStackView = UIStackView()
private var optionsButtons : [UIButton] = []
@objc private func openDropdown(_ sender: UIButton) {
// Add code to make dropdown options appear. There are multiple ways of doing this. For instance, the optionsButtons could be hidden and then unhidden when it's clicked, or they could be created only once the button is clicked.
}
@objc private func selectedOption(_ sender: UIButton) {
// Code here for when option is selected
}
init(options: [String]) {
self.dropdownOptions = options
super.init(frame: CGRect.zero)
// Customize all of your subviews here, and add them to your DropDownMenu (as subviews)
// Add openDropdown(_:) target to self.titleButton
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
}
您已经为 class 的原始版本编写的很多代码都可以放在那里的函数中。另外,您的原始版本中有很多不必要的代码。例如,修复原始错误问题后,target
变量未被使用,view
变量已过时,并且 createDropDownMenu()
函数是不必要的,因为所有这些代码都可以在init(options:) 或 openDropdown(_:) 函数。
然后,如果您选择使用该模板构建 class,您将在 ViewController 的 viewDidLoad()
方法中使用以下代码实现它:
let dropdown = DropDownMenu(titles: ["Title 1", "Title 2", "Title 3"])
self.view.addSubview(dropdown)
// Follow that with layout code that ensures it's the proper size and in the proper location
我希望结合我的评论是有意义的,有帮助的,并且不会太过分。我建议做的是开始一个新的空项目(或目标)并构建您的 class 并将其添加到 ViewController 中,其中没有任何其他内容。这是隔离它并检查并确保一切看起来和工作正常的好方法。如果您想要关于如何构建 class 的替代建议,您实际上可以尝试将 DropDownMenu 设为 UIStackView
的子 class(而不是 UIView
)按钮和所有选项按钮都被安排在子视图中。这实际上可能更简单,因为如果您愿意的话,它可以减少中间人,并且当 opening/closing 下拉列表是 .arrangedSubviews
add/remove 视图时,您需要做的所有事情 属性.
同样重要的是,如果您的视图需要将信息(例如选择了哪个选项)传递回 ViewController,请确保对 ViewController 的引用标记为 weak
所以你不创建一个保留周期。
最后一点,如果您对没有快速修复让原始 class 正常工作感到失望并想继续尝试,那么 可能 是一种拼凑解决方案的方法(比如我第一个答案中的代码,它确实有效......),但最终它可能只会导致更多问题。所以,祝你一切顺利。
我终于明白了!目标必须是 DropDownMenu。
titleButton.addTarget(dp, action: #selector(dp.openDropDown(_:)), for: .touchUpInside)
这是剩余的代码...
let titleButton = UIButton(frame: CGRect(x: 50, y: 290, width: 100, height: 40))
titleButton.backgroundColor = UIColor.white
titleButton.setTitle("Grade", for: .normal)
titleButton.setTitleColor(UIColor.black, for: .normal)
titleButton.layer.borderWidth = 2
titleButton.layer.cornerRadius = 10
let dp = DropDownMenu(options: ["1", "Freshman", "Sophomore", "Junior", "Senior", "College"])
dp.titleButton = titleButton
dp.target = self
dp.borderWidth = 2
dp.spacing = 5
dp.cornerRadius = 10
dp.bgColor = UIColor.white
正在将其添加到子视图并创建它...
view.addSubview(titleButton)
view.addSubview(dp)
dp.createDropDownMenu()