隨著 SwiftUI 推出,有些人會問 UIKit 會否被淘汰。答案是:當然還沒有要被淘汰。在 iOS 15 中,Apple 的工程師繼續為 UIKit 推出新功能,其中一個亮點就是 UISheetPresentationController
。這個新類別讓我們只需幾行程式碼,就可以輕鬆創建可擴展的 Bottom Sheet。
如果你不知道什麼是 Bottom Sheet,你可以打開內置的 Maps App 看看。App 會顯示一個 Bottom Sheet,讓使用者執行搜尋和存取保存的位置。Sheet 的大小可以調整,我們也可以拖動 Bottom Sheet 來展開或折疊它。事實上,這種 UI 模式在其他受歡迎的 App 中都很常見,像是 Google Maps、Twitter 和 Instagram。
在這篇教學文章中,我們會看看如何使用 UISheetPresentationController
,並客製化其屬性 (property)。這次的範例 App 非常簡單,只有一個按鈕,點掣按鈕後,App 就會利用 Bottom Sheet 顯示 Web 內容。
利用 UISheetPresentationController 來顯示一個 Bottom Sheet
在 iOS 15 中,UIViewController
有一個名為 sheetPresentationController
的新屬性。對於繼承自 UIViewController
的視圖控制器,我們可以存取其 sheetPresentationController
屬性來檢索 UISheetPresentationController
的實例,以客製化其外觀。
我們可以設置 detents
屬性,來指定 sheetPresentationController
的大小。讓我們看看以下範例,了解一下如何設置 Bottom Sheet 的大小。
let webViewController = WebViewController()
if let sheet = webViewController.sheetPresentationController {
sheet.detents = [ .medium(), .large() ]
}
present(webViewController, animated: true)
WebViewController
類別是 UIViewController
的子類別,因此我們可以從 sheetPresentationController
屬性中檢索 UISheetPresentationController
的實例。
detents
屬性是用來指定 Sheet 的高度陣列。我們可以使用 .medium()
來讓 Sheet 佔據螢幕的一半。如果要以 full height 顯示 Sheet,就可以使用 .large()
detent。
以上的範例程式碼分別使用了 .medium()
和 .large()
detents 屬性。在這種情況下,Sheet 會先佔據螢幕的一半。當我們向上拖動 Web 視圖控制器時,Sheet 就會完全展開。
如果你如此改變值的次序,App 就會先以 full height 顯示 Sheet。
sheet.detents = [ .large(), .medium() ]
客製化 Bottom Sheet 來添加 Grabber
除了控制 Sheet 的大小之外,UISheetPresentationController
類別還提供了許多可以客製化的選項。
比如說,如果我們想在 Sheet 的頂部顯示一個 Grabber,就可以把 prefersGrabberVisible
屬性設為 true
:
sheet.prefersGrabberVisible = true
在顯示 Bottom Sheet 的時候,底層的視圖會自動變暗。如果我們想保持底層視圖的光度,可以把 smallestUndimmedDetentIdentifier
的值設置為 .medium
:
sheet.smallestUndimmedDetentIdentifier = .medium
如此一來,在顯示 Bottom Sheet 時,系統就不會把底層的視圖變暗。
為滾動視圖 (Scroll View) 客製化 Bottom Sheet
如果我們使用 .medium()
尺寸的 Sheet 來顯示可滾動內容,就可能會遇到一個問題。在我們向上滾動內容時,Sheet 也會被展開,這並不是我們想要的效果。我們希望在滾動內容時,Sheet 的大小可以保持不變。
UISheetPresentationController
有一個名為 prefersScrollingExpandsWhenScrolledToEdge
的屬性,就可以解決這個問題了。我們只需要把屬性的值設置為 false
:
sheet.prefersScrollingExpandsWhenScrolledToEdge = false
設置好之後,即使 Sheet 只佔螢幕的一半,我們都可以正常地滾動內容。要展開 Bottom Sheet,就可以向上拖動 Grabber。
客製化圓角半徑 (Corner Radius)
我們可以利用 preferredCornerRadius
屬性,來改變 bottom sheet 的圓角半徑,數值越大,邊角就越圓。
sheet.preferredCornerRadius = 30.0
總結
UIKit 新增的類別 UISheetPresentationController
非常有用,我們不再需要自己實作來顯示 bottom sheet,很簡單就可以在 App 上使用這個漂亮的手機 UI Pattern。
原文:Displaying a Bottom Sheet in iOS 15 Using UISheetPresentationController