UIImageView が取り込まれた UIScrollView があります。iPhoneの写真アプリと同じように、各UIImageViewでズームとパン、次のページへのフリックができるようにしたいと思います。私は周りを検索しましたが、これまでのところこれがあります:
NSArray *pages = [self loadImages];
_pageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
NSUInteger pageCount = [pages count]; // Adjustable
for (int i = 0; i < pageCount; i++) {
CGFloat x = i * self.view.frame.size.width;
// Page Settings
UIImageView *pageView = [[UIImageView alloc] initWithFrame:CGRectMake(x, 0, self.view.frame.size.width, self.view.frame.size.height)];
pageView.backgroundColor = [UIColor greenColor];
pageView.image = [pages objectAtIndex:i];
pageView.userInteractionEnabled = YES;
pageView.tag = i;
UIScrollView *pageScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
pageScroll.maximumZoomScale = 2.0f;
pageScroll.minimumZoomScale = 1.0f;
pageScroll.zoomScale = 1.0f;
pageScroll.bouncesZoom = YES;
pageScroll.contentSize = CGSizeMake(pageView.frame.size.width, pageView.frame.size.height);
pageScroll.pagingEnabled = NO;
pageScroll.delegate = self;
[pageScroll addSubview:pageView];
// Gesture Reocgnisers
UIPinchGestureRecognizer *pinchGr = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchImage:)];
pinchGr.delegate = self;
[pageView addGestureRecognizer:pinchGr];
UIPanGestureRecognizer *panGr = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panImage:)];
[pageView addGestureRecognizer:panGr];
[_pageScrollView addSubview:pageView];
}
_pageScrollView.contentSize = CGSizeMake(self.view.frame.size.width * pageCount, self.view.frame.size.height);
_pageScrollView.pagingEnabled = YES;
_pageScrollView.delegate = self;
[self.view addSubview:_pageScrollView];
ページング(水平スクロール)だけで問題なく動作します。ただし、UIImageViewごとにUIGesturesを実装する方法にスタックしています。そして、ここstackoverflowのさまざまな良い質問と回答の助けを借りて、次のようにズームとパンを実装しました:
- (void) pinchImage:(UIPinchGestureRecognizer*)pgr {
[self adjustAnchorPointForGestureRecognizer:pgr];
if ([pgr state] == UIGestureRecognizerStateBegan || [pgr state] == UIGestureRecognizerStateChanged) {
CGFloat currentScale = pgr.view.frame.size.width / pgr.view.bounds.size.width;
CGFloat newScale = currentScale * pgr.scale;
if (newScale < 1.01f) {
newScale = 1.01f;
}
if (newScale > 3.0f) {
newScale = 3.0f;
}
CGAffineTransform transform = CGAffineTransformMakeScale(newScale, newScale);
pgr.view.transform = transform;
pgr.scale = 1;
}
}
- (void) panImage:(UIPanGestureRecognizer*)panGr {
if ([panGr state] == UIGestureRecognizerStateBegan || [panGr state] == UIGestureRecognizerStateChanged) {
CGPoint p = [panGr translationInView:self.view];
NSLog(@"[PAMPHLET PAGE]: Point: %@", NSStringFromCGPoint(p));
CGPoint movedPoint = CGPointMake(panGr.view.center.x + p.x, panGr.view.center.y + p.y);
if (panGr.view.frame.size.width > panGr.view.center.x + p.x &&
panGr.view.frame.size.height > panGr.view.center.y + p.y) {
panGr.view.center = movedPoint;
NSLog(@"Current: %f / %f", panGr.view.center.x, panGr.view.center.y);
}
[panGr setTranslation:CGPointZero inView:self.view];
}
}
これはほぼそこで機能しますが、いくつかの問題があります。ズームとパンの両方が UIImageView のスケールに制限されず、境界の外側にズームアウトまたはパンアウトすると、画像が次のビューを超えてすべてがうまくいきません。私はまだこれを理解していますが、どこから始めるべきかわかりません。
これらのジェスチャの有効領域を「制限」するにはどうすればよいですか、または別の方法を試す必要がありますか? これはこれを達成するための正しいアプローチですか?写真アプリのようなシンプルなフォトギャラリーを作りたかった...
よろしくお願いします。
ありがとうございました。