看著身邊的朋友都在寫技術博客,我也談不上什么技術大牛.也只是一個晚輩.所以大多還是自己平時開發(fā)中遇到問題的一些總結.希望大牛多提提意見.
之前沒接觸iOS時候,就喜歡用markdown去寫一些筆記之類的東西,感覺挺方便的.大家可以自己百度,了解下markdown的語法,你也會愛上寫作的.
第一次寫,也不知道寫一些什么東西好.我們就來說說主流的這些APP吧.我的iPhone里面雖然APP很多,但是每天用得APP就那幾個,微博,微信,淘寶,支付寶,滴滴出行和公司的產(chǎn)品.
我們今天就先來了解一下微博主要界面如何去搭建吧.
這是我隨便在微博截圖下來的,大家可以看到其實就是頂部一個導航欄,底部一個tabBar.
這張圖可以很好說明他們之間的關系了
接下來,我們就來說說UITabBarController和UINavigationController這兩個控制器.
UITabBarController
在AppDelegate.m中簡單實現(xiàn)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
self.window.rootViewController = tabBarController;
UIViewController *vc1 = [[UIViewController alloc] init];
vc1.view.backgroundColor = [UIColor redColor];
vc1.title = @"首頁";
[tabBarController addChildViewController:vc1];
UIViewController *vc2 = [[UIViewController alloc] init];
vc2.view.backgroundColor = [UIColor yellowColor];
vc2.title = @"消息";
[tabBarController addChildViewController:vc2];
UIViewController *vc3 = [[UIViewController alloc] init];
vc3.view.backgroundColor = [UIColor blueColor];
vc3.title = @"發(fā)現(xiàn)";
[tabBarController addChildViewController:vc3];
UIViewController *vc4 = [[UIViewController alloc] init];
vc4.view.backgroundColor = [UIColor grayColor];
vc4.title = @"我";
[tabBarController addChildViewController:vc4];
[self.window makeKeyAndVisible];
return YES;
}
我們創(chuàng)建了四個控制器做為UITabBarController的子控制器,這樣子我們就可以在下面的TabBar中來回切換不同的控制器了.但是我們還差導航欄,其實很簡單.我們只需要包裝一個導航控制器做為UITabBarController的子控制器就可以.
UIViewController *vc1 = [[UIViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc1];
vc1.view.backgroundColor = [UIColor redColor];
vc1.title = @"首頁";
[tabBarController addChildViewController:nav];
效果如下:
說一下tabBar的一些屬性
//這個是標題
vc1.tabBarItem.title = @"精華";
//這個是沒選中的圖片
vc1.tabBarItem.image = [UIImage imageNamed:@"tabBar_essence_icon"];
//這個是選中的圖片
vc1.tabBarItem.selectedImage = [UIImage imageNamed:@"tabBar_essence_click_icon"];
- 設置item屬性
- 通過appearance來統(tǒng)一設置(可以查看查看頭文件是否有UI_APPEARANCE_SELECTOR的屬性或方法)
// UIControlStateNormal狀態(tài)下的文字屬性
NSMutableDictionary *normalAttrs = [NSMutableDictionary dictionary];
// 文字顏色
normalAttrs[NSForegroundColorAttributeName] = [UIColor grayColor];
// 文字大小
normalAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:12];
// UIControlStateSelected狀態(tài)下的文字屬性
NSMutableDictionary *selectedAttrs = [NSMutableDictionary dictionary];
// 文字顏色
selectedAttrs[NSForegroundColorAttributeName] = [UIColor darkGrayColor];
// 統(tǒng)一給所有的UITabBarItem設置文字屬性
// 只有后面帶有UI_APPEARANCE_SELECTOR的屬性或方法, 才可以通過appearance對象來統(tǒng)一設置
UITabBarItem *item = [UITabBarItem appearance];
[item setTitleTextAttributes:normalAttrs forState:UIControlStateNormal];
[item setTitleTextAttributes:selectedAttrs forState:UIControlStateSelected];
這樣子我們基本框架就搭建起來了,但是這樣子的代碼略為垃圾.這種重復的代碼還是想想怎么樣去封裝起來比較好,自己看起來也會比較開心點.
- 我們寫一個方法去包裝一下
- 同時包裝一個導航控制器
- 設置子控制器的tabBarItem
/**
* 添加一個子控制器
* @param title 文字
* @param image 圖片
* @param selectedImage 選中時的圖片
*/
- (void)setupChildVc:(UIViewController *)vc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage
{
// 包裝一個導航控制器
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
[self addChildViewController:nav];
}
// 設置子控制器的tabBarItem
nav.tabBarItem.title = title;
nav.tabBarItem.image = [UIImage imageNamed:image];
nav.tabBarItem.selectedImage = [UIImage imageNamed:selectedImage];
設置導航欄item
- 設置導航欄的標題
self.navigationItem.title = @"我的";
- 設置導航欄的標題是View
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"MainTitle"]];
- 這個方法創(chuàng)建的跟圖片尺寸一樣大
[[UIImageView alloc] initWithImage:[UIImage imageNamed:@""]];
- 設置導航欄的按鈕
- 需要自適應圖片的大小
[button sizeToFit];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundImage:[UIImage imageNamed:@"MainTagSubIcon"] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:@"MainTagSubIconClick"] forState:UIControlStateHighlighted];
[button sizeToFit];
[button addTarget:self action:@selector(tagClick) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
- 設置多個按鈕的時候可以把按鈕添加到left/rightBarButtonItems
self.navigationItem.rightBarButtonItems = @[
[[UIBarButtonItem alloc] initWithCustomView:settingButton],
[[UIBarButtonItem alloc] initWithCustomView:moonButton]
];
- 封裝UIBarButtonItem的創(chuàng)建
+ (instancetype)itemWithImage:(NSString *)image highImage:(NSString *)highImage target:(id)target action:(SEL)action
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];
[button sizeToFit];
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
return [[self alloc] initWithCustomView:button];
}
導航欄返回鍵的統(tǒng)一設置和返回手勢
- 通過這個- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated發(fā)放可以攔截所有PUSH進來的子控制器
- 需要把根控制器排除做一個判斷
- 通過設置contentEdgeInsets可以使按鈕向右偏移
- super的push方法一定要寫到最后面
/**
* 攔截所有push進來的子控制器
* @param viewController 每一次push進來的子控制器
*/
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// if (不是第一個push進來的子控制器) {
if (self.childViewControllers.count >= 1) {
// 左上角的返回
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setTitle:@"返回" forState:UIControlStateNormal];
[backButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[backButton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
[backButton setImage:[UIImage imageNamed:@"navigationButtonReturn"] forState:UIControlStateNormal];
[backButton setImage:[UIImage imageNamed:@"navigationButtonReturnClick"] forState:UIControlStateHighlighted];
[backButton sizeToFit];
[backButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
backButton.contentEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0);
viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
viewController.hidesBottomBarWhenPushed = YES; // 隱藏底部的工具條
}
// super的push方法一定要寫到最后面
// 一旦調用super的pushViewController方法,就會創(chuàng)建子控制器viewController的view
// 也就會調用viewController的viewDidLoad方法
[super pushViewController:viewController animated:animated];
}
- (void)back
{
[self popViewControllerAnimated:YES];
}
- 如果重寫了push方法返回手勢就會失效(沒了返回手勢,用戶體驗真心就垃圾了)
- 需要重寫下面的代理方法
- <UIGestureRecognizerDelegate> 別忘記了設置代理
- 切記需要過濾掉根控制器
self.interactivePopGestureRecognizer.delegate = self;
/**
* 每當用戶觸發(fā)[返回手勢]時都會調用一次這個方法
* 返回值:返回YES,手勢有效; 返回NO,手勢失效
*/
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// 如果當前顯示的是第一個子控制器,就應該禁止掉[返回手勢]
// if (self.childViewControllers.count == 1) return NO;
// return YES;
return self.childViewControllers.count > 1;
}
狀態(tài)欄的設置
- 讓狀態(tài)欄樣式為白色
- (UIStatusBarStyle)preferredStatusBarStyle
{
// UIStatusBarStyleDefault
return UIStatusBarStyleLightContent;
}
第一次總結,寫得好亂好亂.下次會注意點的.謝謝你能看到這里