0

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とビューを共有しますが、これは私が望んでいることではありません。

しかし、向きを縦向きに戻すと、ビューは正常に機能しています。

4

1 に答える 1

3

問題は、ページサイズ(つまり、スクロールビューの幅)は変更されていますが、画像の幅は変更されていないことです。

1つの解決策は、回転するときにUIImageViewsのサイズを決定し、scrollviewのcontentSizeを計算する計算を再実行することです。つまり、forループと割り当てをscrollView.contentSizeに移動してviewDidLoadからプライベートメソッド、たとえばsizeImagesAndSetContentSizeに移動します。willAnimateRotationToInterfaceOrientation:durationからそれを呼び出します:次のようなもの:

- (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にあります。実際、コールをそこに移動する場合、ローテーションが発生するとビューがサブビューをレイアウトし、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で実行されます)、ラベルをいじる必要はありません。

テキストオーバーレイのストーリーボード構造

このアプリケーションは、スクロールビューページに現在表示されている画像と一致するように説明ラベルを変更します。そのため、ページの変更を検出する必要があります。このアプリは、スクロールビューデリゲートプロトコルメソッドscrollViewDidEndDeceleratingでそれを行います。スクロールが停止して正しい説明を入力したときに画面に表示される画像を決定します。

別の方法は、各UIImageの上にラベルを付けることですが、それは面倒です。そのため、私のアプリはそれを行いません。ラベルの再配置が意味をなすように、ビューにUIImageとラベルの両方を含めることをお勧めします。おそらくそれをコードで作成します...私にとっては、あまりにも多くの問題があります。

余談ですが、スクロールビューでページモードを使用することは、おそらくこれを行うための「ベストプラクティス」の方法ではなくなったと言えます。アプリを簡素化するUIPageViewControllerを使用するようにアプリを変換しています。たとえば、UIPageViewControlの個々の子VCは自動的にサイズを変更できるため、回転時にサイズ変更を行う必要はありません。

于 2013-03-03T21:18:51.837 に答える