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

【字号: 日期:2024-04-13浏览:51作者:雯心
(adsbygoogle = window.adsbygoogle || []).push({}); 如何解决UITableView布局在推送和返回时弄乱了(iOS 8,Xcode beta 5,Swift)?

此行为的问题是,当您按顺序时,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];}解决方法

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 detailslet link: Link = self.linksArray.objectAtIndex(indexPath.row) as Linkcell.titleLabel.text = link.titlecell.scoreLabel.text = '(link.score)'cell.detailsLabel.text = link.stringCreatedTimeIntervalSinceNow() + ' ago by ' + link.author + ' to /r/' + link.subredditreturn cell } return nil}

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

谢谢你的帮助!

相关文章: