在介紹UIScrollView滑動之前,我們先需要了解一些概念禀综,首先給大家介紹frame撩满,bounds并鸵。
-(CGRect)frame{
return CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);
}
-(CGRect)bounds{
return CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
}
frame:描述了該視圖在superview坐標(biāo)系統(tǒng)中的位置和大小级零。(顯示大杏实)
bounds:描述了該視圖在其自身坐標(biāo)系中的位置和大小舀瓢。(實(shí)際大型⒀拧)
frame和bounds區(qū)別:
- frame是顯示位置和大小(即可見區(qū)域)京髓,bounds是實(shí)際大小航缀。
- frame是相對于superView坐標(biāo)系,bounds是相對于self坐標(biāo)系(即為自身和subView提供坐標(biāo)系)堰怨。
- 修改bounds原點(diǎn)就是修改self坐標(biāo)系統(tǒng)的原點(diǎn)谬盐,修改bounds原點(diǎn)對frame沒有影響。(比如要同時移動所有 subViews 的話诚些,改 bounds 的 origin 是一個很簡單的辦法飞傀。)
- view的frame和bounds的大小總是一樣的,除非用了transform诬烹。
- 修改transform屬性改變的是frame砸烦,bounds不會變化。比如绞吁,transform旋轉(zhuǎn)后幢痘,frame的大小是其外接矩形的大小。
- 繪制的顯示區(qū)域是這樣:
CompositedPosition.x = View.frame.origin.x - Superview.bounds.origin.x;
CompositedPosition.y = View.frame.origin.y - Superview.bounds.origin.y;
所以修改superview.bounds.origin對顯示區(qū)域有影響家破。frame在superview.bounds.origin在原點(diǎn)的時候才表示可見區(qū)域颜说。
下面我們再來看看UIScrollView的相關(guān)屬性,UIScrollView分解如下圖:
contentSize是內(nèi)容要滾動的區(qū)域大刑(比如圖一的相片大忻欧唷),
contentInset相當(dāng)于內(nèi)容邊距烹困,也就是內(nèi)容視圖邊緣和scrollView的邊緣的留空距離玄妈,通常在需要刷新內(nèi)容時用到(類似android內(nèi)邊距padding,圖一相片四個邊框)髓梅,
contentOffset是內(nèi)容偏移拟蜻,描述了內(nèi)容視圖相對于scrollView窗口的位置(當(dāng)然是向上向左的偏移量)(圖二)
滾動的關(guān)鍵屬性bounds:
bounds確定了顯示區(qū)域大小,相對于UIScrollView的subviews而言枯饿,修改bounds原點(diǎn)就是在修改UIScrollView顯示區(qū)域酝锅。
即,我們可以得出結(jié)論奢方,在UIScrollView的frame和其subViews的frame未變化的情況下搔扁,修改bounds原點(diǎn)就相當(dāng)于在平面上移動這個可視區(qū)域擒权!
而滾動的時候,UIScrollView的frame和其subViews的frame不會變化阁谆。所以改變bounds原點(diǎn)碳抄,就是滾動!
總結(jié):
- UIScrollView由contentInset和contentSize組成场绿。
- bounds大小初始默認(rèn)等于frame大小剖效。
- contentOffset其實(shí)改變的是bounds.origin。
UIScrollView.bounds.origin = contentOffset
- 滾動到底
contentOffset.y = contentSize.height - bounds.size.height;
- UIScrollView坐標(biāo)系原點(diǎn)是從contentSize開始的焰盗;contentOffset表示顯示區(qū)域左上角相對于contentSize坐標(biāo)系的坐標(biāo)璧尸。
- contentOffset的最大和最小值是表示邊界(即邊界觸發(fā)彈性回歸)。
- contentInset屬性擴(kuò)充了滾動區(qū)域熬拒,其改變contentOffset的最大和最小值爷光,即改變了彈性回歸的邊界。比如
contentInset=(10,0,0,0)->offset=-10
澎粟。 - 滾動的理解就是修改bounds屬性蛀序。往上滑:屏幕不變,內(nèi)容往上滑活烙,offset變大徐裸。
彩蛋:
contentInset常常用來擴(kuò)充滾動區(qū)域。
比如設(shè)置tableView底部的Inset避免內(nèi)容被上層遮擋啸盏。
比如tableView下拉刷新重贺,如果你將RefreshUI(刷新控件)放在contentSize,那么彈性回歸將是RefreshUI彈回頂點(diǎn)回懦,而不是Cell气笙。
當(dāng)刷新動作pull-to-refresh初始化時,content inset已經(jīng)被校正過怯晕,所以content offset的最小值包含了完整的refresh control潜圃。當(dāng)刷新完成后,content inset恢復(fù)正常贫贝,content offset也跟著適應(yīng)大小秉犹,自動彈性回歸。這里并不需要為content size做數(shù)學(xué)計(jì)算稚晚。(這里可能比較難理解,建議看看EGOTableViewPullRefresh這樣的類庫就應(yīng)該明白了) UIScrollView滾動原理和contentInset原理(裝載)
此文到此結(jié)束型诚,文中圖片來源引用客燕!
請繼續(xù)關(guān)注下文,《深入UIScrollView系列二(滑動事件)》