目录:
- 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]}];