0

简单:我想用屏幕宽度和高度计算图片的大小以保持纵横比,类似于 9gag 应用程序。

如何在PFQueryTableViewController中制作单元格的动态高度,在我的单元格中,我在自定义单元格中有一个标签和 PFImageView并且加载工作正常,但是图片没有改变单元格的高度,并且所有单元格都具有相同的高度。我被困在这个问题上第三天了,它看起来像是来自 parse.com 框架的错误。当我使用 UITableViewController 时,我能够更改单元格高度,但解析框架会忽略它。

我正在使用情节提要并尝试使用自动布局约束而没有它。 TableViewController.swift

import UIKit
import Parse
import ParseUI
import Bolts
class TableViewController: PFQueryTableViewController {

// 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.pullToRefreshEnabled = true
    self.paginationEnabled = false

}

// Define the query that will provide the data for the table view
override func queryForTable() -> PFQuery {

    // Start the query object
    var query = PFQuery(className: "Image")
    query.whereKey("deleted", equalTo: 0)
    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("CustomCell") as! CustomTableViewCell!
    if cell == nil {
        cell = CustomTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "CustomCell")
    }

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

    // display initial image
    var initialThumbnail = UIImage(named: "question")
    cell.postImageView.image = initialThumbnail
    // extract image
    if let thumbnail = object?["image"] as? PFFile {
        cell.postImageView.file = thumbnail
        cell.postImageView.loadInBackground()
    }
    cell.postImageView.contentMode = UIViewContentMode.ScaleAspectFit
    cell.postImageView.clipsToBounds = true

    cell.actualWidth = cell.postImageView.image!.size.width
    cell.actualHeight = cell.postImageView.image!.size.height

    return cell
}


    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        var cell = tableView.dequeueReusableCellWithIdentifier("CustomCell") as! CustomTableViewCell!
        let aspect = cell.actualWidth / cell.actualHeight
        var height: CGFloat = cell.postImageView!.frame.size.width * aspect
        return height
    }
}

CustomTableViewCell.swift

import UIKit
import Parse
import ParseUI
class CustomTableViewCell: PFTableViewCell {
 var actualHeight: CGFloat = 10
 var actualWidth: CGFloat = 10
 @IBOutlet weak var postHeadlineLabel: UILabel!
 @IBOutlet weak var postImageView: PFImageView!
}

我在网上找到了一些建议,但它不起作用,并且似乎是我尝试过的 iOS8 解析框架的错误

cell.postImageView.contentMode = UIViewContentMode.ScaleAspectFit
cell.postImageView.clipsToBounds = true
cell.sendSubviewToBack(cell.postImageView)

或者

override func awakeFromNib() {
    self.setTranslatesAutoresizingMaskIntoConstraints(false)
}

更新 - 解析数据库https ://www.anony.ws/image/D6tp

4

2 回答 2

0

PFQueryTableViewController继承自UITableViewController,这意味着它符合UITableViewDelegate协议。在这里有一个可以覆盖的方法,称为:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat

在这里,您CGFloat应该50.0f根据indexPath.


更新 1

OP 提供了更多代码来详细说明问题


由于您正在调用tableView.dequeueReusableCellWithIdentifiertableView:heightForRowAtIndexPath那么这意味着一旦您准备好一个带有图像的单元格,那么它将一遍又一遍地继续使用此纵横比。tableView.dequeueReusableCellWithIdentifier您没有与提供的唯一对象相关联的逻辑indexPath

克服这个问题的一种方法是调用objectAtIndexPath(indexPath),这是一个来自 的方法PFQueryTableViewController。这将使您可以访问指定单元格的PFObjectand PFFile。这样做的缺点是您必须再次下载图像,从而使用大量带宽。它还会降低您的应用程序的速度,因为您必须等待它下载。

您也可以使用tableView.cellForRowAtIndexPath(indexPath)为该单元获取一些独特的东西,但不幸tableView:heightForRowAtIndexPath的是在之前调用过tableView:cellForRowAtIndexPathPFQueryTableViewController将导致应用程序崩溃。


我最好的建议是为您的Image类添加另一个字段到数据库中,该字段存储图像的纵横比。

如果由于您已经拥有大型数据库或其他一些充分的理由而无法做到这一点,那么我建议您制作一个可以计算纵横比的云功能。


更新 2

更新的解决方案来回答


在坐下来玩了一会儿之后,我设法为您的问题想出了一个解决方案。不幸的是,它并不漂亮,我仍然建议您将纵横比存储在您的数据库模式中作为最佳解决方案。

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return calculateHeightForRowAtIndexPath(indexPath);
}

func calculateHeightForRowAtIndexPath(indexPath: NSIndexPath) -> CGFloat {
    if let file = objectAtIndexPath(indexPath)?["image"] as? PFFile {
        let image = UIImage(data: file.getData()!)
        let imageToScreenRatio = tableView.bounds.size.width / (image?.size.width)!
        return imageToScreenRatio * (image?.size.height)!
    }
    else {
        return 50.0
    }
}

这真的很糟糕的原因是因为图像正在主 UI 线程中使用file.getData(). 相反file.getDataInBackgroundWithBlock(block)应该使用,但这会导致问题,因为calculateHeightForRowAtIndexPath在下载图像之前会返回。


更新 3

OP 提供了有关数据库模式的更多信息


由于您已经将比率存储在数据库中,因此您可以通过以下方式计算单元格高度:

func calculateHeightForRowAtIndexPath(indexPath: NSIndexPath) -> CGFloat {
    if let ratio = objectAtIndexPath(indexPath)?["aspect"] as? Float {
        return tableView.bounds.size.width / CGFloat(ratio)
    }
    else {
        return 50.0
    }
}
于 2015-06-07T17:16:21.893 回答
0

您正在实施的是错误的方法。在 cellForRowAtIndexPath 之前调用 heightForRowAtIndexPath。因此,它将在您的方法中返回错误的值。尝试改用设备宽度。根据我对您要求的理解,我在下面进行了更改。尝试一下并进行相应的更改,如果它有效,请告诉我..

在您的 heightForRowAtIndexPath 中,尝试更改

#define ASPECT_RATIO 0.5f
var height: CGFloat = UIScreen.mainScreen().bounds.size.width * ASPECT_RATIO

这将使单元格的高度成为设备宽度的一半。您可以根据需要更改纵横比的值。如果你有标签,你可以在高度变量中添加它的高度。

于 2015-06-08T06:23:10.303 回答