设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

时间:2021-08-23 15:40:37

1 TMessage项目的输入面板界面

1.1 问题

IOS中经常会使用到九切片技术对图片进行处理。本案例使用九切片技术完成Tmessage项目的输入板界面,如图-1所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-1

1.2 方案

首先创建一个SingleViewApplication项目,在Storyboard中根据界面需求拖放控件到场景中,首先拖放一个适当大小的View控件作为输入面板界面,输入面板的各个控件为View的子视图。

其次在View上拖放一个一样大小的ImageView控件作为输入面板的背景图,在View上面拖放三个按钮和一个TextField控件,最后拖放一个ImageView控件,同TextField一样大小作为TextField的背景图片,并且TextField是覆盖在ImageView上面的。

然后分别将作为输入面板背景的ImageView、TextField、以及作为TextField背景的ImageView关联成TRViewController的属性backgroundView、textField以及textFieldBkgView。

最后在TRViewController的viewDidLoad方法中以代码的方式使用九切片技术给backgroundView和textFieldBkgView设置图片。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:在Storyboard中搭建界面

创建一个SingleViewApplication项目,在Storyboard中根据界面需求拖放控件到场景中。

首先拖放一个适当大小的View控件作为输入面板界面,输入面板的各个控件为View的子视图。

其次在View上拖放一个一样大小的ImageView控件作为输入面的背景图,在View上面拖放三个按钮和一个TextField控件,然后拖放一个ImageView控件,同TextField一样大小作为TextField的背景图片,并且TextField是覆盖在ImageView上面的。

最后Stroyboard完成效果如图-2所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-2

步骤二:设置TMessage的背景图片

首先分别将作为输入面板背景的ImageView、TextField、以及作为TextField背景的ImageView关联成TRViewController的属性backgroundView、textField以及textFieldBkgView,代码如下所示:

 
  1. @interface TRViewController ()
  2. @property (weak, nonatomic) IBOutlet UIImageView *backgroundView;
  3. @property (weak, nonatomic) IBOutlet UITextField *textField;
  4. @property (weak, nonatomic) IBOutlet UIImageView *textFieldBkgView;
  5. @end

然后在TRViewController的viewDidLoad方法中使用UIImage提供的方法resizableImageWithCapInsets: resizingMode:,对图片进行九切片处理,分别给backgroundView和textFieldBkgView设置图片,代码如下所示:

 
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. UIImage *backgroundImage = [UIImage imageNamed:@"ToolViewBkg_Black.png"];
  5. backgroundImage = [backgroundImage resizableImageWithCapInsets:UIEdgeInsetsMake(2, 3, 2, 3) resizingMode:UIImageResizingModeStretch];
  6. self.backgroundView.image = backgroundImage;
  7. UIImage *textFieldImage = [UIImage imageNamed:@"SendTextViewBkg.png"];
  8. self.textFieldBkgView.image = [textFieldImage resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10) resizingMode:UIImageResizingModeStretch];
  9. }

1.4 完整代码

本案例中,TRViewController.m文件中的完整代码如下所示:

 
  1. #import "TRViewController.h"
  2. @interface TRViewController ()
  3. @property (weak, nonatomic) IBOutlet UIImageView *backgroundView;
  4. @property (weak, nonatomic) IBOutlet UITextField *textField;
  5. @property (weak, nonatomic) IBOutlet UIImageView *textFieldBkgView;
  6. @end
  7. @implementation TRViewController
  8. - (void)viewDidLoad
  9. {
  10. [super viewDidLoad];
  11. UIImage *backgroundImage = [UIImage imageNamed:@"ToolViewBkg_Black.png"];
  12. backgroundImage = [backgroundImage resizableImageWithCapInsets:UIEdgeInsetsMake(2, 3, 2, 3) resizingMode:UIImageResizingModeStretch];
  13. self.backgroundView.image = backgroundImage;
  14. UIImage *textFieldImage = [UIImage imageNamed:@"SendTextViewBkg.png"];
  15. self.textFieldBkgView.image = [textFieldImage resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10) resizingMode:UIImageResizingModeStretch];
  16. }
  17. @end

