漫談TabBar(一)
UITabbar是ios框架中重要的元件,通常我們一個app只會建立一個tabbar來管理整個app的流程
手動建立一個tabbarcontroller:
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
timerViewController *timer = [[timerViewController alloc] initWithNibName:@"timerViewController" bundle:nil];
appleViewController *apple0 = [[appleViewController alloc] initWithNibName:@"appleViewController" bundle:nil];
appleViewController *apple1 = [[appleViewController alloc] initWithNibName:@"appleViewController" bundle:nil];
appleViewController *apple2 = [[appleViewController alloc] initWithNibName:@"appleViewController" bundle:nil];
appleViewController *apple3 = [[appleViewController alloc] initWithNibName:@"appleViewController" bundle:nil];
appleViewController *apple4 = [[appleViewController alloc] initWithNibName:@"appleViewController" bundle:nil];
barViewController *bar = [[barViewController alloc] init];
[bar setViewControllers:[NSArray arrayWithObjects:timer,apple0,apple1,apple2,apple3,apple4, nil]];
[self .window setRootViewController:bar];
[self.window makeKeyAndVisible];
return YES;
如果管理的controller超過5個,會自動的變成more的標籤。點選more會彈出一個由tabbar管理的tableView,在這不做過多的描述,手冊上很清楚。
然後,我們覺得這個原生的TabBar太low了,我們想改一下造型,比如高度,顏色?然後
bar.tabBar.backgroundColor = [UIColor blueColor];
CGRect ct = bar.tabBar.frame;
ct.size.height = ct.size.height * 2;
[bar.tabBar setFrame:ct];
嗯,高度沒有變化,顏色變了?好像沒有變成我們設定的顏色,不過還挺好看的 。檢視手冊tabbar的預設高度為49 ,我們自己建立一個tablebarController來探究下, 在viewDidLayoutSubviews中將整個view的層級結構打印出來。。
#import "barViewController.h"
#import "customTabBar.h"
@interface barViewController ()
@end
@implementation barViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)viewDidLayoutSubviews{
[self printViewHierarchy:self.view];
}
//view樹
- (void)printViewHierarchy:(UIView *)superView
{
static uint level = 0;
for(uint i = 0; i < level; i++){
printf("\t");
}
const char *className = NSStringFromClass([superView class]).UTF8String;
const char *frame = NSStringFromCGRect(superView.frame).UTF8String;
printf("%s:%s\n", className, frame);
++level;
for(UIView *view in superView.subviews){
[self printViewHierarchy:view];
}
--level;
}
結果
UILayoutContainerView:{{0, 0}, {375, 667}}
UITransitionView:{{0, 0}, {375, 667}}
UIViewControllerWrapperView:{{0, 0}, {375, 667}}
UIView:{{0, 0}, {375, 667}}
UILabel:{{135, 137}, {165, 21}}
UITabBar:{{0, 618}, {375, 49}}
_UITabBarBackgroundView:{{0, 0}, {375, 49}}
_UIBackdropView:{{0, 0}, {375, 49}}
_UIBackdropEffectView:{{0, 0}, {375, 49}}
UIView:{{0, 0}, {375, 49}}
UITabBarButton:{{2, 1}, {71, 48}}
UITabBarButtonLabel:{{24, 35}, {23, 12}}
UITabBarButton:{{77, 1}, {71, 48}}
UITabBarButtonLabel:{{21.5, 35}, {27.5, 12}}
UITabBarButton:{{152, 1}, {71, 48}}
UITabBarButtonLabel:{{21.5, 35}, {27.5, 12}}
UITabBarButton:{{227, 1}, {71, 48}}
UITabBarButtonLabel:{{21.5, 35}, {27.5, 12}}
UITabBarButton:{{302, 1}, {71, 48}}
UITabBarSwappableImageView:{{23.5, 15.5}, {24, 5}}
UITabBarButtonLabel:{{23.5, 35}, {24, 12}}
UIImageView:{{0, -0.5}, {375, 0.5}}
UILayoutContainerView,UITransitionView,UIViewControllerWrapperView,UITabBarBackgroundView,UIBackdropView,UIBackdropEffectView在手冊中都找不到,apple並沒有公開這些view的資訊,我們自己hack下。
UILayoutContainerView :不用說肯定是整個控制器的最頂層view..
UITransitionView:我們改改他的高度看看效果,在viewDidLayoutSubviews中加入程式碼
for(UIView *view in self.view.subviews){
if ([view isKindOfClass:NSClassFromString(@"UITransitionView")]) {
CGRect rect = view.frame;
rect.size.height = rect.size.height-100;
[view setFrame:rect];
return;
}
}
在使用view除錯工具 debug->view debug->capture view hierarchy
檢視UITransitionView;
我們能很清楚的看到UITransitionView裡面顯示的是什麼東西(藍色邊框);
接下來分析UITabBar裡面的view 層!!在viewdidappear中加入下面程式碼
NSLog(@"viewDidAppear");
for(UIView *view in self.view.subviews){
if ([view isKindOfClass:NSClassFromString(@"UITabBar")]) {
CGRect rect = view.frame;
rect.size.height = 150;
rect.origin.y = rect.origin.y - 150+49;
[view setFrame:rect];
UIView * UITabBarBackgroundView = [view.subviews firstObject];
UITabBarBackgroundView.backgroundColor = [UIColor yellowColor];
rect = UITabBarBackgroundView.frame;
rect.size.height = 150;
[UITabBarBackgroundView setFrame:rect];
UIView * UIBackdropView = [UITabBarBackgroundView.subviews firstObject];
UIBackdropView.backgroundColor = [UIColor greenColor];
rect = UIBackdropView.frame;
rect.size.width = 200;
rect.size.height = 150;
[UIBackdropView setFrame:rect];
UIView * UIBackdropEffectView = [UIBackdropView.subviews firstObject];
UIBackdropEffectView.backgroundColor = [UIColor redColor];
rect = UIBackdropEffectView.frame;
rect.size.width = 200;
rect.size.height = 150;
[UIBackdropEffectView setFrame:rect];
}
}
區域3沒有UIBackdropView層,它顯示出了UITabBarBackgroundView的顏色,由此知道了bar的玻璃透明效果是UIBackdropView來控制的,而UIBackdropEffectView層時整個玻璃效果的核心,UIBackdropView的綠色背景,只是在2區域中稍微的顯示了出來,作為一個邊界的漸變效果,至於UIBackdropEffectView內部是怎樣產生的,我們無法得知了。
現在我們把原生tabBar的高度改變了,顏色的產生也明白了,但是好像還有一點問題,barItem的高度和位置應該放在中間吧,於是加入如下程式碼..
for (UIView *subView in view.subviews) {
if ([subView isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
UIView * lableView = [subView.subviews firstObject];
CGRect re = lableView.frame;
subView.backgroundColor = [UIColor redColor];
re.origin.y = subView.frame.size.height/2;
[lableView setFrame:re];
}
}
然而並沒有什麼卵用,Why? 瞅瞅官方寫的tabBar的文件。有沒有能起作用的。
幾個屬性---
itemPositioning | itemSpacing | itemWidth 貌似可以操作items看看效果吧 加入程式碼
self.tabBar.itemPositioning = UITabBarItemPositioningCentered;
self.tabBar.itemSpacing = 20;
self.tabBar.itemWidth = 20;
懂了吧當UITabBarItemPositioningCentered時候,item會向中間靠攏, UITabBarItemPositioningFill就沒有這個效果會直接填滿了整個tabbar 的。。然而這並沒有設定高度的,不甘心,我們接著將items爬出來。。。
在UITabBarItem種我們找到了setTitlePositionAdjustment方法;我們試一下;
NSArray *Items = self.tabBar.items;
NSLog(@"link : %@",Items);
UITabBarItem *item = [Items firstObject];
[item setTitlePositionAdjustment:UIOffsetMake(0, -20)];
嗯 item中的title改變了 。。。
總結:對於TabBar控制元件而言,apple對於其整合度是很高的,所以我們很難再其中加以改動,至於tabbar自己會有自己內部的機制將item有秩序的放在其view內部,在手冊中UITabbarItem的父類UIbarItem並不是UIView的子類,所以起並沒有frame和bonds屬性,這就讓我們很難去改動item的大小了,(然而這並沒有什麼卵用),如果要使用原生的tabbarController的話那麼久應該遵循其規律。。