ScrollView学习笔记 -Part5
最后更新于:2022-04-01 04:57:56
> 原文:http://www.swiftyper.com/Swift/scrollviewpart5.html
# ScrollView学习笔记 - Part5
在前面的几个小节当中,都是使用代码来实现`ScrollView`的功能,其实,我们也可以在`Interface Builder`当中来使用它。
## 简单使用
如果要实现与前面一样的功能,在一个`ScrollView`当中滚动一张图片,使用`StoryBoard`来实现是相当容易的。
1. 拖一个`ScrollView`到`StoryBoard`上面,并将其约束到屏幕的四个边
2. 拖一个`ImageView`作为`ScrollView`的子视图,同样设置约束到四边
3. 设置`ImageView`的图片,因为图片会使`ImageView`撑开与图片大小相等,这相当与设置了`ScrollView`的`contentSize`
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-19_564d4466c2eaa.png)
通过上面三步,就可以实现图片的滚动了,相当简单。
## 多个视图的滚动
前面那个是最简单的情形,当然很多情况下,我们需要设计的界面比那个要复杂得多,不过,也是可以使用`Interface Builder`来实现的。
只需要在`Simulated Metrics`中选择`Size`为`Freeform`,然后我们就可以自由设置高度与宽度了,注意要将`ScrollView`的约束设置到四个边,就可以进行界面的设计了。虽然我们自己选择了设备的宽和高,但是我们的手机屏幕当然不会因为我们设置的宽和高而改变,所以实际运行的时候,进出手机屏幕的部分,就会使用滚动来呈现了。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-19_564d4466daeb8.png)
这样就可以使用`Interface Builder`来使用`ScrollView`了,也是相当easy的。
## 总结
这小节学习了如何使用`Interface Builder`来创建`ScrollView`,主要就是设置好`ScrollView`的约束,然后选择自由尺寸来对界面进行设计。
ScrollView学习笔记 -Part4
最后更新于:2022-04-01 04:57:54
> 原文:http://www.swiftyper.com/Swift/scrollviewpart4.html
# ScrollView 学习笔记 - Part4
前一节学了`ScrollView`当中的缩放,不过那个缩放实现得并不完美,因为缩放过后,图片只会静静地呆在屏幕的一边,一般情况,我们希望缩放后的图片能够居中。
要实现居中,其实并不复杂,我们只需要计算出`ScrollView`与`ImageView`的宽与高的差值,然后再除以2就可以算出补白的间距。如图:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-19_564d44665fe40.png)
有了这个补白的间距,我们就可以设置`ImageView`的`frame`来设置它的位置,使其居中。
还有另一个方法是设置`ScrollView`的`ContentInset`,也能实现居中。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-19_564d44668a29a.png)
## 实现居中
可以实现下面这个方面用来对缩放后的`View`进行居中:
~~~
private func recenterImage() {
let scrollViewSize = scrollView.frame.size
let imageSize = imageView.frame.size
let horizontalSpace = imageSize.width < scrollViewSize.width ?
(scrollViewSize.width - imageSize.width) / 2 : 0
let verticalSpace = imageSize.height < scrollViewSize.height ?
(scrollViewSize.height - imageSize.height) / 2 : 0
scrollView.contentInset = UIEdgeInsets(top: verticalSpace, left: horizontalSpace, bottom: verticalSpace, right: horizontalSpace)
}
~~~
在`ViewDidLoad`、`viewWillLayoutSubviews`与`scrollViewDidZoom`当中调用这个方法,就能实现缩放后的图片居中了。
## 屏幕旋转后图片位置发生变化
当我们将图片放大后对屏幕进行旋转,会发现,图片的中心发生了改变,不在原本的位置。这是因为虽然`ScrollView`的`contentOffset`没有变化,但是由于屏幕的大小改变了,会影响到中心位置,所以我们可以看到图片的位置发生了变化。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-19_564d4466a594f.png)
要解决这个问题,我们需要在屏幕旋转前记录中心点的位置,然后在旋转后,再根据这个中心点的位置来设置`contentOffset`,这样就能保证旋转前后的中心在同一个位置。我们可以在一个方法中完成所有的这些工作:
~~~
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
// 计算中心点
let centerPoint = CGPoint(x: scrollView.contentOffset.x + CGRectGetWidth(scrollView.bounds) / 2,
y: scrollView.contentOffset.y + CGRectGetHeight(scrollView.bounds) / 2)
// 设置旋转后的中心位置
coordinator.animateAlongsideTransition({ (context) -> Void in
self.scrollView.contentOffset = CGPoint(x: centerPoint.x - size.width / 2, y: centerPoint.y - size.height / 2)
}, completion: nil)
}
~~~
`viewWillTrnsitionToSize(_:withTransitionCoordinator:)`是iOS 8中的新方法,这个方法可以让你屏幕旋转的时候对view进行一些操作,其中的`size`参数是旋转后的view的大小。经过这样的处理之后,旋转前后的中心都会在同一个位置了。
## 总结
这小节主要是对缩放的效果进行了一些小的优化,使它看起来不至于太山寨,主要是一些计算的东西,只要想通了也就不困难了。
ScrollView学习笔记 -Part3
最后更新于:2022-04-01 04:57:52
> 原文:http://www.swiftyper.com/Swift/scrollviewpart3.html
# ScrollView 学习笔记 - Part3
`ScrollView`的第二个基本功能就是“缩放”。
要实现缩放也很简单,只需要两个步骤:
## 实现委托
要实现缩放,需要实现
~~~
viewForZoomingInScrollView:
~~~
这个委托方法,在这个方法中返回需要进行缩放的`ScrollView`的子视图。
## 设置缩放级别
设置缩放的最大和最小级别:
~~~
scrollView.minimumZoomScale = 0.1
scrollView.maximumZoomScale = 3.0
scrollView.zoomScale = 1.0
~~~
只要以上两个步骤就可以实现缩放了,不过,如果只是单纯设置了最小缩放级别,可能会由于缩放得太小,导致屏幕有很多的空白十分难看。所以,我们最好根据`ScrollView`的大小来计算出最小的缩放级别。
~~~
private func setZoomParamatersForSize(scrollViewSize: CGSize) {
let imageSize = imageView.bounds.size
let widthScale = scrollViewSize.width / imageSize.width
let heightScale = scrollViewSize.height / imageSize.height
let minScale = min(widthScale, heightScale)
scrollView.minimumZoomScale = minScale
scrollView.maximumZoomScale = 3.0
scrollView.zoomScale = minScale
}
~~~
同时,为了保证在屏幕方向变化的时候,缩放级别也能改变,还得实现这个方法:
~~~
override func viewWillLayoutSubviews() {
setZoomParamatersForSize(scrollView.bounds.size)
}
~~~
## 其它委托方法
除了`viewForZoomingInScrollView:`,在`ScrollView`的委托方法中,还有两个与缩放有关:
~~~
scrollViewDidZoom:
scrollViewDidEndZooming:
~~~
## 总结
在`ScrollView`当中,实现缩放也是相当容易的,主要还是设置缩放级别来适应`ScrollView`这点比较重要,其它都是很直观的。
ScrollView学习笔记 -Part2
最后更新于:2022-04-01 04:57:49
> 原文:http://www.swiftyper.com/Swift/scrollviewpart2.html
# ScrollView 学习笔记 - Part2
`ScrollView`最基本的功能当然就是“滚动”啦。
要实现`ScrollView`的滚动功能很简单,只需要三个步骤:
## 子视图
设置`ScrollView`的子视图,一般情况下,这个视图要比`ScrollView`来得大,不然我们也就不需要滚动啦
## ContentSize属性
设置`ScrollView`的`ContentSize`属性,这个属性用来指定需要滚动的内容的大小,即使你设置的子视图比`ScrollView`大,但是如果这个属性没有设置的,依然还是不能滚动的
## ContentOffset属性
设置`ScrollView`的`ContentOffset`属性,在前一小节中,学习过了`Bounds`属性,我们知道可以直接设置`Bounds`属性的位置来展现不同区域的内容,但是因为这个功能在`ScrollView`当中太常用了,所以系统直接为我们直接了一个更加方便的属性来直接进行控制。
来张图加深下理解
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-19_564d44661ad94.png)
## ScrollView的委托
按照苹果的设计模式,如果想监听到`ScrollView`的事件,当然要实现它的委托了。
`ScrollView`的委托事件有相当多,对于滚动来说最重要的一个是:
~~~
scrollViewDidScroll(_:)
~~~
这个委托会在`ScrollView`的内容进行滚动的时候被调用,我们可以在里面监听到它当前的`ContentOffset`。
其它的还有:
~~~
scrollViewWillEndDragging(_:withVelocity:targetContentOffset:)
scrollViewDidScrollToTop(_:)
scrollViewDidEndDecelerating(_:)
// ...
~~~
## 总结
使用`ScrollView`来对内容进行滚动其实是很简单的,只要记好三个步骤就行了,更加高级的内容再慢慢学习来。
ScrollView学习笔记 -Part1
最后更新于:2022-04-01 04:57:47
> 原文:http://www.swiftyper.com/Swift/scrollviewpart1.html
# ScrollView 学习笔记 - Part1
`ScrollView`在iOS当中可谓是无处不在,从锁屏画面的滑动解锁到手机的APP列表界面都用到了`ScrollView`,同时它还是两相重量级控件`TableView`以及`CollectionView`的父类。
所以它可以说是相当有分量的一个控件,有必要进行一下系统的学习。
然而在学习`ScrollView`之前,必须要对一个`View`的`Frame`和`Bounds`有清晰的认识,因为这两个属性是理解`ScrollView`的基础。
## Frame
`Frame`指的是一个view以**父视图**的坐标系统为参考系的位置和大小。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-19_564d445f8b9ea.png)
所以图中绿色view的`Frame`的位置是`(60, 80)`,长和宽都为200.
## Bounds
`Bounds`指的是一个view以**自身**的坐标系统为参考系的位置和大小。
事实上,因为`Bounds`始终以自身的坐标系为参考,所以它的位置永远都是`(0, 0)`, 听起来很奇怪,既然它永远是0,我们还要`Bounds`做什么,一个`Frame`不就够了么。表面上,`Bounds`是确实是多余的没错,但是当我们开始改变一个view的`Frame`与`Bounds`的位置的时候,我们就可以听到其中的差别了。
## 改变Frame
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-19_564d446533a46.png)
图中,白色view的`Frame`位置是`(0, 0)`,当我们将它设置为`(60, 80)`的时候,整个view会向右下方移动,这个是比较直观的。
## 改变Bounds
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-19_564d4465e02bc.png)
但是,当我们改变view的`Bounds`的时候,它看起来好像是将`Frame`的位置设置为负数一样,因为它看起来整个view都向左上方跑了,但是事实不是这样的,它整个view的位置都没有改变,而是view里面的内容,不再是从`(0, 0)`的位置开始显示,变成了从`(60, 80)`的位置开始显示,所以左上的部分没有显示在屏幕里面。
这跟`ScrollView`的原理是类似的,当我们“滚动”的时候,我们只是改变了屏幕里显示的内容而已。
## 总结
`Frame`和`Bounds`是比较容易造成混淆,区别它们的不同点,对于理解`ScrollView`的原理有很大的帮助。在感到困惑的时候,可以画下草图来帮忙理解。