旋转后的 UIScrollViews 帧

Posted

技术标签:

【中文标题】旋转后的 UIScrollViews 帧【英文标题】:UIScrollViews frames after rotation 【发布时间】:2013-10-22 11:08:21 【问题描述】:

在第二个 VC 的应用程序中,我有 UICollectionViewCell 有很少的图像缩影,点击后你转到全屏显示单元格内的所有图像(例如,如果单元格中有 3 个图像(滚动视图在里面)你会继续使用它三个图像全屏演示)。 为了显示几张图片,我在另一个里面使用了一个滚动视图(在 *** 上的某个地方找到了解决方案)。

在情节提要上,我只有主 UIView。我在代码中设置的所有其他内容。我知道,在使用自动布局时我不应该在代码中使用框架,但是在使用滚动视图 with zoom 和旋转时,我几乎不可能设置适当的约束。而这个解决方案我只在fullScreenVC中使用。

所以,在viewDidLoad

self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)]; 
self.outerScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];

self.outerScrollView.showsHorizontalScrollIndicator = NO;
self.outerScrollView.showsVerticalScrollIndicator = YES;
self.outerScrollView.delegate = self;
self.outerScrollView.pagingEnabled = YES;
[self scrollViewDataForPortrait:NO];

[self.view insertSubview:self.outerScrollView belowSubview:self.blackInfoBox];
[self scrollToCurrentElement:[self.currentPictureToDisplay integerValue]];

scrollViewDataForPortatit:(BOOL) 是使用图片填充内部滚动视图和设置框架的方法,框架取决于方向

- (void)scrollViewDataForPortrait:(BOOL)isPortrait

    for (int gadabout = 0; gadabout < [self.imagesToDisplay count]; gadabout++)
    
        CGRect frame;
        frame.origin.x = self.imageView.frame.size.width * gadabout;
        frame.origin.y = 0;
        frame.size = self.imageView.frame.size;

        UIScrollView *innerScrollView = [[UIScrollView alloc] initWithFrame:frame];

        UIImageView *newView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
        if (isPortrait)
        
            [newView setFrame:CGRectMake(0, 0, 768, 1024)];
        
        newView.contentMode = UIViewContentModeScaleAspectFit;
        newView.userInteractionEnabled = YES;

        UIImage *painting = [self.imagesToDisplay objectAtIndex:gadabout];
        if (painting)
        
            [newView setImage:painting];
        

        innerScrollView.minimumZoomScale = 1.0f;
        innerScrollView.maximumZoomScale = 4.0f;
        innerScrollView.delegate = self;
        innerScrollView.tag = gadabout;

        [self.arrayForUIImageViewsForZooming addObject:newView];
        [innerScrollView addSubview:newView];
        [innerScrollView setBackgroundColor:[UIColor blackColor]];

        [innerScrollView setContentSize:CGSizeMake(1024, 768)];
        if (isPortrait)
        
            [innerScrollView setContentSize:CGSizeMake(768, 1024)];
        
        [self.outerScrollView addSubview:innerScrollView];
    
    self.outerScrollView.contentSize = CGSizeMake(self.outerScrollView.frame.size.width * self.imagesToDisplay.count, self.outerScrollView.frame.size.height);

在 willRotateTo 中处理旋转...我正在删除旧的子视图并添加新的带有框架的肖像。

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

    self.outerScrollView.zoomScale = 1.0;

    if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
    
        [UIView animateWithDuration:0.3f animations:^
            [self.outerScrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
            [self.imageView setFrame:CGRectMake(0, 0, 1024, 768)];
            [self.outerScrollView setFrame:CGRectMake(0, 0, 1024, 768)];
            [self.arrayForUIImageViewsForZooming removeAllObjects];
            [self scrollViewDataForPortrait:NO];
         completion:^(BOOL finished) 
            [UIView animateWithDuration:0.5f animations:^
                [self scrollToCurrentElement:[self.currentPictureToDisplay integerValue]];
             completion:nil];
        ];
    
    else
    
        [UIView animateWithDuration:0.3f animations:^
            [self.outerScrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
            [self.imageView setFrame:CGRectMake(0, 0, 768, 1024)];
            [self.outerScrollView setFrame:CGRectMake(0, 0, 768, 1024)];
            [self.arrayForUIImageViewsForZooming removeAllObjects];
            [self scrollViewDataForPortrait:YES];
         completion:^(BOOL finished) 
            [UIView animateWithDuration:0.3f animations:^
                [self scrollToCurrentElement:[self.currentPictureToDisplay integerValue]];
             completion:nil];
        ];

不幸的是,这个解决方案的缺点是,在旋转滚动视图滚动到第一个元素之后,我以编程方式滚动到滚动视图中的上一个(当前)位置。 这种变化对我不想要的用户来说是显而易见的。

我还尝试在 willRotate 中设置所有视图和子视图的框架,但之后滚动视图的行为很奇怪。

在使用两个滚动视图(一个在另一个里面)时如何正确处理旋转并正确显示图像?

【问题讨论】:

【参考方案1】:

“我还尝试在 willRotate 中设置所有视图和子视图的框架,但之后滚动视图的行为很奇怪。”

所以这是解决问题的正确解决方案。 我用这段代码做了,例如在旋转到横向之前为所有子视图设置适当的框架。

    int gadabout = 0;
    for (UIScrollView *innerScrollView in self.outerScrollView.subviews)
    
        [innerScrollView setFrame:CGRectMake(1024 * gadabout, 0, 1024, 768)];    
        if ([innerScrollView isKindOfClass:[UIScrollView class]])
        
            [innerScrollView setContentSize:CGSizeMake(1024, 768)];
            
        for (UIImageView *innerImageView in innerScrollView.subviews)
        
            [innerImageView setFrame:CGRectMake(0, 0, 1024, 768)];
        
        gadabout++;
    

【讨论】:

以上是关于旋转后的 UIScrollViews 帧的主要内容,如果未能解决你的问题,请参考以下文章

旋转流式数据帧 pyspark

CSS关键帧动画中的平滑旋转

找到旋转的 SKSpriteNode 的精确帧

带有 UIScrollViews 的 iCarousel

如何使用 linux 帧缓冲区旋转 Qt5 应用程序?

unity物体缓慢停止