滚动或拉动刷新后,UITableViewAutomaticDimension单元格会调整大小 [英] UITableViewAutomaticDimension Cells resize after scroll or pull to refresh

查看:150
本文介绍了滚动或拉动刷新后,UITableViewAutomaticDimension单元格会调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我添加了一个表格视图,并且在单元格中显示图像.我还添加了以下代码:

tableView.estimatedRowHeight = 175
tableView.rowHeight = UITableViewAutomaticDimension

以便使单元格根据图像调整大小.

但是当我启动我的应用程序时,我得到了这个信息:

直到我开始滚动时图像才加载...如果我向下滚动一半页面然后返回顶部,则显示此信息(正确):

如果我删除了like按钮,并且仅在一个单元格中放置了图片,那么当我启动我的应用程序时,如果我等了三秒钟却没有碰到任何东西,那么这些单元格就会自动调整大小.

有什么想法吗?我已经在Google上进行了研究,并尝试了针对旧版本Xcode的奇怪解决方案,但似乎没有任何效果!

这是我来自TableViewController的其余代码:

extension TimelineViewController: UITableViewDataSource {

    func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 46
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return timelineComponent.content.count
    }

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerCell = tableView.dequeueReusableCellWithIdentifier("PostHeader") as! PostHeaderTableViewCell

        let post = self.timelineComponent.content[section]
        headerCell.post = post


        return headerCell
    }


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

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("PostCell") as! PostTableViewCell

        //cell.postImageView?.image = UIImage(named: "Background.png")

        let post = timelineComponent.content[indexPath.section]
        post.downloadImage()
        post.fetchLikes()
        cell.post = post

        cell.layoutIfNeeded()
        return cell
    }
}

extension TimelineViewController: UITableViewDelegate {
    func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        timelineComponent.targetWillDisplayEntry(indexPath.section)
    }


Download image code:

func downloadImage() {
    // 1
    image.value = Post.imageCache[self.imageFile!.name]

    if image is not downloaded yet, get it
        if (image.value == nil) {

            imageFile?.getDataInBackgroundWithBlock { (data: NSData?, error: NSError?) -> Void in
                if let data = data {
                    let image = UIImage(data: data, scale: 2.0)!
                    self.image.value = image
                    // 2
                    Post.imageCache[self.imageFile!.name] = image
                }
            }
        }
}

// MARK: PFSubclassing
extension Post: PFSubclassing {
    static func parseClassName() -> String {
        return "Post"
    }

    override class func initialize() {
        var onceToken : dispatch_once_t = 0;
        dispatch_once(&onceToken) {
            // inform Parse about this subclass
            self.registerSubclass()
            // 1
            Post.imageCache = NSCacheSwift<String, UIImage>()
        }
    }
}


And here is my TableViewCell:


var post: Post? {
    didSet {
        postDisposable?.dispose()
        likeDisposable?.dispose()

        if let oldValue = oldValue where oldValue != post {

            oldValue.image.value = nil

        }

        if let post = post {

            postDisposable = post.image
            .bindTo(postImageView.bnd_image)

            likeDisposable = post.likes
            .observe { (value: [PFUser]?) -> () in

                if let value = value {
                    //self.likesLabel.text = self.stringFromUserList(value)
                    self.likeButton.selected = value.contains(PFUser.currentUser()!)
                    // self.likesIconImageView.hidden = (value.count == 0)
                } else {
                    //self.likesLabel.text = ""
                    self.likeButton.selected = false
                    //self.likesIconImageView.hidden = true

                }
            }
        }
    }
}

我们非常感谢您的帮助!

解决方案

我猜想,当图像最终加载后,您需要重新加载单元格,因为使用new图像时tableView需要重新计算单元格的高度(以及整个contentHeight).大小到来

post.downloadImage { _ in
    if tableView.indexPathForCell(cell) == indexPath {
        tableView.reloadRowsAtIndexPaths([indexPath], animation: .None)
    }
}

和downloadImage方法需要调用完成关闭.像这样的东西.

func downloadImage(completion: ((UIImage?) -> Void)?) {

    if let imageValue = Post.imageCache[self.imageFile!.name] {
        image.value = imageValue
        completion?(imageValue)
        return
    }

    //if image is not downloaded yet, get it
    imageFile?.getDataInBackgroundWithBlock { (data: NSData?, error: NSError?) -> Void in
        if let data = data {
            let image = UIImage(data: data, scale: 2.0)!
            self.image.value = image
            // 2
            Post.imageCache[self.imageFile!.name] = image

            completion?(image)
        } else {
            completion?(nil)
        }
    }
}

I have added a table view, and I am display image in the cells. I have also added this code:

tableView.estimatedRowHeight = 175
tableView.rowHeight = UITableViewAutomaticDimension

So that the cells resize depending on the image.

When I launch my app though, I get this :

And the images do not load untill I start scrolling...If I scroll down half the page then go back to the top, I get this(which is correct):

Also if I remove the like button and just has the image alone in a cell, when I launch my app if I wait 3 seconds without touching anything the cells resize on they're own..?!

Any ideas? I have researched on google and tried the odd solution for the older versions of Xcode, But nothing seems to work!

Here is the rest of my code from the TableViewController:

extension TimelineViewController: UITableViewDataSource {

    func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 46
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return timelineComponent.content.count
    }

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerCell = tableView.dequeueReusableCellWithIdentifier("PostHeader") as! PostHeaderTableViewCell

        let post = self.timelineComponent.content[section]
        headerCell.post = post


        return headerCell
    }


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

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("PostCell") as! PostTableViewCell

        //cell.postImageView?.image = UIImage(named: "Background.png")

        let post = timelineComponent.content[indexPath.section]
        post.downloadImage()
        post.fetchLikes()
        cell.post = post

        cell.layoutIfNeeded()
        return cell
    }
}

extension TimelineViewController: UITableViewDelegate {
    func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        timelineComponent.targetWillDisplayEntry(indexPath.section)
    }


Download image code:

func downloadImage() {
    // 1
    image.value = Post.imageCache[self.imageFile!.name]

    if image is not downloaded yet, get it
        if (image.value == nil) {

            imageFile?.getDataInBackgroundWithBlock { (data: NSData?, error: NSError?) -> Void in
                if let data = data {
                    let image = UIImage(data: data, scale: 2.0)!
                    self.image.value = image
                    // 2
                    Post.imageCache[self.imageFile!.name] = image
                }
            }
        }
}

// MARK: PFSubclassing
extension Post: PFSubclassing {
    static func parseClassName() -> String {
        return "Post"
    }

    override class func initialize() {
        var onceToken : dispatch_once_t = 0;
        dispatch_once(&onceToken) {
            // inform Parse about this subclass
            self.registerSubclass()
            // 1
            Post.imageCache = NSCacheSwift<String, UIImage>()
        }
    }
}


And here is my TableViewCell:


var post: Post? {
    didSet {
        postDisposable?.dispose()
        likeDisposable?.dispose()

        if let oldValue = oldValue where oldValue != post {

            oldValue.image.value = nil

        }

        if let post = post {

            postDisposable = post.image
            .bindTo(postImageView.bnd_image)

            likeDisposable = post.likes
            .observe { (value: [PFUser]?) -> () in

                if let value = value {
                    //self.likesLabel.text = self.stringFromUserList(value)
                    self.likeButton.selected = value.contains(PFUser.currentUser()!)
                    // self.likesIconImageView.hidden = (value.count == 0)
                } else {
                    //self.likesLabel.text = ""
                    self.likeButton.selected = false
                    //self.likesIconImageView.hidden = true

                }
            }
        }
    }
}

Any help is really appreciated!

解决方案

I guess, you need to reload the cell when the image is finally loaded, because tableView needs to recalculate cell height (and the whole contentHeight) when image with new size arrives

post.downloadImage { _ in
    if tableView.indexPathForCell(cell) == indexPath {
        tableView.reloadRowsAtIndexPaths([indexPath], animation: .None)
    }
}

and downloadImage method needs to call completion closure. Something like that.

func downloadImage(completion: ((UIImage?) -> Void)?) {

    if let imageValue = Post.imageCache[self.imageFile!.name] {
        image.value = imageValue
        completion?(imageValue)
        return
    }

    //if image is not downloaded yet, get it
    imageFile?.getDataInBackgroundWithBlock { (data: NSData?, error: NSError?) -> Void in
        if let data = data {
            let image = UIImage(data: data, scale: 2.0)!
            self.image.value = image
            // 2
            Post.imageCache[self.imageFile!.name] = image

            completion?(image)
        } else {
            completion?(nil)
        }
    }
}

这篇关于滚动或拉动刷新后,UITableViewAutomaticDimension单元格会调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