2013-03-03 6 views
0

У меня возникают проблемы с UIPageControl и UIScrollView.UIPageControl и UIScrollView во время ландшафтной ориентации

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    imageArray = [[NSArray alloc] initWithObjects:@"image1.jpg", @"image2.jpg", @"image3.jpg", nil]; 

    for (int i = 0; i < [imageArray count]; i++) { 
     CGRect frame; 
     frame.origin.x = self.scrollView.frame.size.width * i; 
     frame.origin.y = 0; 
     frame.size = self.scrollView.frame.size; 

     UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame]; 
     imageView.image = [UIImage imageNamed:[imageArray objectAtIndex:i]]; 
     [self.scrollView addSubview:imageView]; 
    } 
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * [imageArray count], scrollView.frame.size.height); 

    scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 
    pageControl.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; 
} 

#pragma mark - UIScrollView Delegate 

- (void)scrollViewDidScroll:(UIScrollView *)sender 
{ 
    CGFloat pageWidth = self.scrollView.frame.size.width; 
    int page = floor((self.scrollView.contentOffset.x - pageWidth/2)/pageWidth) + 1; 
    self.pageControl.currentPage = page; 
} 

Проблема возникает, когда я меняю ориентацию на пейзаж. image1.jpg разделяет представление с image2.jpg, что не то, что я хочу.

Но если я изменил ориентацию назад к портрету, вид все в порядке.

ответ

3

Проблема в том, что размер страницы изменился (т. Е. Ширина прокрутки), но ширина изображений не изменилась.

Одним из решений является то, что при повороте вы повторно выполняете вычисления, которые определяют размеры UIImageViews и вычисляют контент contentSize прокрутки. То есть, переместите цикл for и присваивание в scrollView.contentSize из viewDidLoad и в частный метод, скажем sizeImagesAndSetContentSize. Звоните, что с willAnimateRotationToInterfaceOrientation: продолжительность: Что-то вроде следующего:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    imageArray = [[NSArray alloc] initWithObjects:@"image1.jpg", @"image2.jpg", @"image3.jpg", nil]; 

    [self sizeImagesAndSetContentSize]; 

    scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 
    pageControl.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; 
} 


- (void) sizeImagesAndSetContentSize { 
     for (int i = 0; i < [imageArray count]; i++) { 
      CGRect frame; 
      frame.origin.x = self.scrollView.frame.size.width * i; 
      frame.origin.y = 0; 
      frame.size = self.scrollView.frame.size; 

      UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame]; 
      imageView.image = [UIImage imageNamed:[imageArray objectAtIndex:i]]; 
      [self.scrollView addSubview:imageView]; 
     } 
     scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * [imageArray count], scrollView.frame.size.height); 
} 
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration { 
    [self sizeImagesAndSetContentSize]; 

} 

Кстати, viewDidLoad не место, чтобы сделать расчеты геометрии - как вещи, которые включают каркас Scrollview, поскольку геометрия тогда не задана. в viewDidLoad размеры вещей - это размеры, которые они были в раскадровке (или наконечнике), и не были настроены на фактическое устройство и фактическую ориентацию. Если это работает до сих пор, это потому, что вы начинаете с ориентации, которую раскладывает раскадровка. Вероятно, это лучшее место для этого, и, таким образом, позвонить sizeImagesAndSetContentSize есть в способе viewDidLayoutSubviews. Фактически, если вы переместите вызов там, вам не нужно будет явно называть его вращением, потому что, когда происходит поворот, представление отображает subviews и viewDidLayoutSubviews будет вызван автоматически. Поэтому я хотел бы предложить:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    imageArray = [[NSArray alloc] initWithObjects:@"image1.jpg", @"image2.jpg", @"image3.jpg", nil]; 

    scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 
    pageControl.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; 
} 

- (void) sizeImagesAndSetContentSize { 
     for (int i = 0; i < [imageArray count]; i++) { 
      CGRect frame; 
      frame.origin.x = self.scrollView.frame.size.width * i; 
      frame.origin.y = 0; 
      frame.size = self.scrollView.frame.size; 

      UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame]; 
      imageView.image = [UIImage imageNamed:[imageArray objectAtIndex:i]]; 
      [self.scrollView addSubview:imageView]; 
     } 
     scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * [imageArray count], scrollView.frame.size.height); 
} 

- (void)viewDidLayoutSubviews { 
    [self sizeImagesAndSetContentSize]; 
} 

Добавление:
ДОБАВЛЕНИЕ ТЕКСТ НА ФОТО:

Чтобы добавить текст поверх изображения - вы можете добавить текстовый элемент, как ярлык «на вверху "прокрутки. Рассмотрим снимок экрана из приложения ниже. В облачном слайд-шоу верхнего уровня есть полноэкранный вид прокрутки и на том же уровне иерархии, но далее вниз список подзапросов (и, таким образом, «сверху» прокрутки) являются меткой описания, 3 кнопки , и UIPageControl. Метка настроена на изменение размера при повороте через распорки и пружины (это работает на iOS 5), поэтому вам не нужно возиться с ним.

Storyboard structure for text overlay

Это приложение изменяет описание метки, чтобы соответствовать изображение, которое отображается в данный момент на странице Scrollview - поэтому он должен обнаружить изменения страниц. Это приложение делает это в методе делегата протокола прокрутки scrollViewDidEndDecererating:, где он решает, какое изображение отображается на экране, когда прокрутка останавливается и заполняет правильное описание.

Альтернативой было бы поставить ярлык поверх каждого UIImage, но это грязно, поэтому мое приложение этого не делает. Вероятно, вы захотите, чтобы представление содержало как UIImage, так и ярлык, так что изменение положения метки могло бы иметь смысл. Наверное, создадим это в коде ... Для меня слишком много неприятностей.

Как в сторону, я должен сказать, что использование режима страницы в режиме прокрутки, вероятно, не является способом «лучшей практики» для этого. Я конвертирую свое приложение, чтобы использовать UIPageViewController, который должен упростить приложение. Например, вам не нужно делать операцию изменения размера, поскольку отдельные дочерние VC-устройства UIPageViewControl могут автоматически изменять размер.

+0

Большое вам спасибо за это! – Jahm

+0

еще один вопрос, как добавить текст внутри представления? – Jahm

+0

Я не уверен, что вы подразумеваете под «текстом». Вы имеете в виду текст, который появляется поверх изображения? –

Смежные вопросы