UITableViewCell在第一次加载时无法正确呈现

时间:2015-05-28 16:43:57

标签: ios objective-c uitableview ios8 autolayout

一些背景: 我正在使用UITableView构建一个应用程序,该应用程序显示用户可以使用UITableViewCell的子类进行投票的民意调查列表。 UITableViewCell子类有5个IBOutlet UILabel:一个问题标签,然后是4个选择标签。民意调查可能有2,3或4种选择,因此我可能没有显示第3和/或第4选择标签。每个标签都有" Lines"设置为0,这样如果文本太长,它们就会换行。

根据本教程,我设置了布局约束以确保单元格具有动态高度:http://www.raywenderlich.com/87975/dynamic-table-view-cell-height-ios-8-swift

问题标签的内容拥抱优先级为250,而所有选择标签均为251。 问题标签的内容压缩阻力优先级为751,而所有选择标签均为752。

当我第一次加载应用时,第一个民意调查的问题有太多的垂直填充,第一个选择是用省略号截止的。 但是,当我向下滚动然后向上滚动时,它会自行修复:问题标签拥抱它的内容,第一个选项显示其所有内容。

这是我制作的GIF,显示了问题(专注于顶级单元格):

scrolling the tableView

这是Interface Builder的截图(如果它有帮助):

interface builder screenshot

以下是我用来填充Cell标签的代码:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    PollTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kPollCellReuseId];
    Poll *poll = [self.polls objectAtIndex: indexPath.row];

    cell.questionLabel.text = poll.question;
    cell.choiceLabel1.text = [(Choice *)[poll.choices objectAtIndex:0] text];
    cell.choiceLabel2.text = [(Choice *)[poll.choices objectAtIndex:1] text];

    BOOL hasChoice3 = poll.choices.count > 2;
    cell.choiceLabel3.text = hasChoice3 ? [(Choice *)[poll.choices objectAtIndex:2] text] : @"";
    cell.choiceLabel3TopConstraint.constant = hasChoice3 ? 8 : 0;

    BOOL hasChoice4 = poll.choices.count > 3;
    cell.choiceLabel4.text = hasChoice4 ? [(Choice *)[poll.choices objectAtIndex:3] text] : @"";
    cell.choiceLabel4TopConstraint.constant = hasChoice4 ? 8 : 0;

    return cell;
}

为什么第一次尝试时渲染不正确?

4 个答案:

答案 0 :(得分:6)

对我来说,在您的表reloadData修复问题上增加了延迟。

我用过

  

self.tableView.rowHeight = UITableViewAutomaticDimension;

     

self.tableView.estimatedRowHeight = 500.0;

     

cell.layoutIfNeeded()返回单元格

之前

但是为我增加了重装tableView的延迟。该问题仅在iPad上发生。

DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                self.tableView.reloadData()      
          }

另一种替代解决方案对我有用,

 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {

                //Reload with delay
                self.tableView.reloadData()

                //Again reload with delay
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                    self.tableView.reloadData()
                }
            }

答案 1 :(得分:0)

实施

-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath

并返回任何例如100并且不要忘记设置

self.tableView.rowHeight = UITableViewAutomaticDimension

viewDidLoad

答案 2 :(得分:0)

根据@ sikhapol的评论: 在-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

中返回单元格之前执行//emit in jquery $(document).trigger('customEvent', data); app.run(['$rootScope', function ($rootScope) { //capture jQuery events and re-broadcast them as angular events //events to capture var events = [ 'customEvent' ]; //To Use: $scope.$on('eventName', function(ngEvent, jqEvent, data) $(document).on(events.join(' '), function(e) { $rootScope.$broadcast.apply($rootScope, [e.type].concat(Array.prototype.slice.call(arguments, 0))); }); }); //listen for it in directive scope.$on('customEvent', function(){ scope.$apply(function(){ //do stuff here and angular will be aware of it }); });

修复了问题

答案 3 :(得分:0)

我也遇到了同样的问题,并使用以下技巧解决了该问题:

    extension UITableView {
    func reloadDataWithAutoSizingCellWorkAround() {
        self.reloadData()
        self.setNeedsLayout()
        self.layoutIfNeeded()
        self.reloadData()
    }
}
相关问题