转屏后UIPopoverController的重定位

UIPopoverController是iPad上特殊的UI控制器,主要用于以非全屏模态的方式显示界面上的临时信息,UIPopoverController类提供了两个方法用于显示:

//用于以任意view触发的显示定位情况        
– presentPopoverFromRect:inView:permittedArrowDirections:animated:

// 用于由toolbar item触发的显示定位情况
– presentPopoverFromBarButtonItem:permittedArrowDirections:animated:

同时提供了dismiss方法

dismissPopoverAnimated:

用于将popover隐藏。

popover的显示定位依赖于触发popover的视图的当前定位,对于那些在整个生命周期内位置情况不会发生改变的静态视图,显示popover的流程和方法上基本不会存在任何问题,只要按照代码逻辑进行简单的拼装显示即可。但是并不是所有的视图的位置一直是固定不变的,对于同时支持横屏和竖屏的应用程序来说,界面上某些view的位置可能在转屏后要进行重定位,而其中的一些view很可能是用来显示popover的触发器。这样,如果当前在横屏时某个popover处于显示状态,那么在转至竖屏时,需要考虑重定位显示,如果不做任何处理,那么popover本身只会呆在原位置,而不会再自动“链接”至触发显示的view上。这本身是一个显示问题,也是一个程序的bug。

问题很简单,解决的方式处理也很简单,一种方式是在转屏前干脆调用dismissPopoverAnimated:方法将popover清除,之后用户想要再次查看popover中的内容时,只要再次点击触发popover显示的view或toolbar item将popover再次呼出即可。但对于苛求实现细节的设计者或开发者来说,这种处理方式不好之处在于多了一步非必须的用户操作。第二种处理方式则是在转屏完成后以代码形式再次调用popover对应的显示方法,已达到对其重定位的操作。一般情况下新建UIPopoverController对象都是以强引用形式保存在某个UIViewController对象的属性中,并有该controller控制下的某个view作为popover显示的触发器,示例如下:

@interface MyViewController

@property (nonatomic) UIPopoverController *popOver ;

@property (nonatomic , weak) UIView *popoverTriggerView ;

@end

而UIViewController类本身也已经提供了响应设备转屏过程中所涉及到的每个阶段的消息:

// 转屏动作发生即将发生前调用
– willRotateToInterfaceOrientation:duration:

// 转屏过程中调用
– willAnimateRotationToInterfaceOrientation:duration:

// 转屏过程结束调用
– didRotateFromInterfaceOrientation:

鉴于以上内置的转屏消息,我们可以在-didRotateFromInterfaceOrientation:方法中再次调用popover的显示方法,对其重定位:

// MyViewController

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [self.popOver presentPopoverFromRect: self.popoverTriggerView.bounds  
                                   inView:self.popoverTriggerView  
                permittedArrowDirections:UIPopoverArrowDirectionAny
                               animated:YES];
}

你可能感兴趣的:(转屏后UIPopoverController的重定位)