旋转时,从 UITableViewCell 显示的 UIPopoverController 放置不正确

Posted

技术标签:

【中文标题】旋转时,从 UITableViewCell 显示的 UIPopoverController 放置不正确【英文标题】:When rotating, UIPopoverController displayed from UITableViewCell is incorrectly placed 【发布时间】:2013-11-19 20:33:42 【问题描述】:

我有一个从 UITableView 中的 UITableViewCell 显示的弹出框,这是模式对话框中的唯一视图。这在横向和纵向都可以正常工作:

UIViewController *content = [[SetTimeClockTimeViewController alloc] init];
popover = [[UIPopoverController alloc] initWithContentViewController:content];
[popover setDelegate:self];
UITableViewCell *cell = [dataTable cellForRowAtIndexPath:[dataTable indexPathForSelectedRow]];
[popover presentPopoverFromRect:cell.frame inView:cell.superview permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

但是,当屏幕旋转而弹出框保持向上时,弹出框会从单元格移开(如果我旋转回来,它会移动到正确的位置)。如果任一方向是起始方向,就会发生这种情况。我尝试实现popoverController:willRepositionPopoverToRect:inView:,但我放入的任何内容似乎都没有解决问题。例如:

- (void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView *__autoreleasing *)view 
    // TODO: Popover moves wrong when rotating
    UITableViewCell *cell = [dataTable cellForRowAtIndexPath:[dataTable indexPathForSelectedRow]];
    *rect = cell.frame;
    *view = cell.superview;

我尝试在旋转时将桌子告诉reloadData,使用convertRect:toViewself.view 作为视图,并在didRotateFromInterfaceOrientation: 中调用presentPopoverFromRect:inView:permittedArrowDirections:animated,但这些似乎都没有解决不正确的放置.

如何确保在旋转后从新的单元格位置显示弹出框?

纵向显示的弹出框示例(箭头指向“时间”行):

横向定位后(箭头应指向“时间”行):

【问题讨论】:

您是否尝试将单元格框架转换为主视图框架? @danypata 你的意思是convertRect:toView:?还是CGAffineTransformTranslate?我试过前者,虽然我可能做错了。我没有尝试过后者 - 我不确定(如果?)它会如何应用。 第一个是正确的。但是您应该在willAnimateToInterfaceOrientation 中进行操作。 @danypata 我在willAnimate... 中将其更改为[cell.superview convertRect:cell.frame toView:self.view] 并修复了它。您想将其发布为答案以便我接受吗? 我会的。但我看到你已经接受了另一个答案:) 【参考方案1】:

从视图显示的弹出框与视图不保持关系,并且在旋转后可能会经常转移到不正确的位置。这与从条形按钮项目显示不同,其中弹出框将在布局后移动。您应该将弹出框移动到视图控制器 viewDidLayoutSubviews 中的正确位置。

确保使用convertRect:toView:convertRect:fromView: 将返回的矩形转换为视图的正确坐标系。

【讨论】:

这就是我尝试使用popoverController:willRepositionPopoverToRect:inView 所做的事情——我的理解是通过手动将rect 设置为新框架,我会在新方向上获得正确的位置。我误解了我应该在那里做什么吗? 您应该将 rect 转换为 superview 坐标系。试试convertRect:toView: superview 是指持有 TableView 的视图吗?还是表视图? CGRect 不是作为框架返回的,应该是相对于 superview 的,那不是 TableViewCell 的 TableView 吗? 嗯,你是对的。我必须承认,我没有使用 popoverController:willRepositionPopoverToRect:inView: 的经验,我在旋转后手动移动弹出框。这行得通。可能由于呈现的视图控制器在表单中,导致布局系统混乱。 有趣的是,我尝试切换到 willAnimateRotationToInterfaceOrientationconvertRect:toView:(就像你和 danypata 上面建议的那样),但如果我在 popoverController:willRepositionPopoverToRect:inView: 中做同样的事情,它不会。一定是我在那里想念的东西。【参考方案2】:

您应该使用convertRect:toView 将矩形转换为超级视图。最重要的是在willAnimateToInterfaceOrientation方法中调用它。

【讨论】:

【参考方案3】:

我见过的最好的解决方案是使用单元格(或者在我的情况下是 UIButton)作为 sourceView 和单元格的边界作为 sourceRect。 即

[popover 
   presentPopoverFromRect:cell.bounds //vs cell.frame
   inView:cell                        //vs cell.superView
   permittedArrowDirections:UIPopoverArrowDirectionAny 
   animated:YES];

【讨论】:

以上是关于旋转时,从 UITableViewCell 显示的 UIPopoverController 放置不正确的主要内容,如果未能解决你的问题,请参考以下文章

UITableViewCell AccessoryView 未正确显示

在Swift中旋转设备时iOS 8 uitableviewcell高度发生变化

在旋转时更改 UITableViewCell 中的文本对齐方式

自定义 UITableViewCell 中的 UIButton 在旋转后停止工作

UITableViewCell 内的 UIImageView 旋转动画

在 iPad 上旋转 UITableView 后,UITableViewCell 附件未正确定位