2 使用Asset Catalog组件对图片进行9切片处理

2.1 问题

Asset Catalog组件可以用来统一的管理项目中的图片等资源,还提供对图片资源的设备适配,高清,拉伸等支持,也提供9切片技术的支持。本案例将学习如何使用Asset Catalo组件对图片进行9切片处理,如图-3所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-3

2.2 方案

首先在Storyboard中拖放一个Button控件和一个ImageView控件。然后可以在右边栏的检查器中直接设置Button和ImageView 的图片,但是需要先导入图片。

在Xcode的导航栏中选中Images.xcassets,在空白处点击右键,在弹出的窗口中选择New Image Set,可以重新命名为button。将button的不同尺寸的图片到右边的界面中相应的位置,一般图片都有两个尺寸一个是原始大小,一个是扩大两倍的大小,为Retina屏准备的。

然后点击右下角的Show Slicing,通过移动图片的分割线设定九切片上下左右保留的像素,在右边栏的检查器三中设置切片模式,按钮采用的是拉升模式所以选择Stretches,检查器中同样也可以手动设置上下左右保留的像素点。

以同样的方式将ImageView的图片也导入到Images.xcassets中,命名为seperator,切片模式则选择为平铺Tiles。

最后可以直接在Storyboard中设置Button和ImageView的图片了,不需要再写额外的代码了。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:导入图片到Images.xcassets中

首先在Storyboard中拖放一个Button控件和一个ImageView控件。然后可以在右边栏的检查器中直接设置Button和ImageView 的图片,但是需要先导入图片。

在Xcode的导航栏中选中Images.xcassets,在空白处点击右键,在弹出的窗口中选择New Image Set,如图-4所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-4

将新创建的ImageSet重新命名为button,然后将button的不同尺寸的图片到右边的界面中相应的位置,一般图片都有两个尺寸一个是原始大小,一个是扩大两倍的大小,为Retina屏准备的,如图-5所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-5

步骤二:在ImageSet中设置图片

点击右下角的Show Slicing,通过移动图片的分割线设定九切片上下左右保留的像素,两张图片都要设置,如图-6所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-6

然后在右边栏的检查器三中设置切片模式,按钮采用的是拉升模式所以选择Stretches,检查器中同样也可以手动设置上下左右保留的像素点,如图-7所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-7

最后以同样的方式将ImageView的图片也导入到Images.xcassets中,命名为seperator,切片模式则选择为平铺Tiles,如图-8、图-9所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-8

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-9

步骤三:在Storyboard中设置控件的图片

在Storyboard中分别将Button控件和ImageView控件的image设置为button和seperator,如图-10、图-11所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-10

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-11

在Stroyboard的场景中可以看到图片已经按九切片的方式设置完成,如图-12所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-12

3 给各控件美化背景图片

3.1 问题

UIButton 、UITextField 、UISlider、 UISwitch等控件一般有正常、高亮、被选中以及不可用等几种状态,本案例根据控件的不同状态设置图片,如图-13所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-13

3.2 方案

首先根据Button控件的状态设置image,可以在Storyboard里面直接设置也可以通过代码设置。在Storyboard里面拖放一个Button控件,在右边栏的检查器四中选择按钮状态,选择相应的图片。

然后在viewDidLoad方法中创建一个UIButton对象button,使用方法setImage:forState:根据按钮状态设置图片。

最后在Storyboard里面拖放一个Slider控件,将Slider关联成TRViewController的属性slider,在viewDidLoad方法中使用代码设置slider滑块按钮以及进度条的图片。

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:根据Button的状态设置图片

首先在Storyboard里面拖放一个Button控件,在右边栏的检查器四中选择按钮的正常状态和高亮状态,选择相应的图片,如图-14、图-15所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-14

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-15

