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

时间:2015-12-24 16:40:36

标签: ios iphone swift uitableview autolayout

我试图在UITableView子类UIViewController中显示新闻文章(我需要其他一些观点,这就是为什么我没有使用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))
        }
    }
}

视图控制器(函数fetchTableData)从Web中提取大量文章,将它们存储在一个数组(currentStories)中,然后使用以下内容将它们全部添加到UITableView中:

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

在视图控制器的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()
}

我的表格视图功能是:

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
            }
        )
    }
}

1 个答案:

答案 0 :(得分:0)

将此函数从UITableViewDelegate协议添加到表视图函数:

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

您的表格视图会询问每个单元格您想要的高度。如果您不回复它将使用NIB文件中的那个。

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

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