UIScrollView的带自动变焦布局(UIScrollView zooming with Aut

2019-07-17 13:55发布

我想实现UIScrollView的新方法 ,使用自动布局。 我从内视图滚动视图设置的限制,以便它可以计算自己的contentSize自动,这就像不同的是,所有的地狱破散时,我尝试放大或缩小charm-。 我甚至不能正确地描述发生了什么,只是说,内部视图被“搞砸了”。

你可以看到此行为的例子在这里 (不是我的项目,你必须设置滚动视图的maximumZoomScale和实施-viewForZoomingInScrollView:前缩放将工作)。

有没有其他人遇到这样的行为呢? 有目前没有办法得到一个放大UIScrollView与自动布局工作,而基本上不重新实现自己的缩放行为?

Answer 1:

我见过最好的答案是马克( https://stackoverflow.com/users/1051919/mark-kryzhanouski ),张贴在这里: UIScrollView的变焦不工作,自动布局 。

它的关键是,你必须锚定嵌套在滚动视图,滚动视图的父级的图像视图。 尽管在iOS 6的发布说明的指导,它不是直观的对我有什么看法“浮动”过什么。 在这种情况下,滚动视图仅仅是一个单一的图像视图。

我做了很多与此实验,希望能找到一个全IB办法找不着。 您还可以生成IB视图层次,但你还是要编程添加约束。 您可以删除某些或所有的默认约束(主要只是为了安抚约束冲突警告),但你总是需要标记的代码图像视图配合滚动视图,图像视图的盛大母公司的母公司。

现在看来似乎应该比这个更简单 - 它“应该只是工作”,但是:

NSDictionary *viewsDictionary = @{ @"scrollView": self.scrollView, @"imageView": self.imageView };
[self.view addConstraints:[NSLayoutConstraint
    constraintsWithVisualFormat:@"H:|[imageView(width)]"
    options:0
    metrics:@{@"width": @(self.imageView.image.size.width)}
    views:viewsDictionary]];

[self.view addConstraints:[NSLayoutConstraint
    constraintsWithVisualFormat:@"V:|[imageView(height)]"
    options:0
    metrics:@{@"height": @(self.imageView.image.size.height)}
    views:viewsDictionary]];


Answer 2:

如果没有在故事板添加ImageView的,我发现了以下工作完美:

-(UIImageView *)imageView
{
    if (!_imageView) _imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
    return _imageView;
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.scrollView addSubview:self.imageView];
    // Set the min and max:
    self.scrollView.minimumZoomScale = 0.2;
    self.scrollView.maximumZoomScale = 5.0;
    self.scrollView.delegate = self;

    // Set the content:
    self.scrollView.zoomScale = 1.0; // reset zoomScale for new image
    self.scrollView.contentSize = CGSizeMake(image.size.width/2, image.size.height/2);
    self.imageView.frame = CGRectMake(0, 0, image.size.width/2, image.size.height/2);
    self.imageView.image = image;
}

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


Answer 3:

完成斯威夫特游乐场例

我能想到的最简单的例子是加入UIImageViewUIScrollView 。 这是在代码100%,你只需要一个PNG添加到游乐场。 我打电话给我的Image.png 。 在游乐场,你会看到在“实时查看”渲染了整个事情。 捏缩放功能使用Ctrl键单击在屏幕上放置一个手指,然后拖动鼠标。 直到内容在缩放比屏幕大淘洗将无法正常工作。 点击两下图像1X和3倍的规模之间进行切换。

基于苹果公司的技术说明TN2154:UIScrollView中和自动布局

疑难杂症

你会发现整个事情很令人沮丧,如果你的内容并不比屏幕尺寸更大。 如果您的内容上完全符合屏幕什么都不会发生。 这就是为什么你必须得到放大工作过。 如果你想证明自己它的工作原理,测试与真正的大图像(比窗口更大)。

import UIKit
import PlaygroundSupport

enum TapToggle {
    case Regular, Large
}

class ScrollingViewController : UIViewController
{
    var tapToggle: TapToggle = .Large
    var scrollView: UIScrollView?
    var imageView: UIImageView?

    override func viewDidLoad()
    {
        let image = UIImage(named: "Image")
        let imageView = UIImageView(image: image)
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .white
        imageView.isUserInteractionEnabled = true

        let scrollView = UIScrollView()
        scrollView.minimumZoomScale = 0.5
        scrollView.maximumZoomScale = 10.0
        scrollView.delegate = self
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.addSubview(imageView)
        let imageViewKey = "imageView"
        let imageViews = [imageViewKey: imageView]
        scrollView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[\(imageViewKey)]|", options: [], metrics: nil, views: imageViews))
        scrollView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[\(imageViewKey)]|", options: [], metrics: nil, views: imageViews))
        self.imageView = imageView

        scrollView.backgroundColor = .white
        self.view.addSubview(scrollView)

        let scrollViewKey = "scrollView"
        let scrollViews = [scrollViewKey: scrollView]
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[\(scrollViewKey)]|", options: [], metrics: nil, views: scrollViews))
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[\(scrollViewKey)]|", options: [], metrics: nil, views: scrollViews))

        self.scrollView = scrollView

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didDoubleTap(sender:)))
        tapGesture.numberOfTapsRequired = 2
        self.imageView?.addGestureRecognizer(tapGesture)
    }

    @objc
    public func didDoubleTap(sender: AnyObject)
    {
        switch self.tapToggle {
        case .Regular:
            self.scrollView?.zoomScale = 1.0
            self.tapToggle = .Large
        case .Large:
            self.scrollView?.zoomScale = 3.0
            self.tapToggle = .Regular
        }
    }
}

extension ScrollingViewController: UIScrollViewDelegate
{
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return self.imageView
    }

    func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat)
    {
        print("\(scale)")
    }
}

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = ScrollingViewController()


文章来源: UIScrollView zooming with Auto Layout