iOS - UIScrollView的聯(lián)動反饋效果實現(xiàn)


UX的核心是在幫助用戶理解應用的同時提供更愉悅的使用體驗


環(huán)境:

  • Xcode 8.3.1
  • Swift 3

目錄

  • demo
  • 關鍵點
  • Storyboard的設置
  • 代碼
  • 總結

(簡書不支持頁內(nèi)跳轉(zhuǎn),這是個雞肋目錄 = =)

demo

demo

UIScrollView及其子類UITableView, UICollectionView是app里經(jīng)常用到的視圖組件蘸鲸。iOS自帶的反彈特性提供了不錯的反饋信息。結合實現(xiàn)滑動相關的delegate吆视,我們可以構建出多種交互反饋,給用戶提供更明白又眼前一亮的效果酥宴。

以下展示一個通過滑動scroll view,與標題圖片進行聯(lián)動反饋的例子您觉。這個反饋效果在很多App里都很普遍拙寡。其實在大半年前我就寫過一篇博客分享同樣效果的實現(xiàn)方法。后面積累了些項目經(jīng)驗后琳水,發(fā)現(xiàn)有更簡潔且穩(wěn)妥的實現(xiàn)方式肆糕,同時開始轉(zhuǎn)用Swift。在此推薦一波Swift在孝,相對OC而言诚啃,Swift提供了更多實用的語言特性,寫法也比OC簡潔不少私沮。

<p id="keys"></p>

關鍵點

  • UIImageView:
    • height屬性跟隨UIScrollView的滑動而線性變化
    • contentMode屬性設定為UIViewContentModeScaleAspectFill
  • UIScrollView:
    • 初始contentInset屬性的height設定為UIImageView對象的height

<p id="storyboard"></p>

Storyboard的設置

雖然標題圖片與scroll view孰上孰下都會是同樣的視覺效果始赎,不過要想標題圖片可以點擊,建議將其image view放在上層仔燕,如圖:

視圖層級

為了使例子更清楚造垛,這里使用table view,scroll view和其他子類同理

設定Auto Layout的約束:

  • image view: 上晰搀、左五辽、右貼邊,并添加高度約束外恕,數(shù)值隨意杆逗,反正需要在代碼初始化并聯(lián)動更改
  • table view: 上、下鳞疲、左罪郊、右貼邊

具體如圖:


image view的constraints
table view的constraints
整體效果

需要注意的是,image view需要設定:

  • contentMode = .scaleAspectFill建丧,讓image view根據(jù)最短一邊來等比放大和縮放
  • isUserInteractionEnabled = true
  • clipsToBounds = true (不設定的話會出現(xiàn)即使image view高度為0但image依舊會展示的效果)
  • 這里image view會擋住下面table view的cell的設計排龄。可以在設計時先把table view放在上層,完了再放回下面橄维,拖一下鼠標的事情

<p id="code"></p>

代碼

最開心的進入代碼的時刻來了~慣常把image view和table view的引用拉到view controller里來尺铣。同時,把image view的height約束也拉過來:

var bannerImageViewDefaultHeight: CGFloat {
    return UIScreen.main.bounds.width * 1 / 2
}

@IBOutlet weak var bannerImageView: UIImageView!

@IBOutlet weak var tableView: UITableView! {
    didSet {
        tableView.delegate = self
        tableView.dataSource = self
        tableView.estimatedRowHeight = 40.0
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.contentInset = UIEdgeInsetsMake(bannerImageViewDefaultHeight, 0.0, 0.0, 0.0)
    }
}

@IBOutlet weak var bannerImageViewHeightConstraint: NSLayoutConstraint! {
    didSet {
        bannerImageViewHeightConstraint.constant = bannerImageViewDefaultHeight
    }
}

以上代碼的幾個要點:

  • 這里想要標題圖片的高度是屏幕寬度的一半争舞,于是利用computed屬性bannerImageViewDefaultHeight返回
  • 設定標題圖片的高度約束bannerImageViewHeightConstraint凛忿。為什么是使用約束更改高度?下文會詳解說明
  • 設定table view的contentInset為上端inset為初始標題圖片的高度竞川,好讓table view的內(nèi)容剛好在標題圖片下方開始展示
  • didSet里的代碼在對象引用設定后會調(diào)用店溢,在didSet之前,我們一般在viewDidLoad里設定視圖組件的屬性委乌。使用didSet可以使設定代碼與對應的組件更緊湊床牧,便于閱讀。關于Swift的不同屬性的解釋請戳此
  • estimatedRowHeight的值影響table view對content高度的初步計算遭贸,從而影響右側(cè)scrolling indicator的精確度戈咳;rowHeight = UITableViewAutomaticDimension是讓table view開啟利用Auto Layout計算layout的功能,據(jù)說蘋果在iOS 11里對table view進行了優(yōu)化壕吹,rowHeight不再需要人手設定而隱式開啟使用Auto Layout著蛙。具體有待考證。

