由于Completion Handler,单元格高度未正确计算

时间:2016-03-07 14:59:17

标签: ios swift uitableview autolayout constraints

我有一个单元格,其中包含从Amazon S3检索到的图像。此图像的高度将影响单元格的高度,但不幸的是,在确定单元格高度后,将在完成处理程序中检索图像。如果我向下滚动,单元格会正确重新加载。

滚动前(单元格高度不正确): enter image description here

滚动后(正确的单元格高度): enter image description here

单元格配置(为了便于阅读而编辑了一些不必要的东西):

func setCompletionCell(completion: CompletionPublic, contentType: String, classType: String){
        self.completionPub = completion
        self.selectionStyle = UITableViewCellSelectionStyle.None //Disables clicking

        //Setting image or video
        if (contentType == "image"){
            nwa.fetchSignedUrl("image/accepted/" + completion.mediaId + ".png") { (result, err) in
                self.nwa.fetchImage(result) { (image, err) in

                    if image != nil{
                        let screenSize: CGRect = UIScreen.mainScreen().bounds

                        var multiplyNum = screenSize.width / image.size.width
                        //if image height is going to be more than 60% of the screen, resize width and height to ensure that it isn't greater than 60% while keeping the aspect ratio correct
                        if ((image.size.height*multiplyNum) > (screenSize.height*0.6)){
                            multiplyNum = screenSize.height*0.6 / image.size.height
                            self.imageViewWidthConstraint.constant = (multiplyNum*image.size.width)
                            self.imageViewHeightConstraint.constant = screenSize.height*0.6
                        }
                        else{
                            self.imageViewWidthConstraint.constant = screenSize.width
                            self.imageViewHeightConstraint.constant = (multiplyNum*image.size.height)
                        }
                        self.imgView.image = image

                    }
                    else{
                        //no image returned
                    }


                }
            }
        }
        else if (contentType == "video"){
            ytplayer.loadWithVideoId(completion.mediaId)
        }


    }

TableView委托方法:

func callNWT(tableView: UITableView, completionHandler: () -> ()) {
    switch trendingToggle {
    case 0:
        nwt.getTrendingBounties(0) { (bountyArr, err) in
            //@TODO: change pos
            if bountyArr == nil {
                self.bountyArr = []
            }
            else {
                self.bountyArr = bountyArr as [BountyPublic]
            }

            if self.bountyArr.count == 0 {
                completionHandler()
            }
            self.reloadTableViewContent(tableView)
        }
    case 1:
        nwt.getTrendingCompletions(0) { (compArr, err) in
            if compArr == nil {
                self.compArr = []
            }
            else {
                self.compArr = compArr as [CompletionPublic]
            }
            if self.compArr.count == 0 {
                completionHandler()
            }
            self.reloadTableViewContent(tableView)
        }
    case 2:
        nwt.getTrendingPeople(0) { (peopleArr, err) in
            if peopleArr == nil {
                self.peopleArr = []
            }
            else {
                self.peopleArr = peopleArr as [Person]
            }

            if self.peopleArr.count == 0 {
                completionHandler()
            }
            self.reloadTableViewContent(tableView)
        }
    default:
        break
    }
}

func configureTableView(tableView: UITableView){
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 500.0
    tableView.allowsSelection = false; //disables selection highlighting of cells
    tableView.tableFooterView = UIView()
    tableView.dataSource = self
}

func reloadTableViewContent(tableView: UITableView) {
    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        tableView.reloadData()
        print("reloading table view content")
        tableView.scrollRectToVisible(CGRectMake(0, 0, 1, 1), animated: false)
    })
}


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if trendingToggle == 0 {
        return bountyArr.count
    }
    else if trendingToggle == 1 {
        return compArr.count
    }
    else {
        return peopleArr.count
    }
}


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if trendingToggle == 0 {
        return bountyCellAtIndexPath(tableView, indexPath: indexPath)
    }
    else if trendingToggle == 1 {
        return completedCellAtIndexPath(tableView, indexPath:indexPath)
    }
    else {
        return personCellAtIndexPath(tableView, indexPath: indexPath)
    }
}

func completedCellAtIndexPath(tableView: UITableView, indexPath:NSIndexPath) -> CompletedCell{
    var cell: CompletedCell
    if compArr[indexPath.row].contentType == "image" {
        cell = tableView.dequeueReusableCellWithIdentifier(completedImgCellIdentifier) as! CompletedCell
        let comp = compArr[indexPath.row]
        cell.setCompletionCell(comp, contentType: "image", classType: "trending")
    }
    else { //video
        cell = tableView.dequeueReusableCellWithIdentifier(completedVidCellIdentifier) as! CompletedCell
        let comp = compArr[indexPath.row]
        cell.setCompletionCell(comp, contentType: "video", classType: "trending")
    }
    return cell
}

如何确保第一次正确计算细胞高度?有没有办法可以延迟代码执行,直到检索到图像?或者这不是一个好主意?

1 个答案:

答案 0 :(得分:1)

在完成处理程序中重新加载tableview。

tableView.reloadData()

在数据源/委托协议的heightForRowAtIndex方法中,使用图像重新计算高度,并为每个单独的单元格返回适当的值。

当您调用reloadData()时,将再次调用所有数据源/委托方法,因此返回正确的高度将允许您根据需要调整单元格的大小。