这应该是一件很常见的事情,但是我还没能让它完全正确地工作。
我有矩形内容。它通常适合320x361:纵向模式-状态栏-广告-标签栏。
我已经把内容放到了UIScrollView中并启用了缩放。我还希望界面旋转工作。内容将始终是一个高矩形,但当缩放时,用户可能希望一次看到更大的宽度和更小的高度。
我需要在界面生成器和代码中做些什么来完成这项工作?如何在不同的视图上设置自动调整大小?我如何设置我的contentSize和contentInsets?
我已经尝试了很多不同的方法,没有一个是完全正确的。在我的各种解决方案中,我遇到的问题是,在进行了缩放、界面旋转和滚动的组合后,不再可能滚动到屏幕上的整个内容。在你看到内容的边缘之前,滚动视图会把你拉回来。
我现在做的方法大约有80%是正确的。也就是说,在10件应该做的事情中,它只做了8件。它做错的两件事是:
-
当在纵向模式下放大时,您可以滚动过内容的边缘,并看到黑色背景。这没什么好抱怨的。至少你可以看到所有的内容。在横向模式下,无论是否缩放,看到黑色背景超过边缘是正常的,因为内容没有足够的宽度来填充1:1缩放级别的屏幕(最小值)。
-
当它在运行iOS 3.0的测试设备上运行时,我仍然会得到内容卡在边缘,但它在运行4.x的我的设备上工作。——实际上这是上一个解。我的测试人员还没有尝试最新的解决方案。
这是我目前使用的解决方案。总而言之,我已经将滚动视图设置为任意方向所需的宽度和高度,因为我发现手动或自动调整它的大小会增加复杂性,而且很脆弱。
视图层次结构:
- 视图
- 滚动视图
- scrollableArea
- scrollableArea
- 滚动视图
视图是320x411,并有所有的自动调整大小选项,所以符合屏幕形状
scrollView 480 x 361,从原点-80,0开始,只锁定顶部并禁用拉伸
scrollableArea 480 x 361,锁在左边和上面。由于scrollView禁用拉伸,其子视图的自动调整大小掩码无关紧要,但我还是告诉你。
内容是320x361,从原点80,0开始,并锁定到顶部
我将scrollView.contentSize
设置为480x361。
shouldAutorotateToInterfaceOrientation
支持所有方向,除了纵向倒立。
在didRotateFromInterfaceOrientation中,如果方向是横向的,我将底部内容插入值设置为160,如果不是重置为0。如果方向是纵向的,我将左右指示器的插入值分别设置为80,如果不是,则重置。
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 2.0
viewForZoomingInScrollView返回scrollableArea
// in IB it would be all options activated
scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
scrollView.contentSize = content.frame.size; // or bounds, try both
你说的scrollableArea
是什么意思?
你的minZoomScale
被设置为1.0
,这对肖像模式很好,但不适合风景。因为在横屏中你的高度比竖屏小,所以你需要设置一个小于1.0
的值。对我来说,我使用这个实现,每次调用它,scrollView的框架确实改变了:
- (void)setMaxMinZoomScalesForCurrentBounds {
CGSize boundsSize = self.bounds.size; // self is a UIScrollView here
CGSize contentSize = content.bounds.size;
CGFloat xScale = boundsSize.width / contentSize.width;
CGFloat yScale = boundsSize.height / contentSize.height;
CGFloat minScale = MIN(xScale, yScale);
if (self.zoomScale < minScale) {
[self setZoomScale:minScale animated:NO];
}
if (minScale<self.maximumZoomScale) self.minimumZoomScale = minScale;
//[self setZoomScale:minScale animated:YES];
}
- (void)setFrame:(CGRect)rect { // again, this class is a UIScrollView
[super setFrame:rect];
[self setMaxMinZoomScalesForCurrentBounds];
}
我不认为我从你的帖子中理解了整个问题,但这里有一个我理解的答案。
据我所知(和工作与UIScrollView),内容在一个UIScrollView不会自动自动调整大小随着UIScrollView。
把UIScrollView看作是一个窗口/门户,它通向你的内容所在的另一个世界。当自动调整UIScrollView的大小时,你只是改变了查看窗口的形状/大小…而不是另一个宇宙内容的大小
然而,如果需要,你可以拦截旋转事件,并手动更改你的内容也(与动画,使它看起来不错)。
为了正确的自动调整大小,你应该改变scrollView的contentSize(这样它就知道你的宇宙的大小),但也要改变UIView的大小。我想这就是为什么你可以滚动看到黑色内容的原因。也许你只是更新了contentSize,但现在实际的内容视图
就我个人而言,我还没有遇到过任何需要随着UIScrollView调整内容大小的情况,但我希望这将使您在正确的方向上开始
如果我理解正确的话,你想要一个带有图像的滚动视图。它需要全屏开始,你需要能够放大。最重要的是,你希望它能够根据方向旋转。
好吧,我一直在原型与此在过去,如果所有以上是正确的,下面的代码应该为您工作。
我为bar/custombars留下了一点白色区域。
- (void)viewDidLoad
{
[super viewDidLoad];
//first inits and allocs
scrollView2 = [[UIScrollView alloc] initWithFrame:self.view.frame];
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImageName"]];
[scrollView2 addSubview:imageView];
[self drawContent]; //refreshing the content
[self.view addSubview:scrollView2];
}
-(void)drawContent
{
//this refreshes the screen to the right sizes and zoomscales.
[scrollView2 setBackgroundColor:[UIColor blackColor]];
[scrollView2 setCanCancelContentTouches:NO];
scrollView2.clipsToBounds = YES;
[scrollView2 setDelegate:self];
scrollView2.indicatorStyle = UIScrollViewIndicatorStyleWhite;
[scrollView2 setContentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)];
[scrollView2 setScrollEnabled:YES];
float minZoomScale;
float zoomHeight = imageView.frame.size.height / scrollView2.frame.size.height;
float zoomWidth = imageView.frame.size.width / scrollView2.frame.size.width;
if(zoomWidth > zoomHeight)
{
minZoomScale = 1.0 / zoomWidth;
}
else
{
minZoomScale = 1.0 / zoomHeight;
}
[scrollView2 setMinimumZoomScale:minZoomScale];
[scrollView2 setMaximumZoomScale:7.5];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
// Portrait
//the 88pxls is the white area that is left for the navbar etc.
self.scrollView2.frame = CGRectMake(0, 88, [UIScreen mainScreen].bounds.size.width, self.view.frame.size.height - 88);
[self drawContent];
}
else {
// Landscape
//the 88pxls is the white area that is left for the navbar etc.
self.scrollView2.frame = CGRectMake(0, 88, [UIScreen mainScreen].bounds.size.height, self.view.frame.size.width);
[self drawContent];
}
return YES;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
我希望这会解决你的麻烦。如果没有,请留下评论。
当你想把一个内容(一个UIView
实例,让我们叫它theViewInstance
)放在UIScrollView
然后滚动/缩放theViewInstance
,方法是:
-
viewinstance
应该被添加为UIScrollView
的子视图 设置委托给
UIScrollView
实例并实现选择器以返回应该用于缩放/滚动的视图:-(UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView { return theViewInstance; }
设置UIScrollView的内容大小默认为theViewInstance的框架:
scrollView.contentSize=theViewInstance.frame.size;
(此外,可以在UIScrollView:中设置可接受的缩放级别)
scrollView.minimumZoomScale=1.0; scrollView.maximumZoomScale=3.0;
这是在UIImage上实现缩放的方式:UIImageView被添加到UIScrollView中,在UIScrollViewDelegate实现中,UIImageView被返回(如这里所述)。
对于旋转支持,这是在UIViewController中完成的它的UIView包含了我们刚刚讨论过的UIScrollView