IOS 6と自動レイアウトの前にUIScrollView内にUIImageViewを埋め込んでいますが、コントローラーのviedDidLoadメソッド内で次のスニペットを使用して、スクロール可能でズーム可能な画像を表示しました。
self.scrollView.contentSize = self.imageView.image.size;
self.imageView.frame = CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height);
ただし、ストーリーボードで設定された制約が代わりに使用されるようになりました。私はこの質問を見つけました iOS 6の自動レイアウトでScrollViewにImageViewを埋め込みます そしてここで他のいくつかはSOで、viewDidLoadの後に制約がロード/強制されることを示しています、そしてそれは以前のスニペットをviewDidAppearに移動するとこの問題は解決しますが、ズームが適切に機能せず、ピンチ操作でズームした後、scrollViewとimageViewのサイズがストーリーボードの制約にリセットされるようです。
私は推測しているだけですが、おそらく、機能するコードでscrollViewとimageViewの垂直および水平のスペース制約をオーバーライドする方法があると思います。
この問題を抱えている人は他にいますか?
次のコードサンプルを使用して問題を解決しました。 githubリポジトリは、MattNeuburgによる本ProgrammingiOSに対応しています。
最良の解決策は、コメントでZsoltによって提案されました。
http://github.com/evgenyneu/ios-imagescroll これをチェックしてください。私にとっては完璧に機能します。
このリポジトリで提案されている解決策は、画像を表示する前に最小ズームレベルと現在のズームレベルを調整することです。
@interface MyViewController () <UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.scrollView.delegate = self;
[self initZoom];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[self initZoom];
}
// Zoom to show as much image as possible
- (void) initZoom {
float minZoom = MIN(self.view.bounds.size.width / self.imageView.image.size.width,
self.view.bounds.size.height / self.imageView.image.size.height);
if (minZoom > 1) return;
self.scrollView.minimumZoomScale = minZoom;
self.scrollView.zoomScale = minZoom;
}
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
ただし、サンプルのconatinsはズームアウトの問題です。画像が中央に配置されていません。これは、次のコードを含むカスタムスクロールビュークラスを使用することで簡単に修正できます。
@interface MyScrollView : UIScrollView
@end
@implementation MyScrollView
-(void)layoutSubviews
{
[super layoutSubviews];
UIView* v = [self.delegate viewForZoomingInScrollView:self];
CGFloat svw = self.bounds.size.width;
CGFloat svh = self.bounds.size.height;
CGFloat vw = v.frame.size.width;
CGFloat vh = v.frame.size.height;
CGRect f = v.frame;
if (vw < svw)
f.Origin.x = (svw - vw) / 2.0;
else
f.Origin.x = 0;
if (vh < svh)
f.Origin.y = (svh - vh) / 2.0;
else
f.Origin.y = 0;
v.frame = f;
}
@end
Zsoltの提案とリンクにも同意します。
ただし、幅/高さの制約を更新して、任意のサイズの画像を処理できるようにします。
- (void) initZoom
{
for (NSLayoutConstraint *constraint in self.photoImageView.constraints)
{
if (constraint.firstAttribute == NSLayoutAttributeWidth)
constraint.constant = self.photoImageView.image.size.width;
else if (constraint.firstAttribute == NSLayoutAttributeHeight)
constraint.constant = self.photoImageView.image.size.height;
}
float minZoom = MIN(self.scrollView.bounds.size.width / self.photoImageView.image.size.width,
self.scrollView.bounds.size.height / self.photoImageView.image.size.height);
if (minZoom > 1) return;
self.scrollView.minimumZoomScale = minZoom;
self.scrollView.zoomScale = minZoom;
}