Zack Morris
Zack Morris

Reputation: 4823

UIPageViewController changes size?

I'm using the Page-Based Application template in Xcode 4 to load pages of a PDF and create a UITextView over hidden text boxes so the user can write notes.

So far I have it all working, but when I add the UITextView, it's in the wrong place in landscape mode (showing 2 pages).

// ModelController.m

- (id)init
{
    self = [super init];
    if (self) {
        NSString *pathToPdfDoc = [[NSBundle mainBundle] pathForResource:@"My PDF File" ofType:@"pdf"];
        NSURL *pdfUrl = [NSURL fileURLWithPath:pathToPdfDoc];
        self.pageData = CGPDFDocumentCreateWithURL((__bridge CFURLRef)pdfUrl);  // pageData holds the PDF file
    }
    return self;
}

- (DataViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard
{
    // Return the data view controller for the given index.
    if( CGPDFDocumentGetNumberOfPages( self.pageData ) == 0 || (index >= CGPDFDocumentGetNumberOfPages( self.pageData )))
        return nil;

    // Create a new view controller and pass suitable data.
    DataViewController *dataViewController = [storyboard instantiateViewControllerWithIdentifier:@"DataViewController"];
    dataViewController.dataObject = CGPDFDocumentGetPage( self.pageData, index + 1 );   // dataObject holds the page of the PDF file

    [dataViewController view];  // make sure the view is loaded so that all subviews can be accessed

    UITextView  *textView = [[UITextView alloc] initWithFrame:CGRectMake( 10, 20, 30, 40 )];

    textView.layer.borderWidth = 1.0f;
    textView.layer.borderColor = [[UIColor grayColor] CGColor];

    [dataViewController.dataView addSubview:textView];  // dataView is a subview of dataViewController.view in the storyboard/xib

    CGRect  viewFrame = dataViewController.dataView.frame;  // <- *** THIS IS THE WRONG SIZE IN LANDSCAPE ***
}

This behavior really surprised me, because viewControllerAtIndex isn't called when I rotate the iPad, so I have no way of knowing what the real size of the view frame is. I get the same view frame in both portrait and landscape:

# in Xcode console:
po [dataViewController view]

# result in either orientation:
(id) $4 = 0x0015d160 <UIView: 0x15d160; frame = (0 20; 768 1004); autoresize = RM+BM; layer = <CALayer: 0x15d190>>
#

Does anyone know if there is a transform I'm supposed to use to position the UITextView correctly? I'm concerned that I may have to store the locations of the elements independently and reposition them upon receiving shouldAutorotateToInterfaceOrientation messages.

It seems that Apple may have implemented UIPageViewController improperly, but all I could find was this partial workaround that I'm still trying to figure out:

UIPageViewController and off screen orientation changes

Thanks!

Upvotes: 2

Views: 2900

Answers (1)

samkass
samkass

Reputation: 5951

I think the trick here is to override viewDidLayoutSubviews in your DataViewController and manage the size of all your programmatically-inserted non-autosizing views, since you don't really know what the parent is going to do to its subviews until that time.

-(void)viewDidLayoutSubviews
{
  [super viewDidLayoutSubviews];

  self.textView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}

Upvotes: 3

Related Questions