ios - 如果可用,将项目添加到特定 TableView 行

标签 ios arrays swift uitableview parse-server

我正在尝试从同一个类(class)(在学校)的 Parse 数据库中创建一个用户 TableView 。所有用户都必须有用户名,但并非所有人都会为应用提供全名或设置个人资料图片。我使用这段代码:

let studentsQuery = PFQuery(className:"_User")
studentsQuery.whereKey("objectId", containedIn: studentsArray! as! [AnyObject])

let query2 = PFQuery.orQueryWithSubqueries([studentsQuery])

query2.findObjectsInBackgroundWithBlock {
    (results: [PFObject]?, error: NSError?) -> Void in

    if error != nil {

        // Display error in tableview

    } else if results! == [] {

        spinningActivity.hideAnimated(true)

        print("error")

    } else if results! != [] {

        if let objects = results {

            for object in objects {

                if object.objectForKey("full_name") != nil {

                    let studentName = object.objectForKey("full_name")!  as! String

                    self.studentNameResults.append(studentName)


                }

                if object.objectForKey("username") != nil {

                    let studentUsername = object.objectForKey("username")!  as! String

                    self.studentUsernameResults.append(studentUsername)

                }

                if object.objectForKey("profile_picture") != nil {

                    let studentProfilePictureFile = object.objectForKey("profile_picture") as! PFFile

                    studentProfilePictureFile.getDataInBackgroundWithBlock({ (image: NSData?, error: NSError?) in

                        if error == nil {

                            let studentProfilePicture : UIImage = UIImage(data: image!)!
                            self.studentProfilePictureResults.append(studentProfilePicture)

                        } else {

                            print("Can't get profile picture")

                            // Can't get profile picture

                        }

                        self.studentsTableView.reloadData()

                    })

                    spinningActivity.hideAnimated(true)

                } else {

                    // no image

                }

            }
        }
} else {

    spinningActivity.hideAnimated(true)

    print("error")

}
}

如果所有用户都有用户名、全名和个人资料图片,则此代码可以正常工作。但是,我无法弄清楚如何获取用户用户名的 tableView 并将用户名或图片添加到用户相应的 tableViewCell 仅当用户有一张照片。以下是我的 tableView 的配置方式:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return studentUsernameResults.count

}


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("studentsCell", forIndexPath: indexPath) as! StudentsInClassInformationTableViewCell

        cell.studentProfilePictureImageView.layer.cornerRadius = cell.studentProfilePictureImageView.frame.size.width / 2
        cell.studentProfilePictureImageView.clipsToBounds = true

        cell.studentProfilePictureImageView.image = studentProfilePictureResults[indexPath.row]

        cell.studentUsernameLabel.text = studentUsernameResults[indexPath.row]

        cell.studentNameLabel.text = studentNameResults[indexPath.row]


        return cell

}

studentProfilePictureResultsstudentUsernameResultsstudentNameResults 来自从 Parse 中提取的用户图片、用户名和姓名结果的数组。如果用户没有个人资料图片,我会收到错误消息,Index is out of range。显然,这意味着有三个名字、三个用户名和只有两张图片,Xcode 不知道如何配置单元格。我的问题:如何设置一个包含用户用户名的 tableView,并将他们的姓名和个人资料图片放在同一个单元格中,前提是他们有一个?

最佳答案

尝试将不同的属性存储在不同的数组中将是一个问题,因为正如您所发现的,您最终会遇到特定用户没有属性的问题。您可以使用一个可选数组,这样您就可以为不存在的属性存储 nil,但是将 PFObject 本身存储在一个数组中并访问cellForRowAtIndexPath 中的属性,而不是拆分属性。

由于获取照片需要单独的异步操作,因此您可以单独存储它。与其使用数组来存储检索到的照片,这会遇到同样的排序问题,不如使用字典,由用户 ID 索引;尽管对于大量学生来说,使用 SDWebImage 之类的工具根据 cellForRowAtIndexPath 中的要求下载照片可能会更有效。

// these are instance properties defined at the top of your class
var students: [PFObject]?
var studentPhotos=[String:UIImage]()

// This is in your fetch function
let studentsQuery = PFUser.Query()
    studentsQuery.whereKey("objectId", containedIn: studentsArray! as! [AnyObject])

let query2 = PFQuery.orQueryWithSubqueries([studentsQuery])

query2.findObjectsInBackgroundWithBlock {
    (results: [PFObject]?, error: NSError?) -> Void in
    guard (error == nil) else {
        print(error)
        spinningActivity.hideAnimated(true)
        return
    }

    if let results = results {
        self.students = results
            for object in results {
                if let studentProfilePictureFile = object.objectForKey("profile_picture") as? PFFile {
                    studentProfilePictureFile.getDataInBackgroundWithBlock({ (image: NSData?, error: NSError?) in
                    guard (error != nil) else {
                        print("Can't get profile picture: \(error)")
                        return
                    }

                if let studentProfilePicture = UIImage(data: image!) {
                    self.studentPhotos[object["username"]!]=studentProfilePicture
                }
            }
     }
     spinningActivity.hideAnimated(true)
     self.tableview.reloadData()
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if self.students != nil {
        return self.students!.count
    }
    return 0 
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("studentsCell", forIndexPath: indexPath) as! StudentsInClassInformationTableViewCell

    cell.studentProfilePictureImageView.layer.cornerRadius = cell.studentProfilePictureImageView.frame.size.width / 2
    cell.studentProfilePictureImageView.clipsToBounds = true

    let student = self.students[indexPath.row]

    if let studentPhoto = self.studentPhotos[student["username"]!] {
        cell.studentProfilePictureImageView.image = studentProfilePictureResults[indexPath.row] 
    } else {
        cell.studentProfilePictureImageView.image = nil
    }

    cell.studentUsernameLabel.text = student["username"]!

    if let fullName = student["full_name"] {
        cell.studentNameLabel.text = fullName
    } else {
        cell.studentNameLabel.text = ""
    return cell
}

一些其他的提示;

  • 在 iOS 世界中并没有真正使用 _ 来分隔字段名称中的单词;驼峰式是首选,所以 fullName 而不是 full_name
  • 如果您有一个 class 字段或引用对象,那么您的 Parse 查询看起来会更有效率,这样您就不需要提供其他类成员的数组。

关于ios - 如果可用,将项目添加到特定 TableView 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36817673/

相关文章:

ios - 整数文字 '115000159351' 存储到 'Int' 时会溢出,但在一个项目中工作正常,但在另一个项目中则不然 - Swift

html - 从 HTML 获取图像大小

ios - 复制 Google 的搜索 iOS 卡片动画

c - Windows 上的堆损坏操作 C 中的结构指针数组

regex - 如何将正则表达式匹配到字符串末尾?

ios - 是 scrollRangeToVisible(_ :) considered slow if a large attributed text is set in UITextView?

ios - UIButton 在第一次加载时不响应触摸,但在从另一个 View Controller 返回后工作

javascript - 在javascript中以相同的顺序打乱两个数组

php - 如何在 php 中构建一个 json 返回值?

ios - Swift:迭代字典项并将其与数组中的字典项进行比较