当前位置: 首页 > 面试题库 >

UITableView布局在推送和返回时弄乱了。(iOS 8,Xcode beta 5,Swift)

刘浩思
2023-03-14
问题内容

tldr; 自动约束似乎在推送选择时中断,并返回查看自定义单元格

编辑 :我提供了一个github示例项目,展示了发生的错误 https://github.com/Matthew-
Kempson/TableViewExample.git

我正在创建一个需要自定义UITableCell的标题标签的应用程序,以允许根据帖子标题的长度来更改行。单元格可以正确加载到视图中,但是如果我按某个单元格以推送方式将帖子加载到包含WKWebView的视图中,如屏幕截图所示,单元格会立即移动到错误的位置。通过UINavigationController的后退按钮将视图加载回视图时,也可以查看此视图​​。

在这个特定示例中,我按下了最后一个单元格,标题为“我在巴黎拍了照片的两个哥们”,然后正确加载了所有内容。然后,如下面的屏幕快照所示,在加载第二个视图的背景下,所有单元都出于未知原因向上移动。然后,当我重新加载视图时,您可以看到屏幕略微向上移动,而我实际上无法滚动到比显示的更低的水平。当视图加载回去时,这似乎是随机的,与其他测试一样,底部单元格下方有空白不会消失。

我还提供了一张包含单元格约束的图片。

图像(显然,在这个问题上提供图像,我需要更高的声誉,因此它们在imgur相册中):http
://imgur.com/a/gY87E

我的代码:

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

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
}

表格视图中的代码

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
}

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

谢谢你的帮助!


问题答案:

此行为的问题是,当您按顺序时,tableView将调用estimatedHeightForRowAtIndexPath可见单元格并将单元格高度重置为默认值。这发生在viewWillDisappear通话后。如果返回TableView,则所有可见的单元都被弄乱了。

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

- (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文件中:

@property NSMutableDictionary *estimatedRowHeightCache;

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

#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];
}


 类似资料:
  • 问题内容: JPanel初始化 调用方法 在我的框架看起来像这样之前,http://i.imgur.com/XQlQeul.png 然后看起来像这样,http://i.imgur.com/RnVuUzt.png 我在想我的方法有错误,但是我似乎无法解决问题。有人知道发生了什么吗?我想要的结果将是第一张图片,但已被绘制。 问题答案: 您在执行任何自定义绘画之前未先致电就中断了绘画链 如果是共享资源,

  • 向下和向上滚动后滚动回收器视图时遇到问题。这个想法是改变元素的颜色,但是当我向下滚动时,一切都很好,当滚动向上时——不应该着色的元素正在改变颜色。 这是我的适配器:

  • 我使用autolayout在故事板中创建了一个UIViewController,它有一个嵌入式UITableView。由于某些原因,表视图部分上方存在空白。我的期望是tableview将所有可用空间分割为单元格,并使单元格从顶部开始。 当使用自动布局和大小类时,是什么导致表视图在第一部分上方添加空白?

  • 问题内容: 我使用Python编写代码,我非常喜欢Notepad 。但是,当我使用制表符进行缩进时,在Notepad 中看起来很晚,但是当我运行该程序时,出现了缩进错误,并且当我在Emacs中检查代码时,我发现Notepad ++实际上增加了比制表符更多的空格。它显示在屏幕上。怎么了? 问题答案: 没有通用的制表符大小,因此我始终确保用空格替换制表符(因此您知道所看到的就是在其他任何地方都可以看到

  • 问题内容: 我有这个非常奇怪的问题。我有一个包含一些德语字母的网站,当它只是不带php的html时,当我将符号更改为UTF-8时,符号将显示为带有编码的属性,它们不会显示,而不是Ö。当我将html放入php并在Wamp上使用Zenset studio以charset = iso-8859-1编码启动时,得到�而不是Ö(我想补充一下,这个Ö是单选按钮的值) 。当它在一个 标签以正确显示。您能告诉

  • 问题内容: 我正在尝试在Eclipse中输入一对尖括号,例如“ <>”。但是,它显示为单引号和一个点,例如“’”。我尝试了几次,发现尖括号实际上位于反斜杠的位置。 为什么会这样呢?我该如何改回来? 提前致谢。 习 问题答案: 我认为这与Windows的令人讨厌的功能有关-很长时间以来,我在不同的程序(不仅仅是Eclipse)中都有类似的东西。 如果您使用的是非英语版本的Windows,则可能安装了