然后在viewDidLoad方法中创建一个UIButton对象button,使用方法setImage:forState:根据按钮状态设置图片,代码如下所示:

 
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  5. button.frame = CGRectMake(200, 160, 35, 35);
  6. [button setImage:[UIImage imageNamed:@"ToolViewEmotion"] forState:UIControlStateNormal];
  7. [button setImage:[UIImage imageNamed:@"ToolViewEmotionHL"] forState:UIControlStateHighlighted];
  8. [self.view addSubview:button];
  9. }

运行程序,发现通过Storyboard设置图片和代码方式设置图片,点击按钮的效果是一样的。

步骤二:设置滑块控件Slider的图片

在Storyboard里面拖放一个Slider控件,将Slider关联成TRViewController的属性slider,代码如下所示:

  1. @interface TRViewController ()
  2. @property (weak, nonatomic) IBOutlet UISlider *slider;
  3. @end

最后在viewDidLoad方法中使用UIImage的九切片方法创建图片,再将图片设置为slider滑块按钮以及进度条的图片,注意slider的minimumTrackImage和maximumTrackImage必须同时设置才能生效,代码如下所示:

 
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  5. button.frame = CGRectMake(200, 160, 35, 35);
  6. [button setImage:[UIImage imageNamed:@"ToolViewEmotion"] forState:UIControlStateNormal];
  7. [button setImage:[UIImage imageNamed:@"ToolViewEmotionHL"] forState:UIControlStateHighlighted];
  8. [self.view addSubview:button];
  9. UIImage *image = [UIImage imageNamed:@"playing_volumn_slide_foreground.png"];
  10. image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(2, 2, 2, 2) resizingMode:UIImageResizingModeStretch];
  11. [self.slider setMinimumTrackImage:image forState:UIControlStateNormal];
  12. UIImage *bgImage = [UIImage imageNamed:@"playing_volumn_slide_bg.png"];
  13. bgImage = [bgImage resizableImageWithCapInsets:UIEdgeInsetsMake(2, 2, 2, 2) resizingMode:UIImageResizingModeStretch];
  14. [self.slider setMaximumTrackImage:bgImage forState:UIControlStateNormal];
  15. UIImage *thumbImage = [UIImage imageNamed:@"playing_volumn_slide_sound_icon.png"];
  16. [self.slider setThumbImage:thumbImage forState:UIControlStateNormal];
  17. }

3.4 完整代码

本案例中,TRViewController.m文件中的完整代码如下所示:

 
  1. #import "TRViewController.h"
  2. @interface TRViewController ()
  3. @property (weak, nonatomic) IBOutlet UISlider *slider;
  4. @end
  5. @implementation TRViewController
  6. - (void)viewDidLoad
  7. {
  8. [super viewDidLoad];
  9. UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  10. button.frame = CGRectMake(200, 160, 35, 35);
  11. [button setImage:[UIImage imageNamed:@"ToolViewEmotion"] forState:UIControlStateNormal];
  12. [button setImage:[UIImage imageNamed:@"ToolViewEmotionHL"] forState:UIControlStateHighlighted];
  13. [self.view addSubview:button];
  14. UIImage *image = [UIImage imageNamed:@"playing_volumn_slide_foreground.png"];
  15. image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(2, 2, 2, 2) resizingMode:UIImageResizingModeStretch];
  16. [self.slider setMinimumTrackImage:image forState:UIControlStateNormal];
  17. UIImage *bgImage = [UIImage imageNamed:@"playing_volumn_slide_bg.png"];
  18. bgImage = [bgImage resizableImageWithCapInsets:UIEdgeInsetsMake(2, 2, 2, 2) resizingMode:UIImageResizingModeStretch];
  19. [self.slider setMaximumTrackImage:bgImage forState:UIControlStateNormal];
  20. UIImage *thumbImage = [UIImage imageNamed:@"playing_volumn_slide_sound_icon.png"];
  21. [self.slider setThumbImage:thumbImage forState:UIControlStateNormal];
  22. }
  23. @end

