我基本上想传递一个数组索引,但是我收到一条错误消息,并且无法解决问题。
我要访问的索引在我的dropDownView
(didSelectRowAt
)内部。
class dropDownView: UIView, UITableViewDelegate, UITableViewDataSource {
var dropDownOptions = [String]()
var tableView = UITableView()
var delegate : dropDownProtocol!
var selectedWishlistDelegate: selectedWishlistProtocol!
override init(frame: CGRect) {
super.init(frame: frame)
tableView.backgroundColor = UIColor.lightGray
self.backgroundColor = UIColor.lightGray
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(tableView)
tableView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dropDownOptions.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = dropDownOptions[indexPath.row]
cell.backgroundColor = UIColor.lightGray
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.delegate.dropDownPressed(string: dropDownOptions[indexPath.row])
self.selectedWishlistDelegate.didSelectWishlist(idx: indexPath.row) // fatal error
self.tableView.deselectRow(at: indexPath, animated: true)
}
}
//MARK: Protocols
protocol selectedWishlistProtocol {
func didSelectWishlist(idx: Int)
}
要在我的ExampleViewController
中访问它,我尝试了以下操作:
extension ExampleViewController: selectedWishlistProtocol{
func didSelectWishlist(idx: Int) {
self.selectedWishlistIDX = idx
}
}
现在我收到此错误:
线程1:致命错误:在隐式展开一个可选值时意外发现nil
为什么indexPath.row
nil
??上面的delegate
可以正常工作。
可能是初学者的错误,因为我对delegates
不太满意,但我对每次帮助都很感激:)
更新
我在我的DropDownBtn`类中实例化了dropDownView
:
class DropDownBtn: UIButton, DropDownProtocol {
func dropDownPressed(string: String) {
self.setTitle(string, for: .normal)
self.dismissDropDown()
}
var dropView = DropDownView()
var height = NSLayoutConstraint()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.lightGray
dropView = DropDownView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0))
dropView.delegate = self
dropView.translatesAutoresizingMaskIntoConstraints = false
}
override func didMoveToSuperview() {
self.superview?.addSubview(dropView)
self.superview?.bringSubviewToFront(dropView)
dropView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
dropView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
dropView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
height = dropView.heightAnchor.constraint(equalToConstant: 0)
}
var isOpen = false
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if isOpen == false {
isOpen = true
NSLayoutConstraint.deactivate([self.height])
if self.dropView.tableView.contentSize.height > 150 {
self.height.constant = 150
} else {
self.height.constant = self.dropView.tableView.contentSize.height
}
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropView.layoutIfNeeded()
self.dropView.center.y += self.dropView.frame.height / 2
}, completion: nil)
} else {
isOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.dropView.center.y -= self.dropView.frame.height / 2
self.dropView.layoutIfNeeded()
}, completion: nil)
}
}
func dismissDropDown() {
isOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: {
self.dropView.center.y -= self.dropView.frame.height / 2
self.dropView.layoutIfNeeded()
}, completion: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
答案 0 :(得分:2)
确定
var selectedWishlistDelegate:SelectedWishlistProtocol!
不是nil,这意味着在实例化设置视图时
let v = DropDownView()
v.selectedWishlistDelegate = // some value
答案 1 :(得分:1)
此处的最佳做法是使您的delegate
和listener
引用为可选。在这里,您是force unwrapping selectedWishlistDelegate
,而没有先设置它。通过在声明!
后使用selectedWishlistDelegate
,您可以断言该引用不会为nil,但似乎是。这会导致运行时错误,并使您的应用程序崩溃。
要解决此问题,请对此进行更改:
var delegate : dropDownProtocol!
var selectedWishlistDelegate: selectedWishlistProtocol!
对此:
var delegate : dropDownProtocol?
var selectedWishlistDelegate: selectedWishlistProtocol?
这:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.delegate.dropDownPressed(string: dropDownOptions[indexPath.row])
self.selectedWishlistDelegate.didSelectWishlist(idx: indexPath.row) // fatal error
self.tableView.deselectRow(at: indexPath, animated: true)
}
对此:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.delegate?.dropDownPressed(string: dropDownOptions[indexPath.row])
self.selectedWishlistDelegate?.didSelectWishlist(idx: indexPath.row) // fatal error
self.tableView.deselectRow(at: indexPath, animated: true)
}
然后您需要更改:
class DropDownBtn: UIButton, DropDownProtocol {
收件人:
class DropDownBtn: UIButton, DropDownProtocol, selectedWishlistProtocol {
func didSelectWishlist(idx: indexPath.row) {
self.selectedWishlistIDX = idx
}
最后,您应该设置``,以便更改此内容:
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.lightGray
dropView = DropDownView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0))
dropView.delegate = self
dropView.translatesAutoresizingMaskIntoConstraints = false
}
对此:
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.lightGray
dropView = DropDownView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0))
dropView.delegate = self
dropView.selectedWishlistDelegate = self
dropView.translatesAutoresizingMaskIntoConstraints = false
}
如果您尚未设置selectedWishlistDelegate
,这将保护您的应用程序不会崩溃,并使您可以更轻松地测试视图的功能。