当滚动比tableview中的最后一个帖子/项目更远时,应用程序崩溃并且我收到错误消息:“在解开可选值时意外地发现nil”。就像它试图找到另一个不存在的帖子,但我不知道为什么......在tableview中的帖子看起来就像他们应该的那样。
我认为这里有问题:
func tableView(_ tableView: UITableView, cellForRowAt indexpath: IndexPath) -> UITableViewCell {
let post = posts[indexpath.row]
if let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexpath) as? PostCell{
cell.configureCell(post: post)
return cell
} else {
return PostCell()
}
}
(当我删除else部分时,我收到此错误:“在预期返回'UITableViewCell'的函数中缺少返回值)
var posts = [Post]()
配置单元格:
func configureCell(post: Post) {
self.post = post
if post.altA.isEmpty == false {
altALabel.text = post.altA["text"] as? String
if let votes = post.altA["votes"]{
self.altAVotesLbl.text = "\(votes)"
}
} else {
print("No data found in Alt A")
}
if post.altB.isEmpty == false {
altBLabel.text = post.altB["text"] as? String
if let votes = post.altB["votes"]{
self.altBVotesLbl.text = "\(votes)"
}
} else {
print("No data found in Alt B")
}
if post.altD.isEmpty == false {
altDLabel.text = post.altD["text"] as? String
if let votes = post.altD["votes"]{
self.altDVotesLbl.text = "\(votes)"
}
} else {
print("No data found in Alt D")
altDView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0)
altDVotesView.removeFromSuperview()
altDLabelView.removeFromSuperview()
}
if post.altC.isEmpty == false {
altCLabel.text = post.altC["text"] as? String
if let votes = post.altC["votes"]{
self.altCVotesLbl.text = "\(votes)"
}
} else {
print("No data found in Alt C")
self.altCView.removeFromSuperview()
self.botBtnsStackView.removeFromSuperview()
}
import Foundation
class Post {
private var _text: String!
private var _postKey: String!
private var _backgroundImg: Int!
private var _altA: Dictionary<String, Any>!
private var _altB: Dictionary<String, Any>!
private var _altC: Dictionary<String, Any>!
private var _altD: Dictionary<String, Any>!
//TEXT
var text: String {
return _text
}
//BACKGROUND
var backgroundImg: Int{
return _backgroundImg
}
//POSTKEY
var postKey: String{
return _postKey
}
//ALTERNATIVES
var altA: Dictionary<String, Any> {
return _altA
}
var altB: Dictionary<String, Any> {
return _altB
}
var altC: Dictionary<String, Any> {
return _altC
}
var altD: Dictionary<String, Any> {
return _altD
}
init(postKey: String, postData: Dictionary<String, Any>) {
self._postKey = postKey
if let text = postData["text"]{
self._text = text as! String
} else {
self._text = ""
}
if let backgroundImg = postData["backgroundImg"]{
self._backgroundImg = backgroundImg as! Int
}
if let altA = postData["altA"]{
self._altA = altA as! Dictionary<String, Any>
}
if let altB = postData["altB"]{
self._altB = altB as! Dictionary<String, Any>
}
if let altC = postData["altC"]{
self._altC = altC as! Dictionary<String, Any>
} else {
let emptyDictionary = [String: Any]()
self._altC = emptyDictionary
}
if let altD = postData["altD"]{
self._altD = altD as! Dictionary<String, Any>
} else {
let emptyDictionary = [String: Any]()
self._altD = emptyDictionary
}
}
}
其余的tableview代码(没什么特别之处):
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
答案 0 :(得分:0)
从superview中删除视图似乎不是一个好主意。我使用isHidden = true替换了所有removeFromSuperview()方法,并且它现在正在工作。
例如:altDLabelView.removeFromSuperview()现在是altDLabelView.isHidden = True
感谢您的帮助!
答案 1 :(得分:0)
是的,问题是您要从superview中删除self.altCView
和其他视图。
你必须记住,细胞是可重复使用的,所以每当它们离开屏幕时,它们就会“出列”并重复使用。
因此,如果一个单元格最初是一个altD单元格,并且您删除了所有其他超级视图,那么它将被重新用作altC单元格。尝试设置标签会使应用程序崩溃,因为从superview中删除会从内存中释放它(如果你使用的是弱引用,由于某种原因是IBOutlet的默认值。另一个提示,让你所有的IBOutlets都强大我只是觉得它更好)< / p>
一旦从superview中删除了视图,除非你重新添加它们,否则它们将永远消失,所以我会避免在运行多次的代码上执行此操作,例如cellForRowAtIndex
尝试将它们设置为隐藏(或框架为CGZero
)(但同样要警惕细胞重用。假设您获得的细胞永远不会具有正确的值,因此如果您使用它们,则始终设置为取消隐藏如果你没有使用它们,总是设置为隐藏。如果你确实需要它,忘记setHidden = false是一个常见的错误。它可能在上一次使用单元格时仍然被隐藏)