4 给各控件进行颜色美化

4.1 问题

tintColor是视图的一个属性,可以统一的管理一个视图中所有子视图以及子视图的子视图的颜色,还可以批量的修改视图的颜色。本案例使用tintColor属性给控件进行颜色美化,查看父视图和子视图tintColor之间的关系,如图-16所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-16

4.2 方案

首先给Storyboard中的场景嵌套一个NavigationController,然后在场景上面拖放两个Button控件,在右边栏的检查器中将其中一个Button的tintColor进行设置为枚红色,另一个Button的tintColor不做额外设置。

然后在TRAppDelegate里面将window的tintColor颜色设置为紫色,运行程序发现自定义了tintColor的Button颜色不会改变还是自定义的颜色,未设置tintColor的Button颜色发生了改变,变成了window的tintColor颜色。

再在场景中任意拖放几个控件(Slider,Switch,SegmentedControl),分别都设置各自的tintColor,运行程序发现自定义tintColor的控件都会显示自己的tintColor颜色,而不会显示window的tintColor颜色。

其次在Storyboard中新创建一个场景,由第一个场景中的按钮Push过来,给第二个场景的View设置tintColor为绿色,往第二个场景上拖放几个任意的控件(Slider,Switch,Button,SegmentedControl),各个控件的tintColor会自动的变为绿色,这就是tintColor批量设置颜色的功能。

然后将第二个场景中的某个控件的tintColor进行自定义,例如将Slider的tintColor设置为蓝色,运行程序发现其他控件的tintColor和View一样是绿色,Slider控件的tintColor则是自定义的蓝色。

最后在Stroyboard中再创建一个新的场景,由第二个场景的按钮Push出来,在上面拖放几个任意的控件(Slider,Switch,Button,SegmentedControl),第三个场景不做任何tintColor的设置,运行程序发现控件显示的是window的tintColor颜色,由此可以看出如果一个控件没有设置tintColor,那么它会显示父视图的tintColor,如果父视图未设置会显示父视图的父视图的tintColor,以此类推。

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:设置windoe的tintColor

首先给Storyboard中的场景嵌套一个NavigationController,然后在场景上面拖放两个Button控件,在右边栏的检查器中将其中一个Button的tintColor进行设置为枚红色,另一个Button的tintColor不做额外设置,如图-17所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-17

然后在TRAppDelegate里面将window的tintColor颜色设置为紫色,代码如下所示:

 
  1. -(BOOL)application:(UIApplication *)application
  2. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  3. {
  4. self.window.tintColor = [UIColor colorWithRed:115.0/255 green:38.0/255 blue:239.0/255 alpha:0.9];
  5. return YES;
  6. }

运行程序发现自定义了tintColor的Button颜色不会改变还是自定义的颜色,未设置tintColor的Button颜色发生了改变,变成了window的tintColor颜色,如图-18所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-18

最后在场景中任意拖放几个控件(Slider,Switch,SegmentedControl),分别都设置各自的tintColor,运行程序发现自定义tintColor的控件都会显示自己的tintColor颜色,而不会显示window的tintColor颜色,如图-19所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-19

步骤二:设置View的tintColor

在Storyboard中新创建一个场景,由第一个场景中的按钮Push过来,给第二个场景的View设置tintColor为绿色,往第二个场景上拖放几个任意的控件(Slider,Switch,Button,SegmentedControl),各个控件的tintColor会自动的变为绿色,这就是tintColor批量设置颜色的功能,如图-20所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-20

然后将第二个场景中的某个控件的tintColor进行自定义,例如将Slider的tintColor设置为蓝色,运行程序发现其他控件的tintColor和View一样是绿色,Slider控件的tintColor则是自定义的蓝色,如图-21所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-21

步骤三:父视图和子视图tintColor之间的关系

