旋转时,从 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:toView
将self.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:
的经验,我在旋转后手动移动弹出框。这行得通。可能由于呈现的视图控制器在表单中,导致布局系统混乱。
有趣的是,我尝试切换到 willAnimateRotationToInterfaceOrientation
和 convertRect: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 在旋转后停止工作