我正在尝试在我的 UIViewController
子类中的 UITableView
中显示新闻文章(我需要其中的一些其他 View ,所以这就是为什么我不使用 UITableViewController
)
单元格应该是全宽和自动高度。
问题是可见单元格在第一次加载时没有正确的高度,因此它们根本无法正确显示,只有在我向下滚动后它们的大小才正确(其他已经正确大小的单元格是)并备份。
我尝试添加 setNeedsUpdateConstraints
、updateConstraints
、layoutSubviews
、layoutIfNeeded
和其他类似方法的各种组合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 文档:
关于ios - UITableViewCell 自动高度不正确,直到我滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34455648/