客製化長相的UITabBarController

更新於 2024/01/05閱讀時間約 9 分鐘

雖然我之前文章大力讚美SwiftUI的tabView有多好用,無奈專案大部分都是UIKit啊~~~~要在既有專案用Tab架構只能用UITabBarController了

設計這次還出了一個超複雜的UI,陰影+圓角+客製化高度 大套餐

馬上開始吧。

圓角+陰影

圓角+陰影很簡單,高度很難🥹

圓角+陰影很簡單,高度很難🥹


重點就是subclass一個UITabController 並去更改tabBar UI

也有人會在viewWillLayoutSubviews()或viewDidLayoutSubviews()去進行。

class MyTabController: UITabBarController {
func viewDidLoad() {
super.viewDidLoad()
setupTabBarUI()
}   

func setupTabBarUI() {
self.tabBar.backgroundColor = .white
self.tabBar.tintColor = .grayself.tabBar.layer.cornerRadius = 10
self.tabBar.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
self.tabBar.clipsToBounds = true
self.tabBar.layer.masksToBounds = false
self.tabBar.layer.shadowColor = UIColor.black.cgColor
self.tabBar.layer.shadowOpacity = 0.2
// 陰影要這樣畫,不然會太耗效能
self.tabBar.layer.shadowPath = UIBezierPath(roundedRect: self.tabBar.bounds, cornerRadius: 10.0).cgPath
}
}

陰影NG作法

研究的時候,發現有些人的作法是在TabBar後面墊一塊UIView當陰影。這個方法如果TabBar永恆存在的話沒問題,但有些動線需要push後隱藏Tab的話,官方提供的hidesBottomBarWhenPushed只會幫你隱藏TabBar本身,多墊的那塊UIView就要另外再處理,我覺得很不方便,不推薦。

高度

那如何更改高度呢?在網路上有查到2017年的答案StackOverflow是在viewWillLayoutSubviews去更改高度,但我用已經無效了。

我的作法是建立一個CustomTabBar,改他的高度。