在Stroyboard中再创建一个新的场景,由第二个场景的按钮Push出来,在上面拖放几个任意的控件(Slider,Switch,Button,SegmentedControl),第三个场景不做任何tintColor的设置,如图-22所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-22

运行程序发现控件显示的是window的tintColor颜色,如图-23所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-23

由此可以看出如果一个控件没有设置tintColor,那么它会显示父视图的tintColor,如果父视图未设置会显示父视图的父视图的tintColor,以此类推。

4.4 完整代码

本案例中,TRAppDelegate.m文件中的完整代码如下所示:

 
  1. #import "TRAppDelegate.h"
  2. @implementation TRAppDelegate
  3. -(BOOL)application:(UIApplication *)application
  4. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  5. {
  6. self.window.tintColor = [UIColor colorWithRed:115.0/255 green:38.0/255 blue:239.0/255 alpha:0.9];
  7. return YES;
  8. }
  9. @end

5 使用UIAppearance美化控件

5.1 问题

UIAppearance是一个协议,遵守此协议的对象可以批量设置某种控件的外观,例如:颜色、贴图等。本案例使用UIAppearance美化控件,如图-24所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-24

5.2 方案

首先在Storyboard的场景中拖放三个Button控件、一个SegmentedControl控件、一个Slider控件、一个ProgressView。在右边栏的检查器中给三个Button设置不同的字体颜色。

然后在TRAppDelegate的程序入口方法中通过静态方法appearance返回的对象设置UIButton类型控件的背景图片和tintColor,设置其他类型控件的的tintColor。

使用UIAppearance的好处就是可以对同一种类型的控件进行批量设置。

5.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建TRBezierPathView类

首先在Storyboard的场景中拖放三个Button控件、一个SegmentedControl控件、一个Slider控件、一个ProgressView。在右边栏的检查器中给三个Button设置不同的字体颜色,如图-25所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-25

步骤二:通过UIAppearance美化控件

在TRAppDelegate的程序入口方法中通过静态方法appearance返回的对象设置UIButton类型控件的背景图片和tintColor,代码如下所示:

 
  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  2. {
  3. UIImage *image = [UIImage imageNamed:@"delete_btn"];
  4. UIImage *image2 = [image resizableImageWithCapInsets:UIEdgeInsetsMake(5, 5, 5, 5) resizingMode:UIImageResizingModeStretch];
  5. [[UIButton appearance] setBackgroundImage:image2 forState:UIControlStateNormal];
  6. [[UIButton appearance] setTintColor:[UIColor yellowColor]];
  7. return YES;
  8. }

运行程序可以看到三个Button控件的背景图片都被设置了,由于三个Button都设置了各自的文字颜色,所以通过appearance设置的tintColor没有起作用。

然后设置其他控件的tintColor,代码如下所示:

 
  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  2. {
  3. UIImage *image = [UIImage imageNamed:@"delete_btn"];
  4. UIImage *image2 = [image resizableImageWithCapInsets:UIEdgeInsetsMake(5, 5, 5, 5) resizingMode:UIImageResizingModeStretch];
  5. [[UIButton appearance] setBackgroundImage:image2 forState:UIControlStateNormal];
  6. [[UIButton appearance] setTintColor:[UIColor yellowColor]];
  7. [UISlider appearance].tintColor = [UIColor redColor];
  8. [UISegmentedControl appearance].tintColor = [UIColor greenColor];
  9. [UIProgressView appearance].tintColor = [UIColor grayColor];
  10. return YES;
  11. }

运行程序可以看到其他控件的tintColor都显示出来。

5.4 完整代码

