市面上的 App 有各種樣式的 TabBar
有最基本的 這樣的
也有進階一點的
這樣的 TabBar 我們用 LayoutSubView 就能夠實作
今天帶來一種不同的思路 與大家分享
建立項目 AppDelegate.m 中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
_window = [[UIWindow alloc] init];
_window.backgroundColor = [UIColor whiteColor];
_window.rootViewController = [[MainViewController alloc] init];
[_window makeKeyAndVisible];
return YES;
}
我們建立一個類 MainViewController 繼承與 UITabBarController
來到 MainViewController.m 中
建立最基本的4個 TabBar
- (void)viewDidLoad {
[super viewDidLoad];
[self setupUI];
}
- (void)setupUI {
for (NSInteger i = ; i < ; i++) {
UIViewController *vC = [[UIViewController alloc] init];
vC.title = @(i).description;
[self addChildViewController:vC];
}
}
效果如下:
我們的目标呢 是在”2”這個位置放一個 button
先執行個體化一個 button
UIButton *btn = [[UIButton alloc] init];
擷取 TabBar 的 bounds 和每個 button 的寬度
CGRect rect = self.tabBar.bounds;
CGFloat w = rect.size.width / ;
設定 button 的顔色和 frame 并添加到控制器
這裡使用 CGRectInset
給定一個矩形 中心點不變 正值是内聚 負值是外擴
btn.backgroundColor = [UIColor redColor];
btn.frame = CGRectInset(rect, , );
[self.tabBar addSubview:btn];
運作程式我們會看到紅色的 button 已經把整個 TabBar 都蓋住了
我們想要的效果是 紅色的button 隻占 TabBar 的 1/5 并且居中
此時我們對 button 的 frame 進行修改
看一下修改後的效果 ��
至此 與懂球帝和微網誌類似的效果就實作了
那之前我們定的目标 紅色的 button 更高大一點是如何實作的呢?
其實也很簡單 我們隻要修改剛才代碼的 y 值就可以輕松實作
剩下的我們隻需要把 UI設計師給我們提供的圖檔往 button 上一放
一個美麗的 TabBar 就這麼出來啦 !
但是得注意 使用者在點選 超過 TabBar 部分的 button 時是無法響應的
因為它已經超過父視圖的範圍 是以無法接受監聽
并且 隻做這樣的設定 使用者在多次點選”1”和”3”的邊緣時會出現一些 bug
如圖�� :
這樣的 bug 着實也是吓我一跳
為什麼會出現這樣詭異的 bug 呢?
我們運作程式 看一下視圖層次
通過視圖層次 我們清楚的看見 每一個 TabBar button 之間都會有間隙
這個間隙 是蘋果為了友善使用者 做了一個容錯的處理 使每個中間都有一個間隙
這個間隙輕易還點選不出來 ��
但是如果我們的項目上線了,什麼樣 bug 都能被使用者發現出來
他們在真機中 很輕易的就能夠将這個 bug 點選出來
這樣的方法雖然比 LayoutSubView 簡單 但是有個 bug
這要如何解決呢 ?
我們跳到 UITabBarController 的頭檔案中
發現裡面有個代理方法
| @property(nullable, nonatomic,weak) id<UITabBarControllerDelegate> delegate;
在這個代理方法中 我們看到一個方法
| - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController NS_AVAILABLE_IOS(_0);
shouldSelect 是否應該被選中
回到 HMMainViewController.m 中
設定代理 遵守協定
self.delegate = self;
我們剛才在頭檔案中看見的方法 粘進項目中
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
return ![viewController isMemberOfClass:[UIViewController class]];
}
這個方法傳回的是 BOOL 類型
我們傳回一下這行代碼就可以解決間隙問題 ~
再點選 就點選不到那個間隙了
類似懂球帝 微網誌這樣的 TabBar 還有一些實作的方法
有時間我會寫個部落格 再介紹給大家 ~