我已经在堆栈上待了一段时间,但从来不需要问一个问题,因为我总是在经过一番搜索后找到了答案,但现在我陷入了困境。我一直在搜索并经历一些试验和错误以获得答案,并且我一直在犯同样的错误。我基本上在屏幕的下半部分制作了一个带有tableView的个人资料页面。上半部分正在填写当前用户的信息。与视图控制器和单元视图控制器的所有连接似乎都很好。但是,在加载致命错误时,表格视图将显示没有数据并崩溃:
在展开可选值时意外发现了nil。
我也相信cellForRowAtIndexPath
根本没有被调用,因为"测试"没有打印到日志。
我使用的是最新版本的Swift和Parse。
我对swift相对较新,所以我会继续在这里发布我的整个代码,任何帮助都会受到赞赏。
import UIKit
import Parse
import ParseUI
class profileViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet var tableView: UITableView!
@IBOutlet var profilePic: UIImageView!
@IBOutlet var userName: UILabel!
@IBOutlet var userBio: UILabel!
var image: PFFile!
var username = String()
var userbio = String()
var content = [String]()
@IBAction func logout(sender: AnyObject) {
PFUser.logOut()
let Login = storyboard?.instantiateViewControllerWithIdentifier("ViewController")
self.presentViewController(Login!, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
profilePic.layer.borderWidth = 1
profilePic.layer.masksToBounds = false
profilePic.layer.borderColor = UIColor.blackColor().CGColor
profilePic.layer.cornerRadius = profilePic.frame.height/2
profilePic.clipsToBounds = true
tableView.delegate = self
tableView.dataSource = self
self.tableView.rowHeight = 80
self.hideKeyboardWhenTappedAround()
if let nameQuery = PFUser.currentUser()!["name"] as? String {
username = nameQuery
}
if PFUser.currentUser()!["bio"] != nil {
if let bioQuery = PFUser.currentUser()!["bio"] as? String {
userbio = bioQuery
}
}
if PFUser.currentUser()!["icon"] != nil {
if let iconQuery = PFUser.currentUser()!["icon"] as? PFFile {
image = iconQuery
}
}
self.userName.text = username
self.userBio.text = userbio
if image != nil {
self.image.getDataInBackgroundWithBlock { (data, error) -> Void in
if let downIcon = UIImage(data: data!) {
self.profilePic.image = downIcon
}
}
}
// Do any additional setup after loading the view.
var postsQuery = PFQuery(className: "Posts")
postsQuery.whereKey("username", equalTo: username)
postsQuery.findObjectsInBackgroundWithBlock( { (posts, error) -> Void in
if error == nil {
if let objects = posts {
self.content.removeAll(keepCapacity: true)
for object in objects {
if object["postText"] != nil {
self.content.append(object["postText"] as! String)
}
self.tableView.reloadData()
}
}
}
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
print(content.count)
return content.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let profCell = self.tableView.dequeueReusableCellWithIdentifier("profCell", forIndexPath: indexPath) as! profTableViewCell
print("test")
profCell.userPic.layer.borderWidth = 1
profCell.userPic.layer.masksToBounds = false
profCell.userPic.layer.borderColor = UIColor.blackColor().CGColor
profCell.userPic.layer.cornerRadius = profCell.userPic.frame.height/2
profCell.userPic.clipsToBounds = true
profCell.userPic.image = self.profilePic.image
profCell.name.text = self.username
profCell.content.text = content[indexPath.row]
return profCell
}
}
答案 0 :(得分:4)
我让它坐了几天我回来意识到我犯了一个非常愚蠢的错误。我现在和大约15个视图控制器一起工作,并且意识到我有一个与我在上面发布的同名的副本。我现在明白为什么你说使用故事板非常粘。虽然,我不需要它,但我很感激帮助,我可以说我学到了一些东西。
答案 1 :(得分:0)
您可能需要注册用于自定义UITableViewCell的类:
self.tableView.registerClass(profTableViewCell.self, forCellReuseIdentifier: "profCell")
除非您在IB中使用原型单元格,否则此注册不会自动为您完成。
因此,当您调用dequeue方法( !
强制解包)时,您将遇到问题。如果您没有为标识符注册类或nib,则dequeueReusableCellWithIdentifier:forIndexPath:
断言。
注册课程时,始终会返回一个单元格。
在这种情况下,旧的(dequeueReusableCellWithIdentifier:
)版本返回nil,然后您可以创建自己的单元格。
你应该在?
演员阵容期间使用 as
来避免崩溃,尽管你不会获得任何单元格!
另外一个提示,你应该总是使用大写字母作为类名,ProfTableViewCell
而不是profTableViewCell
,这只是很好的实践。
iOS天才Rob Mayoff在最佳答案中提供了更多信息:Assertion failure in dequeueReusableCellWithIdentifier:forIndexPath:
答案 2 :(得分:0)
您必须创建一个简单的NSObject类,其中包含image,username和userbio作为可选值。然后你必须在你的profileviewcontroller中声明一个这样的var:
var allProfiles = [yourNSObjectClass]()
在你的cellForRowAtIndexPath中添加:
let profile = yourNSObjectClass()
profile = allProfiles[indexPath.row]
cell.username.text = profile.username
然后继续。
也可以使用:
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
而不是:
self.tableView.reloadData()