本案例中,TRAppDelegate.m文件中的完整代码如下所示:

 
  1. #import "TRAppDelegate.h"
  2. @implementation TRAppDelegate
  3. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  4. {
  5. UIImage *image = [UIImage imageNamed:@"delete_btn"];
  6. UIImage *image2 = [image resizableImageWithCapInsets:UIEdgeInsetsMake(5, 5, 5, 5) resizingMode:UIImageResizingModeStretch];
  7. [[UIButton appearance] setBackgroundImage:image2 forState:UIControlStateNormal];
  8. [[UIButton appearance] setTintColor:[UIColor yellowColor]];
  9. [UISlider appearance].tintColor = [UIColor redColor];
  10. [UISegmentedControl appearance].tintColor = [UIColor greenColor];
  11. [UIProgressView appearance].tintColor = [UIColor grayColor];
  12. return YES;
  13. }
  14. @end

6 美化导航栏NavigationBar

6.1 问题

本案例对导航栏的背景,标题以及状态栏进行设置和美化,如图-26所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-26

6.2 方案

首先在Storyboard中,拖放两个场景分别和TRViewController类和TROtherViewController类绑定。将场景嵌入NavigationController,并在导航栏上面添加一个BarButtonItem,点击按钮Push到第二个场景。

第一步先设置导航栏的tintColor,navigaitonBar有两个属性tintColor和barTintColor,tintColor可以设置导航栏的背景颜色和导航栏子视图的背景颜色,如果只需要设置导航栏的背景颜色,那么设置barTintColor即可。

首先在viewDidLoad里面获取到当前的navigaitionBar对象,设置tintColor属性,并且使用方法setBackgroundImage:forBarMetrics:给navigationBar设置背景图片。

其次设置back按钮的图片,设置navigationBar的backIndicatorImage和backIndicatorTransitionMaskImage属性即可。

然后设置导航栏的标题字体,导航栏标题的文字可以通过setTitleTextAttributes:方法进行设置,atrributes是一个NSDictionary类型的参数,记录标题文字各种属性,包括字体、颜色、字体大小等。

再在Storyboard的场景中拖放一个Button控件,关联成TRViewController的方法hideNavigationBar:,该方法用于实现导航栏的隐藏和显示。

最后设置状态栏,重写方法preferredStatusBarStyle进行状态栏的设置,但是如果存在NavigationBar,那么状态栏的风格由NavigationBar决定,该方法对状态栏的设置则无效。

6.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:设置状态栏的tintColor、图片和back按钮

首先在Storyboard中,拖放两个场景分别和TRViewController类和TROtherViewController类绑定。将场景嵌入NavigationController,并在导航栏上面添加一个BarButtonItem,点击按钮Push到第二个场景。

然后设置导航栏的tintColor和图片,在viewDidLoad里面获取到当前的navigaitionBar对象,设置tintColor属性并且使用方法setBackgroundImage:forBarMetrics:给navigationBar设置背景图片,代码如下所示:

 
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. UINavigationBar *navigationBar = self.navigationController.navigationBar;
  5. //设置导航栏的tintColor
  6. navigationBar.tintColor = [UIColor redColor];
  7. //是否半透明
  8. navigationBar.translucent = YES;
  9. //设置导航栏的barTintColor
  10. navigationBar.barTintColor = [UIColor lightGrayColor];
  11. //设置导航栏的背景图片
  12. [navigationBar setBackgroundImage:[UIImage imageNamed:@"navi1"] forBarMetrics:UIBarMetricsDefault];
  13. //设置横屏状态下的导航栏的背景图片
  14. [navigationBar setBackgroundImage:[UIImage imageNamed:@"navi2"] forBarMetrics:UIBarMetricsLandscapePhone];
  15. }

运行程序可以看到竖屏和横屏的导航栏背静图片不一样,如图-27、图-28所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-27

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-28

