UIView加载了Nib自动调整问题

时间:2011-07-20 06:37:50

标签: iphone ios uiview interface-builder orientation

我有一个UIView子类 -

@interface DatePickerPopup : UIView
    UIToolbar *toolbar;
    UIDatePicker *datePicker;
@end

@implementation

- (id)initWithFrame:(CGRect)frame
{
    NSArray *xib = 
        [[NSBundle mainBundle] 
            loadNibNamed:@"DatePickerPopup" 
                  owner:self 
                options:nil];
    self = [xib objectAtIndex:0];
    if (self) {

    }
    return self;
}
@end

和笔尖看起来像 -
nib ib autoresizing

在我的包含DatePickerPopup(datePopup)的UIViewController中:

- (void)viewDidLoad
{
    datePopup = [[DatePickerPopup alloc] initWithRect:CGRectZero];
    CGRect newFrame = datePopup.frame;
    newFrame.y = 200.0f; //lets say this aligns it to the bottom in portrait
    datePopup.frame = newFrame;

    // Normally happens when accessory button pressed but for brevity...
    [self.view.superview addSubview:datePopup];
}

- (void)willAnimateRotationToInterfaceOrientation:
    (UIInterfaceOrientation)toInterfaceOrientation 
    duration:(NSTimeInterval)duration
{
    CGRect screen = [[UIScreen mainScreen] bounds];
    if (toInterfaceOrientation == UIInterfaceOrientationPortrait || 
        toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
    {
        self.datePopup.frame = 
            CGRectMake(0.0f, newHeightPortrait, screen.size.width, 260.0f);
    }
    else
    {
        self.datePopup.frame = 
            CGRectMake(0.0f, newHeightLandscape, screen.size.width, 260.0f);
    }
}

然而,当方向改变视图被拉伸到屏幕边界的高度时,由于某种原因,这会被拉伸 - 导航栏......

在viewDidLoad之后

after viewDidLoad

之后willAutorotate ...
after willAutorotate...

2 个答案:

答案 0 :(得分:2)

由于您的视图控制器似乎由导航控制器管理,因此调用[self.view.superview addSubview:datePopup];会将您的弹出窗口添加为UIViewControllerWrapperView的子视图,这是UIKit用于实现其功能的私有类之一UINavigationController。与UIKit的私有视图层次结构混淆总是有风险的。在这种情况下,根据您所看到的行为,UIKit可能希望UIViewControllerWrapperView的任何子视图都是视图控制器的视图,因此它会相应地调整弹出窗口的大小。

我认为解决此问题最安全的方法是让您的视图控制器视图成为包含tableView的包装器,并在必要时包含弹出视图。不幸的是,使用包装器视图意味着视图控制器不能是UITableViewController。您必须将超类更改为UIViewController,设置自定义tableView属性,然后手动采用UITableViewDataSourceUITableViewDelegate协议。

注意:您可能想要将popover添加为窗口的子视图,但我不建议这样做,因为UIWindow仅自动旋转其对应于视图控制器的最顶层子视图。这意味着如果您将弹出窗口添加到窗口,它将不会自动旋转。


编辑:顺便说一下,通过在self = [xib objectAtIndex:0];中重新分配initWithFrame:,您正在泄漏最初分配的对象。如果您要以这种方式重新分配self,则应首先释放现有对象。

答案 1 :(得分:0)

添加

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
viewController类中的

方法并返回YES。如果此方法返回YES,则只有设备支持横向方向。试试这个额外的代码,看看它是否有帮助...... 您可以在此方法本身中设置横向的帧大小,而不是当前方法。 PS:我刚刚看到你使用的是UIView而不是控制器...你可能想要换成控制器。