IOS 滚动视图问题
Posted
技术标签:
【中文标题】IOS 滚动视图问题【英文标题】:IOS ScrollView Issues 【发布时间】:2013-05-14 14:40:08 【问题描述】:嘿,我正在关注这个tutorial,目前正处于第一步,但我遇到了一些奇怪的行为。本教程是关于为图像创建滚动视图,最后展示了如何使用页面控制器创建分页的水平 ScrollView。我遵循了第一部分,一切似乎都很好。但是,当我运行代码时它没有正常执行,经过大约一个小时的调试后,我下载了最终项目,在手机上运行它以检查它是否正常工作(确实如此),然后将代码复制到我的所需文件中项目。我的项目仍然无法运行。所以我认为这一定是我的故事板在项目设置中的配置方式。然后我打开了工作示例,清除了他们的故事板,并以与我在项目中所做的完全相同的方式和顺序创建了视图和自我定位。砰!它仍然有效,当我删除故事板上的所有视图并以完全相同的方式重新创建它们时,仍然没有。有人可以查看本教程并告诉我我是否要发疯或他们会遇到类似的结果。我已将其缩小为两种可能性,教程末尾提供的项目创建方式不同,委托或出口以仅适用于项目的方式连接,或者项目是使用早期版本的iPhone 开发套件适用于当前版本的 XCode,但不适用于我创建新项目时。再说一次,我对此很陌生,所以我会抛出我正在使用的代码并希望最好。
ViewController.h
文件:
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController <UIScrollViewDelegate>
@property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
@end
ViewController.m
文件:
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) UIImageView *imageView;
- (void)centerScrollViewContents;
- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer;
- (void)scrollViewTwoFingerTapped:(UITapGestureRecognizer*)recognizer;
@end
@implementation ViewController
@synthesize scrollView = _scrollView;
@synthesize imageView = _imageView;
- (void)centerScrollViewContents
CGSize boundsSize = self.scrollView.bounds.size;
CGRect contentsFrame = self.imageView.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;
self.imageView.frame = contentsFrame;
- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer
// Get the location within the image view where we tapped
CGPoint pointInView = [recognizer locationInView:self.imageView];
// Get a zoom scale that's zoomed in slightly, capped at the maximum zoom scale specified by the scroll view
CGFloat newZoomScale = self.scrollView.zoomScale * 1.5f;
newZoomScale = MIN(newZoomScale, self.scrollView.maximumZoomScale);
// Figure out the rect we want to zoom to, then zoom to it
CGSize scrollViewSize = self.scrollView.bounds.size;
CGFloat w = scrollViewSize.width / newZoomScale;
CGFloat h = scrollViewSize.height / newZoomScale;
CGFloat x = pointInView.x - (w / 2.0f);
CGFloat y = pointInView.y - (h / 2.0f);
CGRect rectToZoomTo = CGRectMake(x, y, w, h);
[self.scrollView zoomToRect:rectToZoomTo animated:YES];
- (void)scrollViewTwoFingerTapped:(UITapGestureRecognizer*)recognizer
// Zoom out slightly, capping at the minimum zoom scale specified by the scroll view
CGFloat newZoomScale = self.scrollView.zoomScale / 1.5f;
newZoomScale = MAX(newZoomScale, self.scrollView.minimumZoomScale);
[self.scrollView setZoomScale:newZoomScale animated:YES];
- (void)viewDidLoad
[super viewDidLoad];
// Set a nice title
self.title = @"Image";
// Set up the image we want to scroll & zoom and add it to the scroll view
UIImage *image = [UIImage imageNamed:@"photo1.png"];
self.imageView = [[UIImageView alloc] initWithImage:image];
self.imageView.frame = (CGRect).origin=CGPointMake(0.0f, 0.0f), .size=image.size;
[self.scrollView addSubview:self.imageView];
// Tell the scroll view the size of the contents
self.scrollView.contentSize = image.size;
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewDoubleTapped:)];
doubleTapRecognizer.numberOfTapsRequired = 2;
doubleTapRecognizer.numberOfTouchesRequired = 1;
[self.scrollView addGestureRecognizer:doubleTapRecognizer];
UITapGestureRecognizer *twoFingerTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewTwoFingerTapped:)];
twoFingerTapRecognizer.numberOfTapsRequired = 1;
twoFingerTapRecognizer.numberOfTouchesRequired = 2;
[self.scrollView addGestureRecognizer:twoFingerTapRecognizer];
- (void)viewWillAppear:(BOOL)animated
[super viewWillAppear:animated];
// Set up the minimum & maximum zoom scales
CGRect scrollViewFrame = self.scrollView.frame;
CGFloat scaleWidth = scrollViewFrame.size.width / self.scrollView.contentSize.width;
CGFloat scaleHeight = scrollViewFrame.size.height / self.scrollView.contentSize.height;
CGFloat minScale = MIN(scaleWidth, scaleHeight);
self.scrollView.minimumZoomScale = minScale;
self.scrollView.maximumZoomScale = 1.0f;
self.scrollView.zoomScale = minScale;
[self centerScrollViewContents];
- (void)viewDidUnload
[super viewDidUnload];
// Release any retained subviews of the main view.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
// Return the view that we want to zoom
return self.imageView;
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
// The scroll view has zoomed, so we need to re-center the contents
[self centerScrollViewContents];
@end
上面的代码不像在教程项目中那样工作。以下 UIScrollView 委托方法 viewForZoomingInScrollView 会产生此错误:
2013-05-14 10:01:18.585 TestScrollView[3809:907] 成功了
5 月 14 日 10:01:18 Scott-Laroses-iPhone TestScrollView[3809]:CGAffineTransformInvert:奇异矩阵。
5 月 14 日 10:01:18 Scott-Laroses-iPhone TestScrollView[3809]:CGAffineTransformInvert:奇异矩阵。
这让我觉得延迟设置不正确,尽管我的做法与教程中的完全相同,并且在不起作用时以编程方式进行。有什么想法吗?
【问题讨论】:
你忘了扔代码 ;) 我开始在我的 PC 上写问题,并不认为需要代码,所以我把它贴出来打开我的 Mac 并完成它。没想到有人会注意到,但男孩是我错了! @danypata ios: <Error>: CGAffineTransformInvert: singular matrix的可能重复 【参考方案1】:如果分配的值为 0,您的问题可能来自 zoomScale
和 minimumZoomScale
。请确保这两个属性的值永远不会为 0。
【讨论】:
您可以从 .xib 文件中设置缩放比例,但我看到您也可以通过代码计算缩放比例,您应该检查该代码,以便 zoomScale 永远不会为 0。【参考方案2】:我想通了!问题是自动布局约束弄乱了屏幕外视图。所以我禁用了自动布局,它工作正常。
【讨论】:
以上是关于IOS 滚动视图问题的主要内容,如果未能解决你的问题,请参考以下文章
滚动视图在 iOS 7 中运行良好,但在 iOS6 中出现问题