目錄:
- NavigationBar
- 由導航欄引起的零點坐標問題
- TabBar
- StatusBar
- NSAttributedString
- 文本自適應
1. NavigationBar
- 父子關系:UINavigationController->
UINavigationbar(設置tintColor/barTintColor/圖像)
UINavigationItem(設置左右按鈕/title/titleview)( 上下平級) - translucent 管理半透明效果
YES為開啟 NO為關閉 iOS7之后默認為YES。當為YES時ViewController上的View的原點坐標會以navigationBar以下的坐標為原點,就是在view 上創建視圖將不在考慮navigationBar的高度 - titleTextAttributes 是UINavigationBar的一個屬性,通過此屬性可以設置title部分的字體。有時我們在開發過程中會遇到當我們導航欄的顏色是比較暗的顏色是我們設置的文字不容易看見,這個時候我們用titleTextAttributes可以設置title字體顏色。
setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]} - title 和 navigationItem.title 的區別當你的項目中沒有tabBarController時.title和navigationItem.title效果是一樣的當你的項目中有設置 tabBarController 時設置self.title會顯示在TabBarItem上和navigationBar上。但如果你只需要TabBarItem上和NavigationBar上顯示的不一樣的話這些都需要單獨設置。
- navigationBarHidden,為了app的界面更好看通常我們都會給viewController一個背景圖片,這個時候navigationBar在不是必須要的情況下navigationBar會影響界面的美觀我們通常會將navigationBar隱藏起來再需要的時候將其顯示出來。
self.navigationController.navigationBarHidden = NO;
self.navigationController.navigationBar.hidden = NO;
兩種方法不一樣
兩種方法都是可以隱藏導航欄的,隱藏之后依然可以使用push和pop方法。
但是如果用navigationBar.hidden隱藏導航欄,我們可以繼續使用navigationBarHidden提供的滑動pop效果.
如果用navigationBarHidden,這個操作將無效;
但前者navigationBar.hidden沒有系統自動的動畫效果。
- barStyle設置navigationBar的顏色,系統只支持這兩種格式
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;UIBarStyleDefault = 0,
//白色默認UIBarStyleBlack = 1
//黑色
- barTintColor 背景色; tintColor分別是item的顏色;titleTextAttributes可以設置title字體顏色。
self.navigationController.navigationBar.barTintColor = [UIColor redColor];self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
- UINavigationItem自定義view大小一般為w=h=30;用btn.imageEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0)指定位置,視圖的x和y無效
//設置導航標題視圖,就是這一塊可以加載任意一種視圖,視圖上下左右居中顯示在標題的位置,視圖的x和y無效
UIView *textView1=[[UIView alloc]initWithFrame:CGRectMake(10, 10, 50, 30)];
textView1.backgroundColor=[UIColor whiteColor];
[self.navigationItem setTitleView:textView1];
- 導航欄透明
[self.navigationController.navigationBar setBackgroundImage:[UIImage new]
forBarMetrics:UIBarMetricsDefault];
//shadowImage,是導航欄下面的那根細線,如果不設置則會看到一根線。
self.navigationController.navigationBar.shadowImage = [UIImage new];
- 導航欄透明漸變
self.barImageView = self.navigationController.navigationBar.subviews.firstObject;
對self.barImageView.alpha 做出改變
- [UINavigationBar appearance]類方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[UINavigationBar appearance].tintColor = [UIColor orangeColor];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"m_nav64"] forBarMetrics:UIBarMetricsDefault];
return YES;
}
2. 由導航欄引起的零點坐標問題
屏幕原點的改變(只要是VC中的控件,都是從設備左上角的(0,0)開始算的)。iOS 7之后都是從Statusbar左上角(0,0)開始布局的,但是有時,我們也會遇到在 NavigationController 中是以(0,64)布局的,此處又是什么情況呢?先來看一下下面三個屬性:
-
edgesForExtendedLayout
表示視圖是否覆蓋到四周的區域,默認是UIRectEdgeAll,即上下左右四個方向都會覆蓋,那么為讓頂部不進行延伸到導航欄覆蓋的區域,我們可以把頂部區域延伸去掉。這個屬性是UIExtendedEdge類型,用來制定視圖的哪條邊需要擴展。默認是UIRectEdgeAll,也就是全屏布局(iOS7中鼓勵這樣,這樣可以透過半透明的bar看到一些模模糊糊的內容),如果設置為UIExtendedEdgeNone,view就不會延伸到bar的后面了 - extendedLayoutIncludesOpaqueBars默認值NO,這個屬性指定了當Bar使用了不透明圖片時,視圖是否延伸至Bar所在區域; 但是Bar的默認屬性是透明的。也就是說只有在不透明下才有用;因此,如果我們自定義了nav bar背景圖片,view會從導航欄下面開始布局。
- automaticallyAdjustsScrollViewInsets默認值是YES,如果視圖里面存在唯一一個UIScrollView或其子類View,那么它會自動設置相應的內邊距(如果有navbar的時候,這個內邊距是64,這樣scrollview可以占滿屏幕,內容在64像素以下,不會被遮到,滑動scrollview,可以透過半透明效果看到scrollview上面的內容)。設置改變的是inset,而不是frame。
-
VC中的view默認會對UIScrollView做一個適應導航欄的處理,由此推測,其實只要是VC中的控件,都是從設備左上角的(0,0)開始算的,只是對于UIScrollView,VC會自動調整一下內容的位置而已。
在有導航的情況下,可視范圍的Y坐標就是從64開始的,除了UIScrollView的控件,定位的時候,都應當以(0,64)為原點;而UIScrollView如果是全屏的,那么無所謂,如果不是全屏的,請注意是否需要設置VC的automaticallyAdjustsScrollViewInsets。 - 所以說有時,我們發現原點位置變化了,就可以看看上述幾個屬性是否有設置改動的。經常我們用到
tableView
或collectionView
的時候就需要設置self.automaticallyAdjustsScrollViewInsets = NO
, 不讓其自動調整。 - 這幾個屬性當使用的時候互相影響互相有聯系,對原點改變的影響力:navigationBarHidden> edgesForExtendedLayout> translucent> extendedLayoutIncludesOpaqueBars
3. 定制TabBar
*父子關系:UITabBarController->UITabbar(設置tintColor/barTintColor/圖像)->UITabBarItem(設置titile/image/badgeValue ; 每個tabBarItem對應一個viewController)
圖片渲染
隱藏tabbar
第一種
vc.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:vc animated:YES];
第二種
//隱藏
self.hidesBottomBarWhenPushed = YES;
//顯示
self.hidesBottomBarWhenPushed = NO;
第三種
//隱藏TabBar
- (void)hideTabBar {
if (self.tabBarController.tabBar.hidden == YES) {
return;
}
UIView *contentView;
if ( [[self.tabBarController.view.subviews objectAtIndex:0] isKindOfClass:[UITabBar class]] )
contentView = [self.tabBarController.view.subviews objectAtIndex:1];
else
contentView = [self.tabBarController.view.subviews objectAtIndex:0];
contentView.frame = CGRectMake(contentView.bounds.origin.x, contentView.bounds.origin.y, contentView.bounds.size.width, contentView.bounds.size.height + self.tabBarController.tabBar.frame.size.height);
self.tabBarController.tabBar.hidden = YES;
}
//顯示TabBar
- (void)showTabBar {
if (self.tabBarController.tabBar.hidden == NO)
{
return;
}
UIView *contentView;
if ([[self.tabBarController.view.subviews objectAtIndex:0] isKindOfClass:[UITabBar class]])
contentView = [self.tabBarController.view.subviews objectAtIndex:1];
else
contentView = [self.tabBarController.view.subviews objectAtIndex:0];
contentView.frame = CGRectMake(contentView.bounds.origin.x, contentView.bounds.origin.y, contentView.bounds.size.width, contentView.bounds.size.height - self.tabBarController.tabBar.frame.size.height);
self.tabBarController.tabBar.hidden = NO;
}
4. StatusBar:系統提供了2種管理狀態欄的方式
- 通過UIViewController管理(每一個UIViewController都可以擁有自己不同的狀態欄),默認是交給控制器來管理的.直接重寫這個方法
在控制器當中設置狀態欄樣式
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
-(BOOL)prefersStatusBarHidden{
return YES;
}
- 由程序來管理隱藏及style,通過UIApplication管理(一個應用程序的狀態欄都由它統一管理)
前提:通常在開發當中都是應用程序來管理狀態欄的.來做統一管理,不然的話, 會有很多個控制器.會非常的麻煩.想要讓應用程序管理狀態欄,要在info.plist
當中進行配置,
添加一個key
值:是最后一個,View controller-based status bar appearance
設置為NO.就是應用程序來管理了.
UIApplication *app = [UIApplication sharedApplication];
[app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
[app setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
- 既然兩種都可以對狀態欄進行管理,那么什么時候該用什么呢?
如果狀態欄的樣式只設置一次,那就用UIApplication來進行管理;
如果狀態欄是否隱藏,樣式不一樣那就用控制器進行管理。
UIApplication來進行管理有額外的好處,可以提供動畫效果。
5. NSAttributedString-富文本
- 普通的文本屬性已經無法滿足需求,就需要我們學習和使用更加靈活的富文本。可實現圖文混排及生成鏈接(在 UILabel 和 UITextField 中是無法使用該屬性的。更準確點說是在UILabel 和 UITextField 中無法實現點擊鏈接啟動瀏覽器打開一個URL地址,因為在此過程中用到了一個代理函數。只能用在 UITextView 中。)
-
AttributedString
可以分為NSAttributedString
和NSMutableAttributedString
兩種。在使用中通過將AttributedString
賦值給控件的attributedText
屬性來添加文字樣式。有此屬性的控件有UILabel
、UITextField
和UITextView
. - 兩種用法
//初始化NSMutableAttributedString
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]init];
//設置字體格式和大小
NSString *str = @"設置字體格式和大小";
NSDictionary *dictAttr = @{NSFontAttributeName:[UIFont systemFontOfSize:14]};
NSAttributedString *attr = [[NSAttributedString alloc]initWithString:str attributes:dictAttr];
[attributedString appendAttributedString:attr];
NSString *str = @"人生若只如初見,何事悲風秋畫扇。\n等閑變卻故人心,卻道故人心易變。\n驪山語罷清宵半,淚雨霖鈴終不怨。\n何如薄幸錦衣郎,比翼連枝當日愿。";
// 創建 NSMutableAttributedString
NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:str];
// 設置字體和設置字體的范圍
[attrStr addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:30.0f]
range:NSMakeRange(0, 3)];
6. 文本自適應
- sizeToFit
當 寫上label.numberOfLines = 0,寬度不變,高度變化
當 沒有寫上label.numberOfLines = 0,寬度自適應,高度變化仍是單行
- boundingRectWithSize:這個方法是 iOS7 以后根據寬高屬性計算字符串寬度跟高度的一個方式.不同的屬性會計算出不同的值.具體的可以谷歌下
NSStringDrawingOptions
.
計算高度:給定具體寬度值,高度值為0;
計算寬度:給定具體高度值,寬度值為0;
NSDictionary *attributeDic = @{NSFontAttributeName: [UIFont systemFontOfSize:14]};
CGRect rect = [info boundingRectWithSize:CGSizeMake(0, 30) options:
NSStringDrawingUsesLineFragmentOrigin|
NSStringDrawingUsesFontLeading
attributes: attributeDic context:nil];
// 參數1: 自適應尺寸,提供一個寬度(高度),去自適應高度(寬度)
// 參數2:自適應設置 (以行為矩形區域自適應,以字體字形自適應)
// 參數3:文字屬性,通常這里面需要知道是字體大小
// 參數4:繪制文本上下文,做底層排版時使用,填nil即可
NSStringDrawingTruncatesLastVisibleLine : 如果文本內容超出指定的矩形限制,文本將被截去并在最后一個字符后加上省略號 . 如果三選項沒有選擇, 忽略此選項.
NSStringDrawingUsesLineFragmentOrigin : 整個文本將以每行組成的矩形為單位計算整個文本的尺寸.
NSStringDrawingUsesFontLeading : 以字體間的行距(leading,行距:從一行文字的底部到另一行文字底部的間距。)來計算高度。
NSStringDrawingUsesDeviceMetrics : 計算布局時使用圖像符號邊界, 而不是排版的邊界 .
注意:當計算NSMutableAttributedString
時, 必須設置富文本的字體樣式(NSMutableParagraphStyle),才可以計算正確
-
sizeWithAttributes
:計算寬度
適用于根據字體計算出文本單行的長度和高度(寬度和高度),注意是單行,所以你返回的高度是一個定值。
CGSize size = [s.text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:10]}];