ios - UITableViewCell 自动高度不正确,直到我滚动

标签 ios iphone swift uitableview autolayout

我正在尝试在我的 UIViewController 子类中的 UITableView 中显示新闻文章(我需要其中的一些其他 View ,所以这就是为什么我不使用 UITableViewController)

单元格应该是全宽和自动高度。

问题是可见单元格在第一次加载时没有正确的高度,因此它们根本无法正确显示,只有在我向下滚动后它们的大小才正确(其他已经正确大小的单元格是)并备份。

我尝试添加 setNeedsUpdateConstraintsupdateConstraintslayoutSubviewslayoutIfNeeded 和其他类似方法的各种组合UITableView 和单元格,但它根本没有任何效果。

我非常感谢任何帮助,因为我很长时间以来一直在尝试解决这个问题,但从未找到解决方案。

我的设置

我有 MyStoryCell 类型的自定义单元格,它存储在 .xib 文件中:

MyStoryCell.xib in Interface Builder

它的类如下所示:

class MyStoryCell: UITableViewCell
{
    // MARK: - Properties
    @IBOutlet weak var badgeView: UIImageView!
    @IBOutlet weak var thumbnailView: UIImageView!

    @IBOutlet weak var dateLabel: UILabel!
    @IBOutlet weak var taglineLabel: UILabel!
    @IBOutlet weak var titleLabel: UILabel!

    // MARK: - Methods
    func setTaglineText(text: String)
    {
        ....
    }

    func setTitleText(text: String)
    {
        ...
    }

    // MARK: - Overrides
    override func awakeFromNib() {
        super.awakeFromNib()
    }

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

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        if let image = self.thumbnailView?.image
        {
            // Using PureLayout
            self.thumbnailView?.autoSetDimension(.Height, toSize: (self.contentView.frame.width * image.size.height / image.size.width))
        }
    }
}

View Controller (函数fetchTableData)从网络中提取大量文章,将它们存储在一个数组(currentStories)中,然后使用以下方法将它们全部添加到UITableView:

self.table.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)

在 View Controller 的 viewDidLoad 覆盖中,我有:

override func viewDidLoad()
{
    super.viewDidLoad()

    // Setting up table view
    table.delegate = self
    table.dataSource = self
    table.registerNib(UINib(nibName: "MyStoryCell", bundle: nil), forCellReuseIdentifier: "StoryCell")

    // Setting cells to automatic height
    table.estimatedRowHeight = 300
    table.rowHeight = UITableViewAutomaticDimension

    // ... some more code

    fetchTableData()
}

我的表格 View 功能是:

func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    return currentStories.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    var cell: MyStoryCell? = tableView.dequeueReusableCellWithIdentifier("StoryCell", forIndexPath: indexPath) as? MyStoryCell
    if cell == nil
    {
        tableView.registerNib(UINib(nibName: "MyStoryCell", bundle: nil), forCellReuseIdentifier: "StoryCell")
        cell = tableView.dequeueReusableCellWithIdentifier("StoryCell", forIndexPath: indexPath) as? MyStoryCell
    }

    if currentStories.count >= indexPath.row + 1
    {
        let currentStory: Story = currentStories[indexPath.row]

        dispatch_async(get_user_queue()) {
            let badgeImage = codeToFetchBadgeImage

            dispatch_async(dispatch_get_main_queue(), {
                cell?.badgeView.image = badgeImage
            })

            let thumbnailImage = codeToFetchThumbnailImage

            dispatch_async(dispatch_get_main_queue(), {
                cell?.thumbnailView.image = thumbnailImage
            })
        }

        // Set labels
        cell?.dateLabel.text = currentStory.storyDate
        cell?.setTitleText(currentStory.storyTitle) // Attributed string
        cell?.setTaglineText(currentStory.storyTagline) // Attributed string
    }

    return cell!
}

fetchTableData 实现:

