ScrollView自動(dòng)布局的實(shí)現(xiàn)方式

背景

開發(fā)中,可能會(huì)有一些頁面顯示的元素很多娘荡,可能會(huì)超出一個(gè)屏幕干旁,但也不適合用 TableView 或者 CollectionView,此時(shí)我們一般會(huì)用 ScrollView炮沐,那么就會(huì)出現(xiàn)自動(dòng)布局的問題争群。

實(shí)現(xiàn)方式

純代碼

特點(diǎn)

  • 編碼繁瑣:需要手寫控件
  • 安全:只要正確地設(shè)置約束或者 frame、contentSize大年,一般不會(huì)出現(xiàn)滾動(dòng)問題

示例

lazy var scrollView: UIScrollView = {
    let obj = UIScrollView(frame: CGRect(x: 0, y: 0, width: .screenW, height: self.screenH))
    return obj
}()
override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(scrollView)
    let subViewH: CGFloat = 400
    let topView = UIView(frame: CGRect(x: 0, y: 0, width: enW, height: subViewH))
    topView.backgroundColor = UIColor.red
    scrollView.addSubview(topView)
    let bottomView = UIView(frame: CGRect(x: 0, y: subViewH, h: screenW, height: subViewH))
    bottomView.backgroundColor = UIColor.purple
    scrollView.addSubview(bottomView)
    
    scrollView.contentSize = CGSize(width: screenW, height: iewH * 2)
}

效果圖

Scrollview_純代碼實(shí)現(xiàn).gif

Storyboard + 內(nèi)部View

特點(diǎn)

  • 搭建界面簡(jiǎn)單
  • 直觀
  • 需要占位視圖

頁面結(jié)構(gòu)如圖

Scrollview_SB_Innerview.png

可能出現(xiàn)的問題

  • ScrollView 中直接添加子元素换薄,報(bào)錯(cuò):Has ambiguous scrollable content height
  • ScrollView 內(nèi)容超出屏幕仍不能滾動(dòng)


    Scrollview_layout_error.png

實(shí)現(xiàn)滾動(dòng)的代碼

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    let statusBarH: CGFloat = 20
    // 如果沒有導(dǎo)航欄,就返回狀態(tài)欄的高度
    let navH = gationController?.navigationBar.frame.maxY ?? statusBarH
    let deltaH = (screenH - navH) - bottomView.frame.maxY
    placeholderViewBottomConstraint.constant = deltaH
}

效果圖

Scrollview_SB+InnerView.gif

Storyboard + 外部View

特點(diǎn)

  • 搭建界面簡(jiǎn)單
  • 直觀
  • 不需要占位視圖翔试,不需要對(duì) ScrollView 的布局做特殊處理
  • 需要處理外部視圖的 frame(如果沒有用戶交互轻要,可以忽略)

頁面結(jié)構(gòu)如圖

Scrollview_SB+OutterView.png

可能出現(xiàn)的問題

  • ScrollView 中直接添加子元素,報(bào)錯(cuò):Has ambiguous scrollable content height
  • 當(dāng)內(nèi)容超出屏幕高度時(shí)垦缅,必須得設(shè)置 ContainerView 的 frame伦腐,否則不能滾動(dòng)或者超出屏幕部分不接受事件


    Scrollview_SB+OutterView_事件問題.png

實(shí)現(xiàn)滾動(dòng)的代碼

override func viewDidLoad() {
    super.viewDidLoad()
    
    scrollView.addSubview(containerView)
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    var f = containerView.frame
    f.size.width = screenW
    // 這句代碼很重要,處理超出屏幕無法響應(yīng)事件問題
    f.size.height = bottomView.frame.maxY
    containerView.frame = f
    scrollView.contentSize = CGSize(width: screenW, height: omView.frame.maxY)
}

效果圖

Scrollview_SB+OutterView.gif

總結(jié)

ScrollView 不能滾動(dòng)的原因

  • contentSize 小于自身 frame 的尺寸
  • isScrollEnabled 屬性失都,不過它默認(rèn)就是 true柏蘑,默認(rèn)無需設(shè)置
  • ScrollView 或者其父元素?zé)o法交互幸冻,此時(shí)我們需要檢查 isUserInteractionEnabled 屬性是否為 true

ScrollView 一直支持滾動(dòng)

默認(rèn)情況下,當(dāng) ScrollView 里的元素不足一個(gè)屏幕高度時(shí)咳焚,不能滾動(dòng)洽损,如需滾動(dòng)(彈簧效果),需要設(shè)置 alwaysBounceVertical 屬性為 true(水平方向亦如此)

關(guān)于 ScrollView 布局的選擇

純代碼布局

如果是純代碼布局革半,只能用方式一碑定。老老實(shí)實(shí)、一行一行代碼實(shí)現(xiàn)布局又官,雖然代碼繁雜延刘,但是坑少。(現(xiàn)在仍有不少公司是這樣編程的)

界面布局

推薦方式三六敬,這樣 ScrollView 和 其子元素分離碘赖,可以簡(jiǎn)化很多約束問題,更直觀

以上代碼外构,適用于 Swift 3.0 語法普泡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市审编,隨后出現(xiàn)的幾起案子撼班,更是在濱河造成了極大的恐慌,老刑警劉巖垒酬,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砰嘁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡勘究,警方通過查閱死者的電腦和手機(jī)般码,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乱顾,“玉大人,你說我怎么就攤上這事宫静∽呔唬” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵孤里,是天一觀的道長伏伯。 經(jīng)常有香客問我审胸,道長雅镊,這世上最難降的妖魔是什么代芜? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任踩萎,我火速辦了婚禮声诸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘袜瞬。我一直安慰自己险毁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布候引。 她就那樣靜靜地躺著侯养,像睡著了一般。 火紅的嫁衣襯著肌膚如雪澄干。 梳的紋絲不亂的頭發(fā)上逛揩,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音麸俘,去河邊找鬼辩稽。 笑死,一個(gè)胖子當(dāng)著我的面吹牛从媚,可吹牛的內(nèi)容都是我干的逞泄。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼静檬,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼炭懊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拂檩,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤侮腹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后稻励,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體父阻,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年望抽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了加矛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡煤篙,死狀恐怖斟览,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辑奈,我是刑警寧澤苛茂,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站鸠窗,受9級(jí)特大地震影響妓羊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜稍计,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一躁绸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦净刮、人聲如沸剥哑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽星持。三九已至,卻和暖如春弹灭,著一層夾襖步出監(jiān)牢的瞬間督暂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來泰國打工穷吮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逻翁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓捡鱼,卻偏偏與公主長得像八回,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子驾诈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容