class CustomTabBar: UITabBar {    
override func sizeThatFits(_ size: CGSize) -> CGSize {
var sizeThatFits = super.sizeThatFits(size)
sizeThatFits.height = 98
return sizeThatFits
}

然而使用自定義的Tabbar意外的困難,override tabBar屬性也沒反應(NG作法)

class MyTabController: UITabBarController {
// 沒有變高
override var tabBar: UITabBar {
return customTabBar
}
}

後來查到要使用object_setClass在runtime時把tabBar改掉。apple真的很難搞耶🧐

class MyTabController: UITabBarController {
init() {
super.init(nibName: nil, bundle: nil)
object_setClass(self.tabBar, CustomTabBar.self)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

成品

raw-image

同場加映:小紅點

原生提供的小紅點是有數字的

vc1.tabbarItem.badgeValue = "1"
raw-image


如果設計想要純小紅點怎麼辦??

有一種邪魔歪道(?的作法是,用同上方法,但不放數字

vc1.tabbarItem.badgeValue = ""
raw-image


雖然可以出現紅點,但整個大的不可思議,而且因為客製化高度,位置也跑掉。

增加客製化的小紅點

先做一個列出所有Tab的enum

enum V2TabBarItem {
case tab1
case tab2
case tab3

// badge tag要不同,新增移除時不會互相干擾
var badgeTag: Int {
switch self {
case .tab1:
return 6543
case .tab2:
return 6542
case .tab3:
return 6541
}
}

}

增加小紅點

private func addRedDotAtTabBarItem(tab: V2TabBarItem) {
guard let index = tabs.firstIndex(of: tab) else { return }
removeRedDotAtTabBarItem(tab: tab)
let radius: CGFloat = 5
let diameter = radius * 2
let topMargin:CGFloat = 17
let tabBarItemCount = CGFloat(tabBar.items?.count ?? 0)
let screenSize = UIScreen.main.bounds
let halfItemWidth = (screenSize.width) / (tabBarItemCount * 2)
let xOffset = halfItemWidth * CGFloat(index * 2 + 1)
let imageHalfWidth: CGFloat = ((tabBar.items?[index])?.selectedImage?.size.width ?? 0) / 2
// 離tab icon距離可自行調整
let redDot = UIView(frame: CGRect(x: xOffset + imageHalfWidth/2 + 3, y: topMargin, width: diameter, height: diameter))
redDot.tag = tab.badgeTag
redDot.backgroundColor = UIColor.red
redDot.layer.cornerRadius = radius
tabBar.addSubview(redDot)
}

移除小紅點

private func removeRedDotAtTabBarItem(tab: V2TabBarItem) {
for subview in tabBar.subviews {
if subview.tag == tab.badgeTag {
subview.removeFromSuperview()
break
}
}
}

加!!!!!

加在viewDidLoad裡會沒反應,我覺得應該是太快了tabBar UI還沒ready,我是選擇加在ViewDidAppear裡

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
addRedDotAtTabBarItem(tab: .tab1)
}
VC生命週期

VC生命週期

成品

raw-image







avatar-img
7會員
35內容數
紀錄iOS開發上遇到的問題或是一些流程筆記。主要都是Swift。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Michelle Chen的沙龍 的其他內容
Sandbox 架構 /Documents:主要用於儲存用戶生成的數據或者不能重新創建的數據。這些可能包括由你的應用程式創建的文件、從服務器下載的文件、用戶在應用程式中創建或修改的數據等。 這些數據在應用程式的生命週期中是持久保存的,即使應用程式被終止或者系統重啟,這些數據也會保留。此外
SwiftUI的TabView實在太好用啦!我要大大的推廣他ლ(╹◡╹ლ) 換頁+小圓點滑動 無限自動輪播 底部Tabbar
這個浮誇標題是ChatGPT幫我想的😊 圖也是DALL幫我產的, AI萬歲! GCD也是面試必問題啊!我答超爛的,只會用背景呼叫API+切Main Thread更新畫面,今天就來認真了解。 GCD是什麼? 先來問ChatGPT什麼是GCD? GCD,全名 Grand Central Dis
字數算法 = string.count? 在swift算一個string的字數時候,很直覺的會想到用.count來算 let s = "這是幾個字呢".count print(s.count) // 6 毫無疑問的安心信賴6個字 表情符號的場合 let emoji = "😂" print
Xcode15的 @escaping closure裡解包後的[weak self]不必再寫 self了!! 用一個範例class Test來實驗,裡面只有一個變數a跟一個testClosure回"test",再用callTestClosure把變數a改成"test" 編譯正常!變數a成功被改成
一樣先來看官方文件 A view controller that provides access to documents or destinations outside your app’s sandbox. 其實就是讓你去讀取檔案App的東西 有兩種模式,Don’t copy the do
Sandbox 架構 /Documents:主要用於儲存用戶生成的數據或者不能重新創建的數據。這些可能包括由你的應用程式創建的文件、從服務器下載的文件、用戶在應用程式中創建或修改的數據等。 這些數據在應用程式的生命週期中是持久保存的,即使應用程式被終止或者系統重啟,這些數據也會保留。此外
SwiftUI的TabView實在太好用啦!我要大大的推廣他ლ(╹◡╹ლ) 換頁+小圓點滑動 無限自動輪播 底部Tabbar
這個浮誇標題是ChatGPT幫我想的😊 圖也是DALL幫我產的, AI萬歲! GCD也是面試必問題啊!我答超爛的,只會用背景呼叫API+切Main Thread更新畫面,今天就來認真了解。 GCD是什麼? 先來問ChatGPT什麼是GCD? GCD,全名 Grand Central Dis
字數算法 = string.count? 在swift算一個string的字數時候,很直覺的會想到用.count來算 let s = "這是幾個字呢".count print(s.count) // 6 毫無疑問的安心信賴6個字 表情符號的場合 let emoji = "😂" print
Xcode15的 @escaping closure裡解包後的[weak self]不必再寫 self了!! 用一個範例class Test來實驗,裡面只有一個變數a跟一個testClosure回"test",再用callTestClosure把變數a改成"test" 編譯正常!變數a成功被改成
一樣先來看官方文件 A view controller that provides access to documents or destinations outside your app’s sandbox. 其實就是讓你去讀取檔案App的東西 有兩種模式,Don’t copy the do
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
帶大家來開箱「Google 商業智慧專業證照」證照課程!快來點開看看!
Thumbnail
🔗https://edjump.pse.is/54meaw 今天的來賓劉柏楊TK,為TKS FULL HOUSE 提克斯國際餐飲的創始人,他在高雄從事餐飲業已經超過11年。TK提供我們關於餐飲業競爭性質的見解,以及從酒吧業務開始轉型經營成功的外送公司的個人經歷。
Thumbnail
您是學生或公司行號正在為團服或公司制服所煩惱嗎?幾何學幫您整理了關於客製化團服、公司制服或團體服設計與材質,還有最重要的價格估算,讓您對於客製化團體服有更全面的認識,快來看看幾何學精心撰寫的內容吧! 客製化衣服怎麼製作?衣服設計流程大公開! https://www.geometrytaiwan.co
Thumbnail
記得先點+追蹤喔❤️ 【復刻未來・AI 海洋名畫特展】 活動期間:2022/10/5 ~ 2023/3/31 票價資訊:Xpark 門票
Thumbnail
近來好嗎?感謝老天為我們下了場雨,即時讓這週的各地水庫有進帳。 您好,這是一則每週日晚上都會為您親自撰寫的一封信,來自銀色大門的一封信。 在這封信裡,您能夠知道銀色大門在成長、服務長輩等面向的細節, 為的就是邀請您可以一起參與服務長輩和創造台灣銀髮產業革命!
Thumbnail
台灣有許多店家取名都有它必然與因緣際會而成為這家店的名字。長春二號飯盒專賣店就是如此店家,該店家靠近中山捷運站附近,地址在台北市中山區長春路二號,因為門牌地址就取了這個長春二號店名。 長春二號相關資訊:: 地址: 台北市中山區長春路2號 電話: 02 2581 5508 營業時間:
Thumbnail
   今天要分享給大家的這幅作品,是我們在紐約的布魯克林大橋上創作的,所以我們在背景加上了當時的景色,給畫中的情侶留下一份獨特的回憶.   今天我們要介紹的就是這畫中的背景,在紐約的布魯克林大橋.
Thumbnail
HI~Whoscake今天來跟大家分享一下常見的幾種2020年最特別的生日蛋糕推薦類別 以上是我個人2020年生日蛋糕精選又不負任何責任的評論,看完文章的人感謝你的耐心。大家都可以在下方跟我多多討論唷,這樣我才有更多方向去挖掘美食!
Thumbnail
人生事業 愛情皆轉轉轉!http://www.6995.com.tw哈哈哈哈哈!轉運了!邱允文和邱吉爾在生日禮物結婚禮物客製化商品-天藏地酒1月25日上午2:25 · 台中市 · 「邱允文」的圖片搜尋結果邱允文和邱吉爾在生日禮物結婚禮物客製化商品-天藏地酒邱允文 阿拉丁創客團隊 免費
Thumbnail
邱允文– 阿拉丁瓶雕刻生日禮物結婚禮物國立臺中科技大學 ...2019年5月23日 - 邱允文國立臺中科技大學『回憶只會越來越淡,直至它已烙印在你心深處。 ... 天貓商行酒瓶雕刻生日禮物結婚禮物台中客製化商品- YouTube客製化商品台中- 邱允文阿拉丁創客團隊  http://www.6995
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
帶大家來開箱「Google 商業智慧專業證照」證照課程!快來點開看看!
Thumbnail
🔗https://edjump.pse.is/54meaw 今天的來賓劉柏楊TK,為TKS FULL HOUSE 提克斯國際餐飲的創始人,他在高雄從事餐飲業已經超過11年。TK提供我們關於餐飲業競爭性質的見解,以及從酒吧業務開始轉型經營成功的外送公司的個人經歷。
Thumbnail
您是學生或公司行號正在為團服或公司制服所煩惱嗎?幾何學幫您整理了關於客製化團服、公司制服或團體服設計與材質,還有最重要的價格估算,讓您對於客製化團體服有更全面的認識,快來看看幾何學精心撰寫的內容吧! 客製化衣服怎麼製作?衣服設計流程大公開! https://www.geometrytaiwan.co
Thumbnail
記得先點+追蹤喔❤️ 【復刻未來・AI 海洋名畫特展】 活動期間:2022/10/5 ~ 2023/3/31 票價資訊:Xpark 門票
Thumbnail
近來好嗎?感謝老天為我們下了場雨,即時讓這週的各地水庫有進帳。 您好,這是一則每週日晚上都會為您親自撰寫的一封信,來自銀色大門的一封信。 在這封信裡,您能夠知道銀色大門在成長、服務長輩等面向的細節, 為的就是邀請您可以一起參與服務長輩和創造台灣銀髮產業革命!
Thumbnail
台灣有許多店家取名都有它必然與因緣際會而成為這家店的名字。長春二號飯盒專賣店就是如此店家,該店家靠近中山捷運站附近,地址在台北市中山區長春路二號,因為門牌地址就取了這個長春二號店名。 長春二號相關資訊:: 地址: 台北市中山區長春路2號 電話: 02 2581 5508 營業時間:
Thumbnail
   今天要分享給大家的這幅作品,是我們在紐約的布魯克林大橋上創作的,所以我們在背景加上了當時的景色,給畫中的情侶留下一份獨特的回憶.   今天我們要介紹的就是這畫中的背景,在紐約的布魯克林大橋.
Thumbnail
HI~Whoscake今天來跟大家分享一下常見的幾種2020年最特別的生日蛋糕推薦類別 以上是我個人2020年生日蛋糕精選又不負任何責任的評論,看完文章的人感謝你的耐心。大家都可以在下方跟我多多討論唷,這樣我才有更多方向去挖掘美食!
Thumbnail
人生事業 愛情皆轉轉轉!http://www.6995.com.tw哈哈哈哈哈!轉運了!邱允文和邱吉爾在生日禮物結婚禮物客製化商品-天藏地酒1月25日上午2:25 · 台中市 · 「邱允文」的圖片搜尋結果邱允文和邱吉爾在生日禮物結婚禮物客製化商品-天藏地酒邱允文 阿拉丁創客團隊 免費
Thumbnail
邱允文– 阿拉丁瓶雕刻生日禮物結婚禮物國立臺中科技大學 ...2019年5月23日 - 邱允文國立臺中科技大學『回憶只會越來越淡,直至它已烙印在你心深處。 ... 天貓商行酒瓶雕刻生日禮物結婚禮物台中客製化商品- YouTube客製化商品台中- 邱允文阿拉丁創客團隊  http://www.6995