【问题标题】:UIPageControl and UIScrollView during landscape orientation横向时的 UIPageControl 和 UIScrollView
【发布时间】:2013-03-03 16:52:42
【问题描述】:

我遇到了 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 共享视图,这不是我想要的。

但如果我将方向改回纵向,则视图效果很好。

【问题讨论】:

    标签: ios uiview uiscrollview screen-orientation uipagecontrol


    【解决方案1】:

    问题是页面大小已经改变(即滚动视图的宽度)但图像的宽度没有改变。

    一种解决方案是,当您旋转时,您重新计算 UIImageViews 的大小并计算滚动视图的 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];
    }
    

    附录:
    在图像中添加文字:

    要在图像顶部添加文本——您可以在滚动视图的“顶部”添加文本元素,如标签。考虑下面应用程序的屏幕截图。在顶级 Cloud Slide Show View 中有一个全屏滚动视图,在相同的层次结构级别但在子视图列表的更下方(因此在滚动视图的“顶部”)是描述标签,3 个按钮和一个 UIPageControl。标签设置为通过支柱和弹簧调整旋转大小(这在 iOS 5 上运行),因此您不必弄乱它。

    此应用程序更改描述标签以匹配当前显示在滚动视图页面中的图像——因此它必须检测页面更改。此应用在滚动视图委托协议方法 scrollViewDidEndDecelerating: 中执行此操作,它决定滚动停止时屏幕上显示的图像并填写正确的描述。

    另一种方法是在每个 UIImage 上放置一个标签,但这很混乱,这就是我的应用不这样做的原因。您可能希望视图同时包含 UIImage 和标签,以便重新定位标签是有意义的。可能在代码中创建它......对我来说,太麻烦了。

    顺便说一句,我应该说在滚动视图中使用页面模式可能不再是执行此操作的“最佳实践”方式。我正在将我的应用程序转换为使用 UIPageViewController 来简化应用程序。例如,您不必执行 resize-on-rotate 的操作,因为 UIPageViewControl 的各个子 VC 可以自动调整自己的大小。

    【讨论】:

    • 还有一个问题,如何在视图中添加文本?​​
    • 我不确定您所说的“文本”是什么意思。您是指出现在图像顶部的一些文字吗?
    • 是的,例如 image1 是花,image2 是猫。在图片顶部(不在导航栏中),有一个 UILabel 会根据图片而变化。
    • 好的,我编辑了答案以包含在图像上放置描述标签的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 2011-07-02
    • 1970-01-01
    • 2019-01-11
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    相关资源
    最近更新 更多