我想实现UIScrollView
的新方法 ,使用自动布局。 我从内视图滚动视图设置的限制,以便它可以计算自己的contentSize
自动,这就像不同的是,所有的地狱破散时,我尝试放大或缩小charm-。 我甚至不能正确地描述发生了什么,只是说,内部视图被“搞砸了”。
你可以看到此行为的例子在这里 (不是我的项目,你必须设置滚动视图的maximumZoomScale
和实施-viewForZoomingInScrollView:
前缩放将工作)。
有没有其他人遇到这样的行为呢? 有目前没有办法得到一个放大UIScrollView
与自动布局工作,而基本上不重新实现自己的缩放行为?
我见过最好的答案是马克( 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]];
如果没有在故事板添加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;
}
完成斯威夫特游乐场例
我能想到的最简单的例子是加入UIImageView
的UIScrollView
。 这是在代码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()