設定滑動的聯(lián)動反饋效果:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let offsetY = scrollView.contentOffset.y
    bannerImageViewHeightConstraint.constant = offsetY < 0.0 ? -offsetY : 0.0
}

超級實用的scrollViewDidScroll(_:)排上用場啦~scroll view往下滑動的contentOffset.y是減小耳贬,當添加大于0的上端inset踏堡,長度為bannerImageViewDefaultHeight時,初始的contentOffset.y會是-bannerImageViewDefaultHeight咒劲。

這里說下為什么改約束而不是直接改image view的frame呢顷蟆?我曾經(jīng)也習慣直接改frame,簡單快捷缎患,不需要額外拉一條約束的引用進入view controller慕的。但在我看完realm的一篇分享之后,關于之前遇到的view的一些奇怪行為恍然大悟挤渔。

簡單來說就是肮街,在iOS的定義里,Auto Layout相當于一系列視圖組件的布局規(guī)則判导。當我們在代碼里直接更改frame時嫉父,我們是在Auto Layout之外進行操作。那么問題來了眼刃,系統(tǒng)的一些特定事件會觸發(fā)布局系統(tǒng)重新讀取我們設定在視圖組件上的一系列約束绕辖,
這就意味著我們更改的frame會被重置,而這也許不是我們想要的結果擂红。因此我現(xiàn)在的偏好是仪际,如果用了Auto Layout做布局,代碼里針對view的布局更改甚至一些動畫都通過修改約束來進行,這樣當特定事件出現(xiàn)時树碱,視圖組件的布局會維持原樣肯适。那么,有哪些系統(tǒng)特定事件呢成榜?如下:

  • 鍵盤的彈出與收回
  • 手機豎屏與橫屏的切換
  • 視圖組件或其父視圖組件調(diào)用layoutIfNeeded()時 (其實這是根本)

<p id="conclusion"></p>

總結

scrollViewDidScroll(_:)是可以實現(xiàn)很多有趣的滑動反饋的開始框舔。對不同應用,應該根據(jù)實際來實現(xiàn)合適的用戶體驗反饋赎婚。
完整代碼已上傳至個人Github刘绣。傳送請戳此

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市挣输,隨后出現(xiàn)的幾起案子纬凤,更是在濱河造成了極大的恐慌,老刑警劉巖撩嚼,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件移斩,死亡現(xiàn)場離奇詭異,居然都是意外死亡绢馍,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門肠套,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舰涌,“玉大人,你說我怎么就攤上這事你稚〈砂遥” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵刁赖,是天一觀的道長搁痛。 經(jīng)常有香客問我,道長宇弛,這世上最難降的妖魔是什么鸡典? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮枪芒,結果婚禮上彻况,老公的妹妹穿的比我還像新娘。我一直安慰自己舅踪,他們只是感情好纽甘,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抽碌,像睡著了一般悍赢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天左权,我揣著相機與錄音皮胡,去河邊找鬼。 笑死涮总,一個胖子當著我的面吹牛胸囱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瀑梗,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼烹笔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了抛丽?” 一聲冷哼從身側(cè)響起谤职,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎亿鲜,沒想到半個月后允蜈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡蒿柳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年饶套,在試婚紗的時候發(fā)現(xiàn)自己被綠了垒探。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妓蛮。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖圾叼,靈堂內(nèi)的尸體忽然破棺而出构挤,到底是詐尸還是另有隱情箱歧,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布驼鹅,位于F島的核電站微谓,受9級特大地震影響森篷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜豺型,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一仲智、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧姻氨,春花似錦钓辆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至娶眷,卻和暖如春似嗤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背届宠。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工烁落, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人豌注。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓伤塌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親轧铁。 傳聞我的和親對象是個殘疾皇子寸谜,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

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