我想要帮助我的UIScrollView示例。
我创建了一个简单的程序来滚动和缩放内容(UIImageView
)。它工作正常,但当我尝试缩小时内容经常消失到右下角。但是因为我将minimumZoomScale
设置为1.0f,它实际上没有缩小,只有内容跳出视图。更奇怪的是,在此之后我无法向上滚动。显然内容大小也很混乱。
我的示例代码中的设置如下图所示。
当我在(尝试)缩小后检查状态时,我发现了两件错误的事情。
_scrollView.contentSize
为480x360,不应小于1000x1000 _scrollView.bounds
以某种方式跳到顶端(即_scrollView.bounds.origin.y
始终为0) 为了解决上面的两个问题,我在UIScrollViewDelegate中添加了以下代码,现在它可以正常工作。
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
if(scrollView == _scrollView && view == _contentView)
{
// Setting ivars for scrollViewDidZoom
_contentOffsetBeforeZoom = _scrollView.contentOffset;
_scrollViewBoundsBeforeZoom = _scrollView.bounds;
}
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
if(scrollView == _scrollView)
{
// If you zoom out, there are cases where ScrollView content size becomes smaller than original,
// even though minimum zoom scale = 1. In that case, it will mess with the contentOffset as well.
if(_scrollView.contentSize.width < CONTENT_WIDTH || _scrollView.contentSize.height < CONTENT_HEIGHT)
{
_scrollView.contentSize = CGSizeMake(CONTENT_WIDTH, CONTENT_HEIGHT);
_scrollView.contentOffset = _contentOffsetBeforeZoom;
}
// If you zoom out, there are cases where ScrollView bounds goes outsize of contentSize rectangle.
if(_scrollView.bounds.origin.x + _scrollView.bounds.size.width > _scrollView.contentSize.width ||
_scrollView.bounds.origin.y + _scrollView.bounds.size.height > _scrollView.contentSize.height)
{
_scrollView.bounds = _scrollViewBoundsBeforeZoom;
}
}
}
然而,是否需要归结为此?这是一个非常简单的序列,很难相信Apple要求我们付出这样的努力。所以,我的赌注是我在这里遗漏了一些东西......
以下是我的原始代码。请帮我找到我做错了什么(或遗漏了什么)!
#define CONTENT_WIDTH 1000
#define CONTENT_HEIGHT 1000
>>>> Snip >>>>
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
_scrollView.contentSize = CGSizeMake(CONTENT_WIDTH, CONTENT_HEIGHT);
_scrollView.backgroundColor = [UIColor blueColor];
_scrollView.maximumZoomScale = 8.0f;
_scrollView.minimumZoomScale = 1.0f;
_scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
_scrollView.scrollEnabled = YES;
_scrollView.delegate = self;
[self.view addSubview:_scrollView];
_contentView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"sample.jpg"]]; // sample.jpg is 480x360
CGPoint center = (CGPoint){_scrollView.contentSize.width / 2, _scrollView.contentSize.height / 2};
_contentView.center = center;
[_scrollView addSubview:_contentView];
_scrollView.contentOffset = (CGPoint) {center.x - _scrollView.bounds.size.width / 2, center.y - _scrollView.bounds.size.height / 2};
}
- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView
{
if(scrollView == _scrollView)
{
return _contentView;
}
return nil;
}
答案 0 :(得分:11)
我创建了一个快速示例项目,并使用您粘贴的代码描述了相同的问题。我并不完全知道在iOS中“缩放”的“正确”方法是什么,但是我找到了this教程,其中说明在放大scrollView之后需要重新设置contentView。我个人希望它会自动重新集中,因为它是你在viewForZoomingInScrollView委托方法中返回的视图,但显然不是。
- (void)centerScrollViewContents {
CGSize boundsSize = _scrollView.bounds.size;
CGRect contentsFrame = _contentView.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
} else {
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
} else {
contentsFrame.origin.y = 0.0f;
}
_contentView.frame = contentsFrame;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
// The scroll view has zoomed, so we need to re-center the contents
[self centerScrollViewContents];
}
上面的代码不是由我编写的,只是从教程中复制而来。我觉得它很简单。此外,使contentView居中似乎更加优雅,然后不断更改scrollview的边界和内容大小,所以试一试。
答案 1 :(得分:1)
如果有人在缩小显示的背景时遇到弹跳问题,请尝试在Interface Builder中删除跳出(Bounces Zoom)。
答案 2 :(得分:1)
我能够使用调整缩放后的速率的委托答案解决这个问题...但后来我记得我正在使用自动布局,只是添加了水平和垂直居中的约束(除了约束绑定滚动视图的每个边缘的图像)在不使用委托方法的情况下为我解决了问题。
答案 3 :(得分:0)
奥尔山斯克迅速回答5
func scrollViewDidZoom(_ scrollView: UIScrollView) {
centerScrollViewContents()
}
func centerScrollViewContents() {
let boundsSize = scrollView.bounds.size;
var contentsFrame = container.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0;
} else {
contentsFrame.origin.x = 0.0;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0;
} else {
contentsFrame.origin.y = 0.0;
}
container.frame = contentsFrame;
}