最后设置back按钮的图片,设置navigationBar的backIndicatorImage和backIndicatorTransitionMaskImage属性即可,代码如下所示:

 
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. UINavigationBar *navigationBar = self.navigationController.navigationBar;
  5. navigationBar.tintColor = [UIColor redColor];
  6. navigationBar.translucent = YES;
  7. navigationBar.barTintColor = [UIColor lightGrayColor];
  8. [navigationBar setBackgroundImage:[UIImage imageNamed:@"navi1"] forBarMetrics:UIBarMetricsDefault];
  9. [navigationBar setBackgroundImage:[UIImage imageNamed:@"navi2"] forBarMetrics:UIBarMetricsLandscapePhone];
  10. navigationBar.backIndicatorImage = [UIImage imageNamed:@"back_btn"];
  11. navigationBar.backIndicatorTransitionMaskImage = [UIImage imageNamed:@"back_btn"];
  12. }

运行效果如图-29所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-29

步骤二:设置导航栏标题

导航栏标题的文字可以通过setTitleTextAttributes:方法进行设置,atrributes是一个NSDictionary类型的参数,记录标题文字各种属性,包括字体、颜色、字体大小等,代码如下所示:

 
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. UINavigationBar *navigationBar = self.navigationController.navigationBar;
  5. navigationBar.tintColor = [UIColor redColor];
  6. navigationBar.translucent = YES;
  7. navigationBar.barTintColor = [UIColor lightGrayColor];
  8. [navigationBar setBackgroundImage:[UIImage imageNamed:@"navi1"] forBarMetrics:UIBarMetricsDefault];
  9. [navigationBar setBackgroundImage:[UIImage imageNamed:@"navi2"] forBarMetrics:UIBarMetricsLandscapePhone];
  10. navigationBar.backIndicatorImage = [UIImage imageNamed:@"back_btn"];
  11. navigationBar.backIndicatorTransitionMaskImage = [UIImage imageNamed:@"back_btn"];
  12. [navigationBar setTitleTextAttributes:@{
  13. NSFontAttributeName : [UIFont italicSystemFontOfSize:30],NSForegroundColorAttributeName : [UIColor greenColor]
  14. }];
  15. }

运行程序,导航栏的标题如图-30所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-30

然后在Storyboard的场景中拖放一个Button控件,关联成TRViewController的方法hideNavigationBar:,该方法用于实现导航栏的隐藏和显示,点击按钮可以将导航栏隐藏再次点击可以显示,代码如下所示:

 
  1. - (IBAction)hideNavigationBar:(id)sender {
  2. [self.navigationController setNavigationBarHidden:!self.navigationController.navigationBarHidden animated:YES];
  3. }

步骤三:设置状态栏

状态栏的设置方式是通过在TRViewController类中重写方法preferredStatusBarStyle进行状态栏样式的设置,重写方法prefersStatusBarHidden设置是否隐藏状态栏,但是如果存在NavigationBar,那么状态栏的风格由NavigationBar决定,该方法对状态栏的设置则无效。,代码如下所示:

 
  1. //设置状态栏的样式
  2. - (UIStatusBarStyle)preferredStatusBarStyle
  3. {
  4. return UIStatusBarStyleLightContent;
  5. }
  6. //是否隐藏状态栏
  7. - (BOOL)prefersStatusBarHidden
  8. {
  9. return NO;
  10. }

运行程序可以看出,隐藏导航栏和显示导航栏的时候,状态栏的样式是不一样的,如图-31、图-32所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-31

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-32

6.4 完整代码

