0

我在 Swift 和 PFQueryTableViewController 中使用 parse.com 框架,当我设置分页时它不起作用。如果数据库的行数少于 objectPerPage 中设置的行数,则它可以正常工作,但是如果行数更多并且当我运行应用程序时,它会一直显示加载屏幕并且没有下载任何内容,当我执行“刷新时滑动”时,它会崩溃为 错误

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 4]

ImagesTableViewController.swift

import UIKit
import Parse
import ParseUI
import Bolts

class ImagesTableViewController: PFQueryTableViewController {
@IBAction func unwindToSegue (segue : UIStoryboardSegue) {}

// Initialise the PFQueryTable tableview
override init(style: UITableViewStyle, className: String!) {
    super.init(style: style, className: className)
}

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    // Configure the PFQueryTableView
    self.parseClassName = "Image"
    self.pullToRefreshEnabled = true
    self.paginationEnabled = true
    self.objectsPerPage = 5

}

// Define the query that will provide the data for the table view
override func queryForTable() -> PFQuery {
    var query = PFQuery(className: "Image")
    query.whereKey("deleted", notEqualTo: 1)
    query.orderByDescending("createdAt")
    return query
}

//override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell {

    var cell = tableView.dequeueReusableCellWithIdentifier("ImageCell") as! ImageTVCell!
    if cell == nil {
        cell = ImageTVCell(style: UITableViewCellStyle.Default, reuseIdentifier: "ImageCell")
    }

    // Extract values from the PFObject to display in the table cell HEADLINE
    if let caption = object?["caption"] as? String {
        cell?.headlineLabel?.text = caption
    }

    // Display image
    var initialThumbnail = UIImage(named: "question")
    cell.postImageView.image = initialThumbnail
    if let thumbnail = object?["image"] as? PFFile {
        cell.postImageView.file = thumbnail
        cell.postImageView.loadInBackground()
    }

    return cell
}

// if I remove this code pagination work but the cell height is wrong
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return calculateHeightForRowAtIndexPath(indexPath)
}


func calculateHeightForRowAtIndexPath(indexPath: NSIndexPath) -> CGFloat {
    if let ratio = objectAtIndexPath(indexPath)?["aspect"] as? Float {
        println("Ratio: \(ratio)")
        return tableView.bounds.size.width / CGFloat(ratio)
    } else {
        return 50.0
    }
}


@IBAction func addNewPhotoButton(sender: UIBarButtonItem) {
    self.tabBarController?.tabBar.hidden = true
    self.performSegueWithIdentifier("showUploadNewImage", sender: self)
}

}
4

2 回答 2

0

出现此问题的原因是PFQueryTableViewController'tableView:numberOfRowsInSectionUITableViewDataSource. 我已经从包含的 GitHub 存储库中复制/粘贴了它PFQueryTableViewController.m

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSInteger count = [self.objects count];
    if ([self _shouldShowPaginationCell]) {
        count += 1;
    }
    return count;
}

它只是返回要显示的对象的数量(这是有道理的),但是如果启用了分页,则需要显示一个额外的单元格。这意味着您必须手动创建另一个带有文本“加载更多数据”或类似内容的单元格,这将触发刷新。


克服这个问题的一种方法是简单地用tableView:numberOfRowsInSection以下内容覆盖自己:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.objects!.count
}

更新 1

预建的Parse分页按钮在上一个答案中消失了


使用以下代码片段计算单元格的高度以显示预建的Parse分页按钮

func calculateHeightForRowAtIndexPath(indexPath: NSIndexPath) -> CGFloat {
    // Special case for pagination, using the pre-built one by Parse
    if (indexPath.row >= objects!.count) { return 50.0 }

    // Determines the height if an image ratio is present
    if let ratio = objectAtIndexPath(indexPath)?["aspect"] as? Float {
        println("Ratio: \(ratio)")
        return tableView.bounds.size.width / CGFloat(ratio)
    } else {
        return 50.0
    }
}
于 2015-06-09T12:17:09.707 回答
0

在 iOS 9.2 和 Xcode 7.2 Parse Pagination 中使用 Parse 1.11 可以完美运行。当用户在没有正确管理 Parse 添加的“Load More ...”行的情况下覆盖 Parse 本身使用的一些函数时,问题就会浮出水面。在我的情况下,我需要覆盖 tableView-canEditRowAtIndexPath 以确定当前用户是否可以根据对象的 ACL 删除行。我最初的功能是:

覆盖 func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {

    if let curUser = PFUser.currentUser() {
        let currentObject = objects![indexPath.row]
        if let acl = currentObject.ACL {
            return acl.getWriteAccessForUser(curUser)
        } else {
           return true
        }
    }
    return true
}

但是当在列表滚动期间遇到 Load More 行时,我得到了 indexpath 的异常。添加此测试后问题已解决:

    if (indexPath.row == self.objects!.count) { // row "Load More ..."
        return true
    }

如果没有此代码,Parse 不会添加“加载更多...”行!所以完整正确的覆盖函数是:

覆盖 func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {

    if (indexPath.row == self.objects!.count) { // row "Load More ..."
        return true
    }
    if let curUser = PFUser.currentUser() {
        let currentObject = objects![indexPath.row]
        if let acl = currentObject.ACL {
            return acl.getWriteAccessForUser(curUser)
        } else {
           return true
        }
    }
    return true
}

一般来说,包括 heightForRowAtIndexpath 在内的所有覆盖函数都必须注意启用分页时 Parse 添加的额外行。

高温高压

罗伯托·塔加

于 2015-12-26T12:02:51.183 回答