UITableView布局搞乱推送segue和返回

UITableView布局搞乱推送segue和返回

本文介绍了UITableView布局搞乱推送segue和返回。 (iOS 8,Xcode beta 5,Swift)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

tldr;自动约束似乎在推送segue上中断并返回查看自定义单元格

编辑:我提供了一个github示例项目这显示了发生的错误

Edit: I have provided a github example project that shows off the error that occurshttps://github.com/Matthew-Kempson/TableViewExample.git

我正在创建一个应用程序,它需要自定义UITableCell的标题标签,以允许根据帖子标题的长度变化的行。单元格正确加载到视图中但是如果我按下单元格以将推送信号加载到包含WKWebView的视图中,您可以看到,如屏幕截图所示,单元格会立即移动到不正确的位置。当通过UINavigationController的后退按钮加载视图时也会看到这一点。

I am creating an app which requires the title label of the custom UITableCell to allow for varying lines dependent on the length of the post title. The cells load into the view correctly but if I press on a cell to load the post in a push segue to a view containing a WKWebView you can see, as shown in the screen shot, the cells move immediately to incorrect positions. This is also viewed when loading the view back through the back button of the UINavigationController.

在这个特定的例子中,我按下最后一个单元格,标题为两个好友我在巴黎拍了一张照片,所有东西都装得正确。然后,如下一个屏幕截图所示,在加载第二个视图的背景中,单元格都会因未知原因向上移动。然后,当我加载视图时,您可以看到屏幕稍微向上移动,我实际上无法滚动任何低于显示的值。这看起来是随机的,就像其他测试一样,当视图加载回来时,底部单元格下方的空白区域不会消失。

In this particular example I pressed on the very end cell, with the title "Two buddies I took a picture of in Paris", and everything is loaded correctly. Then as shown in the next screenshot the cells all move upwards for unknown reasons in the background of loading the second view. Then when I load the view back you can see the screen has shifted upwards slightly and I cannot actually scroll any lower than is shown. This appears to be random as with other tests when the view loads back there is white space under the bottom cell that does not disappear.

我还包含一张包含细胞所具有的约束。

I have also included a picture containing the constraints that the cells has.

图像(我需要更多的声誉才能在这个问题中提供图像,所以他们就在这张imgur专辑中):

Images (I need more reputation to provide images in this question apparently so they are in this imgur album): http://imgur.com/a/gY87E

我的代码:

自定义单元格中允许单元格在旋转时正确调整视图大小的方法:

Method in custom cell to allow the cell to resize the view correctly when rotating:

override func layoutSubviews() {
    super.layoutSubviews()

    self.contentView.layoutIfNeeded()

    // Update the label constaints
    self.titleLabel.preferredMaxLayoutWidth = self.titleLabel.frame.width
    self.detailsLabel.preferredMaxLayoutWidth = self.detailsLabel.frame.width
}

tableview中的代码

Code in tableview

override func viewDidLoad() {
    super.viewDidLoad()

    // Create and register the custom cell
    self.tableView.estimatedRowHeight = 56
    self.tableView.rowHeight = UITableViewAutomaticDimension
}

创建单元格的代码

    override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    if let cell = tableView.dequeueReusableCellWithIdentifier("LinkCell", forIndexPath: indexPath) as? LinkTableViewCell {

        // Retrieve the post and set details
        let link: Link = self.linksArray.objectAtIndex(indexPath.row) as Link

        cell.titleLabel.text = link.title
        cell.scoreLabel.text = "\(link.score)"
        cell.detailsLabel.text = link.stringCreatedTimeIntervalSinceNow() + " ago by " + link.author + " to /r/" + link.subreddit

        return cell
    }

    return nil
}

如果您需要更多代码或信息,请询问我将提供必要的信息

感谢您的帮助!

推荐答案

这种行为的问题是当你推动一个segue时 tableView 将为可见单元格调用 estimatedHeightForRowAtIndexPath ,并将单元格高度重置为默认值。这发生在 viewWillDisappear 调用之后。如果你回到TableView,所有可见的单元格都搞砸了..

The problem of this behavior is when you push a segue the tableView will call the estimatedHeightForRowAtIndexPath for the visible cells and reset the cell height to a default value. This happens after the viewWillDisappear call. If you come back to TableView all the visible cells are messed up..

我用 estimatedCellHeightCache 解决了这个问题。我只是将此代码剪切添加到 cellForRowAtIndexPath 方法:

I solved this problem with a estimatedCellHeightCache. I simply add this code snipped to the cellForRowAtIndexPath method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
    // put estimated cell height in cache if needed
    if (![self isEstimatedRowHeightInCache:indexPath]) {
        CGSize cellSize = [cell systemLayoutSizeFittingSize:CGSizeMake(self.view.frame.size.width, 0) withHorizontalFittingPriority:1000.0 verticalFittingPriority:50.0];
        [self putEstimatedCellHeightToCache:indexPath height:cellSize.height];
    }
    ...
}

现在你需要实现 estimatedHeightForRowAtIndexPath 如下:

-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [self getEstimatedCellHeightFromCache:indexPath defaultHeight:41.5];
}

配置缓存

将此属性添加到.h文件中:

Add this property to your .h file:

@property NSMutableDictionary *estimatedRowHeightCache;

实施放置/获取/重置的方法..缓存:

Implement methods to put/get/reset.. the cache:

#pragma mark - estimated height cache methods

// put height to cache
- (void) putEstimatedCellHeightToCache:(NSIndexPath *) indexPath height:(CGFloat) height {
    [self initEstimatedRowHeightCacheIfNeeded];
    [self.estimatedRowHeightCache setValue:[[NSNumber alloc] initWithFloat:height] forKey:[NSString stringWithFormat:@"%d", indexPath.row]];
}

// get height from cache
- (CGFloat) getEstimatedCellHeightFromCache:(NSIndexPath *) indexPath defaultHeight:(CGFloat) defaultHeight {
    [self initEstimatedRowHeightCacheIfNeeded];
    NSNumber *estimatedHeight = [self.estimatedRowHeightCache valueForKey:[NSString stringWithFormat:@"%d", indexPath.row]];
    if (estimatedHeight != nil) {
        //NSLog(@"cached: %f", [estimatedHeight floatValue]);
        return [estimatedHeight floatValue];
    }
    //NSLog(@"not cached: %f", defaultHeight);
    return defaultHeight;
}

// check if height is on cache
- (BOOL) isEstimatedRowHeightInCache:(NSIndexPath *) indexPath {
    if ([self getEstimatedCellHeightFromCache:indexPath defaultHeight:0] > 0) {
        return YES;
    }
    return NO;
}

// init cache
-(void) initEstimatedRowHeightCacheIfNeeded {
    if (self.estimatedRowHeightCache == nil) {
        self.estimatedRowHeightCache = [[NSMutableDictionary alloc] init];
    }
}

// custom [self.tableView reloadData]
-(void) tableViewReloadData {
    // clear cache on reload
    self.estimatedRowHeightCache = [[NSMutableDictionary alloc] init];
    [self.tableView reloadData];
}

这篇关于UITableView布局搞乱推送segue和返回。 (iOS 8,Xcode beta 5,Swift)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 14:29