本案例中,TRViewController.m文件中的完整代码如下所示:

 
  1. #import "TRViewController.h"
  2. @implementation TRViewController
  3. - (void)viewDidLoad
  4. {
  5. [super viewDidLoad];
  6. UINavigationBar *navigationBar = self.navigationController.navigationBar;
  7. //设置导航栏的tintColor
  8. navigationBar.tintColor = [UIColor redColor];
  9. //是否半透明
  10. navigationBar.translucent = YES;
  11. //设置导航栏的barTintColor
  12. navigationBar.barTintColor = [UIColor lightGrayColor];
  13. //设置导航栏的背景图片
  14. [navigationBar setBackgroundImage:[UIImage imageNamed:@"navi1"] forBarMetrics:UIBarMetricsDefault];
  15. //设置横屏状态下的导航栏的背景图片
  16. [navigationBar setBackgroundImage:[UIImage imageNamed:@"navi2"] forBarMetrics:UIBarMetricsLandscapePhone];
  17. navigationBar.backIndicatorImage = [UIImage imageNamed:@"back_btn"];
  18. navigationBar.backIndicatorTransitionMaskImage = [UIImage imageNamed:@"back_btn"];
  19. [navigationBar setTitleTextAttributes:@{
  20. NSFontAttributeName : [UIFont italicSystemFontOfSize:30],NSForegroundColorAttributeName : [UIColor greenColor]
  21. }];
  22. }
  23. //设置状态栏的样式
  24. - (UIStatusBarStyle)preferredStatusBarStyle
  25. {
  26. return UIStatusBarStyleLightContent;
  27. }
  28. //是否隐藏状态栏
  29. - (BOOL)prefersStatusBarHidden
  30. {
  31. return NO;
  32. }
  33. - (IBAction)hideNavigationBar:(id)sender {
  34. [self.navigationController setNavigationBarHidden:!self.navigationController.navigationBarHidden animated:YES];
  35. }
  36. @end

7 给TableViewCell进行贴图美化

7.1 问题

表视图的单元格的背景也同样可以进行美化,本案例对TableView的单元格不同的状态进行贴图美化,如图-33所示:

设备、像素和点 、 9切片技术 、 颜色和外观 、 NavigationBar的美化

图-33

7.2 方案

首先在Storyboard文件创建一个带有导航的表视图控制器,该视图控制器管理的是一个动态表视图,并和TRMyTableViewController类进行绑定。

然后TRMyTableViewController类中实现三问给表视图加载数据,给单元格进行美化的代码主要写在cellForRowAtIndexPath:方法,即创建cell代码之后。

主要是通过设置cell的backgroundView属性和selectedBackgroundView属性进行美化,selectedBackgroundView是单元格被选中之后的样式。

7.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建表视图控制器项目

首先在Storyboard文件创建一个带有导航的表视图控制器,该视图控制器管理的是一个动态表视图,并和TRMyTableViewController类进行绑定。

然后TRMyTableViewController类中实现三问给表视图加载数据,代码如下所示:

 
  1. -(NSInteger)tableView:(UITableView *)tableView
  2. numberOfRowsInSection:(NSInteger)section
  3. {
  4. return 10;
  5. }
  6. -(UITableViewCell *)tableView:(UITableView *)tableView
  7. cellForRowAtIndexPath:(NSIndexPath *)indexPath
  8. {
  9. static NSString *CellIdentifier = @"MyCell";
  10. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
  11. cell.textLabel.text = @"Hello World.";
  12. return cell;
  13. }

步骤二:美化单元格

给单元格进行美化的代码主要写在cellForRowAtIndexPath:方法,即创建cell代码之后,主要是通过设置cell的backgroundView属性和selectedBackgroundView属性进行美化,selectedBackgroundView是单元格被选中之后的样式,代码如下所示:

 
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  2. {
  3. static NSString *CellIdentifier = @"MyCell";
  4. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
  5. cell.textLabel.text = @"Hello World.";
  6. cell.backgroundView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"list"]];
  7. cell.selectedBackgroundView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"listSelected"]];
  8. return cell;
  9. }

7.4 完整代码

本案例中,TRMyTableViewController.m文件中的完整代码如下所示:

 
  1. #import "TRMyTableViewController.h"
  2. @implementation TRMyTableViewController
  3. #pragma mark - Table view data source
  4. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  5. {
  6. return 10;
  7. }
  8. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  9. {
  10. static NSString *CellIdentifier = @"MyCell";
  11. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
  12. cell.textLabel.text = @"Hello World.";
  13. cell.backgroundView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"list"]];
  14. cell.selectedBackgroundView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"listSelected"]];
  15. return cell;
  16. }
  17. @end