2013-10-25 18 views
5

我有一个方法我请计算在自定义UITableViewCell子类,这是在一个UIPopoverController我有一堆标签的大小。当用户旋转设备时,我需要重新计算尺寸,然后重新绘制表格以使用新的尺寸。我尝试检测轮换的每种方法都是折旧的,不会被调用,或者在正确的时间没有被调用。是否有一种方法会在设备旋转时自动调用,我可以重新计算尺寸?重新计算子视图的尺寸在IOS 7


编辑:我已经试过,为什么它不工作:

  • shouldAutorotate - 不会被调用 - 显然贬值。
  • layoutSubviews - 被调用,但如果我尝试[self.tableView reloadData]在这里,我就会陷入无限循环
  • NSNotificationCenter观察员UIDeviceOrientationDidChangeNotification - 天黑之前我控制器知道它是新的维度调用,所以我不能在这里重新计算我的尺寸
  • [self.tableView setNeedsDisplay] in layoutSubviews - 不提示重新绘制表格。
  • didRotateFromInterfaceOrientation - 不会被调用 - 显然贬值。

编辑2:我想要做

我试图模仿“行和柱”样式表,排队的标签,以模仿更多细节列。当我重新计算大小时,我遍历表中的所有行,然后遍历该行中的每个“列”。我得到每列的宽度,并跟踪每列中所有行的最大宽度。然后我操作宽度和字体大小之间的间距来获得它,这样,如果任何行在每列中都有最宽的标签,它仍然适合在屏幕上。

+0

layoutSubviews? – ChrisH

+0

介意分享您尝试过哪些方法? shouldAutorotate已弃用。 –

+0

@ChrisH:我可以把它放在那里,但如果我尝试'[self.tableView reloadTable];'那里,我陷入了一个无限循环。 – GeneralMike

回答

1

你不想依赖于实际的渲染UILabels你的细胞内来计算你的“列”的宽度。请改为:

  1. 执行名为calculateColumnWidthsForInterfaceOrientation:的方法,其方法为UIInterfaceOrientation。在该方法中,使用UIInterfaceOrientationIsLandscape(orientation)检查请求的方向是纵向还是横向。然后,根据方向浏览要在标签中显示的数据,并使用NSString的sizeWithAttributes:方法(或其衍生词之一)找到最宽的列宽。将这些值缓存在数组或其他东西中。
  2. 添加像setColumnWidths:一个方法,是以期望的列宽的定制表格视图细胞。
  3. 在你tableView:cellForRowAtIndexPath:方法,检索缓存列的宽度和使用setColumnWidths:方法来设置它的细胞。
  4. 在您的单元格中,使用刚刚设置的列宽布局标签。
  5. 在您的视图控制器中,执行didRotateFromInterfaceOrientation:。在里面,以给定的方向拨打calculateColumnWidthsForInterfaceOrientation:,然后拨打电话[self.tableView reloadData]
  6. 最后,在viewDidLoad,调用[self calculateColumnWidthsForInterfaceOrientation:self.interfaceOrientation]第一旋转前做数据的初始设置。

这应该做的伎俩。

更新:细胞的总宽度应等于您表视图的总宽度。这可以通过自动布局或其他方式进行管理。这个大小将反映在单元格的大小上。

更新2: 既然我们是在谈论一个酥料饼,你也许可以简单地驳回酥料饼在willRotateToInterfaceOrientation:duration:,然后用你的新的期望尺寸再次显示它的旋转在didRotateFromInterfaceOrientation:完成后。

+0

大部分这是我已经做的。 'sizeWithFont:'已被折旧,这就是为什么我需要渲染'UILabels'来计算我的列宽。我如何根据方向计算单元格的总宽度(请参阅我对RahulVyas对我的OP的评论的回复)。另外,'didRotateFromInterfaceOrientation'是另一个已被折旧的旋转方法,所以我回到了我的原始问题“我如何检测旋转”。我将'didRotateFromInterfaceOrientation'添加到我的OP中不起作用的列表中。 – GeneralMike

+0

你对'sizeWithFont:'方法是正确的:我已经将它改为'sizeWithAttributes:'。但是,我不认为'didRotateFromInterfaceOrientation:'已被弃用。我无法在文档或标题中找到任何内容。我已经为我的答案添加了另一个更新。 –

+0

我尝试了'didRotateFromInterfaceOrientation:'并在其上放置了一个塞子 - 它没有被调用(至少在模拟器上 - 所以也许这是一个模拟器 - 只有错误?)。 – GeneralMike

1

在layoutSubviews尝试重新计算子视图一个细胞

例如CustomCell.m

- (void)layoutSubviews 
{ 

UIViewController *viewController = (id)[(AppDelegate *)[UIApplication sharedApplication].delegate window].rootViewController; 

if (UIInterfaceOrientationIsPortrait(viewController.interfaceOrientation)) 
    self.backgroundColor = [UIColor redColor]; 
else 
    self.backgroundColor = [UIColor greenColor]; 

}

+0

嗯,我不认为这是什么接近我在找什么。谢谢你尝试。 – GeneralMike

0

您在使用自动布局来定义您的tableView和细胞考虑?使用适当的限制与updateConstraints一起更新设备旋转时的单元布局应该有所帮助。通过这种方法,您可以设置每个“列”标签的preferredMaxLayoutWidth,并定义约束条件以处理适当的水平填充,而不考虑方向。

此外,如果使用iOS 7,则应执行popoverController:willRepositionPopoverToRect:inView:来处理循环中的子视图布局,除非您从条形按钮项呈现弹出式窗口。我建议检讨UIPopoverController Class Reference