func fetchTableData()
{
    /* removed unnecessary code for displaying loading indicator etc. */
    stories = [Story]()
    currentStories = [Story]()

    table.reloadData()

    // Go through all the feeds
    for feed in 0...rss_urls.count-1
    {
        // Set url of the RSS feed
        var rss_url: NSURL = rss_urls[feed]

        // Try to download the RSS feed
        if var rss_data: NSData = NSData(contentsOfURL: rss_url)
        {
            // Initialize the XML Parser and set its delegate to self
            parser = NSXMLParser(data: rss_data)
            parser.delegate = self

            // Start parsing XML
            parser.parse()
        }
        else
        {
            alert_rss_error_show()
        }
    }

    // Sort by ID
    stories.sort{ $0.storyId.toInt() > $1.storyId.toInt() }
}

class DataManager {
    func requestData(offset:Int, size:Int, array:[Story], listener:([Story]) -> ()) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
            //generate items
            var arr:[Story] = []
            var limit = offset + size
            if limit >= stories.count
            {
                limit = stories.count - 1
            }
            if offset > limit
            {
                allLoaded = true
                return
            }
            // For each story
            for i in offset...limit {

                // Story for current index
                var currentStory: Story = stories[i]

                if let badgeUrl = currentStory.storyBadgeUrl
                {
                    if !badgeUrl.isEmpty
                    {
                        if let currentBadge = badgeCache[badgeUrl] { }
                        else
                        {
                            if let badgeData = NSData(contentsOfURL: NSURL(string: badgeUrl)!)
                            {
                                var image = UIImage(data: badgeData)
                                badgeCache[badgeUrl] = image
                            }
                        }
                    }
                }

                // If story has a thumbnail stored in cache, skip the next step
                if let currentThumbnail = thumbnailCache[currentStory.storyLink] { }
                else if !currentStory.storyThumbLink.isEmpty
                {
                    if let thumbnailData = NSData(contentsOfURL: NSURL(string: currentStory.storyThumbLink)!)
                    {
                        var image = UIImage(data: thumbnailData)
                        thumbnailCache[currentStory.storyLink] = image
                    }
                }
                arr.append(currentStory)
            }

            //call listener in main thread
            dispatch_async(dispatch_get_main_queue()) {
                listener(arr)
            }
        }
    }

    loadSegment(0, size: PageSize)
}

func loadSegment(offset:Int, size:Int) {
    if (!self.isLoading) {
        self.isLoading = true

        let manager = DataManager()
        manager.requestData(offset, size: size, array: currentStories,
            listener: {(items:[Story]) -> () in
                for item in items {
                    var row = currentStories.count
                    var indexPath = NSIndexPath(forRow:row,inSection:0)
                    currentStories.append(item)
                    self.table.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
                }
                self.isLoading = false
            }
        )
    }
}

最佳答案

将此函数从 UITableViewDelegate 协议(protocol)添加到您的 TableView 函数中:

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

您的表格 View 询问您每个单元格的高度是多少。如果您不回复,它将使用 NIB 文件中的内容。

有关这些功能的更多信息,您可以在此处查看 Apple 文档:

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/#//apple_ref/occ/intfm/UITableViewDelegate/tableView:heightForRowAtIndexPath :

关于ios - UITableViewCell 自动高度不正确,直到我滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34455648/

相关文章:

ios - Swift 不支持 SDK 'iPhoneSimulator9.3.sdk'?

iOS - tableView reloadData 非常奇怪的问题

iOS:LocationManager 更新,什么时候停止更新?

iphone - 在 GCD block 中绘制图像时卡顿

ios - 试图在我的 UITableView 中返回数组的每个索引

ios - 使用未解析的标识符 'Realm'

iphone - 自定义 UITableViewCell 不会立即更新其 subview ,为什么?

swift - 用于 Facebook 身份验证和数据库的 Firebase

ios - 从 UITableView 取消注册 UINib

ios - 导航栏根据用户滚动方向隐藏和显示 IOS SWIFT