UIScrollView缩放不适用于Autolayout

Cor*_*rey 38 zoom uiscrollview ios autolayout

使用严格的自动布局环境缩放UIScrollView似乎不起作用.

这特别令人沮丧,因为iOS 6发行说明肯定让我相信它应该在写下关于"纯自动布局方法"的时候http://developer.apple.com/library/ios/#releasenotes/General/RN- iOSSDK-6_0/_index.html

我查看了WWDC 2012幻灯片的会话202,228和232,并没有看到答案.

我在互联网上专门针对这个问题看到的唯一问题是UIScrollView使用自动布局进行缩放,但是它没有提供问题的代码,也没有答案.

这个用户/sf/users/23939611/对UIScrollView自动布局问题给出了很多很好的回复,甚至链接到git hub上的代码,但我找不到任何可以解决这个问题的东西.

我试图将这个问题降到最低限度,以便明确.

我使用故事板创建了一个新的单视图应用程序,并且在界面构建器中没有进行任何更改.

我在项目"pic.jpg"中添加了一个大图片文件.

SVFViewController.h

#import <UIKit/UIKit.h> 
@interface SVFViewController : UIViewController <UIScrollViewDelegate>
@property (nonatomic) UIImageView *imageViewPointer;
@end
Run Code Online (Sandbox Code Playgroud)

SVFViewController.m

#import "SVFViewController.h"

@interface SVFViewController ()

@end

@implementation SVFViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIScrollView *scrollView = [[UIScrollView alloc] init];
    UIImageView *imageView = [[UIImageView alloc] init];
    [imageView setImage:[UIImage imageNamed:@"pic.jpg"]];
    [self.view addSubview:scrollView];
    [scrollView addSubview:imageView];

    scrollView.translatesAutoresizingMaskIntoConstraints = NO;
    imageView.translatesAutoresizingMaskIntoConstraints = NO;
    self.imageViewPointer = imageView;
    scrollView.maximumZoomScale = 2;
    scrollView.minimumZoomScale = .5;
    scrollView.delegate = self;

    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(scrollView,imageView);
    NSLog(@"Current views dictionary: %@", viewsDictionary);
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageView]|" options:0 metrics: 0 views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageView]|" options:0 metrics: 0 views:viewsDictionary]];
}

-(UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView{
    return self.imageViewPointer;
}

@end
Run Code Online (Sandbox Code Playgroud)

请注意,我特别努力使其与iOS 6发行说明中提供的示例代码非常相似,只是尽量减少实现缩放.

那么,问题呢?

当您运行此应用程序并在滚动视图中平移时,一切都很好.但是当你缩放问题很明显时,图像会来回闪烁,并且每次缩放时图像在滚动视图中的位置都会出错.

看起来像是对于imageView的内容偏移正在进行战斗,似乎每次"缩放"时它被两个不同的东西设置为不同的值.(imageView的内容偏移属性的NSLog似乎证实了这一点).

我在这做错了什么?有没有人知道如何在纯自动布局环境中的UIScrollView中实现属性缩放.在那里的任何地方都有这样的例子吗?

请帮忙.

Mar*_*ski 14

再一次,重新阅读iOS SDK 6.0发行说明,我发现:

请注意,通过在视图和滚动视图子树外部的视图(例如滚动视图的超级视图)之间创建约束,可以使滚动视图的子视图显示为浮动(不滚动)在其他滚动内容上.

将子视图连接到外部视图.换句话说,对于嵌入了scrollview的视图.

并以下列方式应用约束我已经得到了它的工作:

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageView(width)]" options:0 metrics:@{@"width":@(self.imageViewPointer.image.size.width)} views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageView(height)]" options:0 metrics:@{@"height":@(self.imageViewPointer.image.size.height)} views:viewsDictionary]];
Run Code Online (Sandbox Code Playgroud)

  • 这是一个简单的项目,我希望,正如你所期望的那样有效.https://dl.dropbox.com/u/52101940/Test.zip (2认同)

Bre*_*ett 10

出现的问题是在缩放过程中更改imageview的位置.在缩放过程中,imageview的原点位置将变为负值.我相信这就是为什么会发生生涩的运动.同时,缩放完成后的ImageView的仍然是在错误的位置,这意味着滚动会出现偏移.

如果实现-(void) scrollViewDidZoom:(UIScrollView *)scrollView,在此期间日志的UIImageView的框架,你可以看到它的原点改变.

我最终通过实施这样的策略来解决问题

另外在缩放时更改contentView的框架

-(void) scrollViewDidZoom:(UIScrollView *)scrollView {
    CGRect cFrame = self.contentView.frame;
    cFrame.origin = CGPointZero;
    self.contentView.frame = cFrame;
}
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考 - github链接已损坏 (2认同)