IOS开发——UI进阶篇(十)导航控制器、plist存储、微博详情页

一、导航控制器出栈



1、initWithRootViewController本质

    UIViewController *vc = [[OneViewController alloc] init];
    // 创建导航控制器
    // 导航控制器必须要有一个根控制器
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
    // 会调用push方法
    // initWithRootViewController底层其实是调用导航控制器的push方法,把vc成为导航控制器的子控制器
    // 一旦把一个控制器压入到栈,就会把这个控制器的view添加到导航控制器的view上
    //    [nav pushViewController:vc animated:YES];

2、回到上个控制器或者根控制器

// 回到上一个控制器
- (IBAction)back2Pre:(id)sender {

    // 导航控制器中做界面之间的跳转必须拿到导航控制器
    [self.navigationController popViewControllerAnimated:YES];

    // 调用pop方法并不会马上销毁当前控制器

}
// 回到根控制器
- (IBAction)back2Root:(id)sender {

//    [self.navigationController popToRootViewControllerAnimated:YES];

    // 还有一种方法:指定回到哪个控制器
    // popToViewController使用注意点,传入进去的控制器必须是导航控制器栈里面的控制器
    [self.navigationController popToViewController:self.navigationController.childViewControllers[0] animated:YES];
}

二、设置导航条内容



1、UINavigationItem:是一个模型,决定导航条的内容(左边内容,中间,右边内容)
2、UIBarButtonItem:是一个模型,决定导航条上按钮的内容
只要看到item,通常都是苹果提供的模型,只要改模型就能修改苹果的某些控件.

         // 1、设置导航条的标题
    self.navigationItem.title = @"chg";
    self.navigationItem.titleView = [UIButton buttonWithType:UIButtonTypeContactAdd];

        // 2、设置导航条左边的内容
    UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithTitle:@"abc" style:UIBarButtonItemStyleDone target:self action:@selector(leftClick)];
    self.navigationItem.leftBarButtonItem = leftItem;

        // 3、设置导航条右边的内容

    // 在iOS7之后,默认会把导航条上的按钮的图片渲染成蓝色.
    // 不想要渲染导航条上的按钮的图片颜色
    UIImage *image = [UIImage imageNamed:@"navigationbar_friendsearch"];
    // 告诉苹果哪个图片不要渲染
    image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

    // UIBarButtonItem
    UIBarButtonItem *rigthItem = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStyleDone target:nil action:nil];

    // 创建按钮
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    // 正常
    [btn setBackgroundImage:[UIImage imageNamed:@"navigationbar_friendsearch"] forState:UIControlStateNormal];
    // 高亮
    [btn setBackgroundImage:[UIImage imageNamed:@"navigationbar_friendsearch_highlighted"] forState:UIControlStateHighlighted];

    // 导航条上的子控件位置不需要我们管理,只需要管理尺寸
    btn.frame = CGRectMake(0, 2000, 30, 30);

    UIBarButtonItem *rigthItem1 = [[UIBarButtonItem alloc] initWithCustomView:btn];

    // self.navigationItem.rightBarButtonItem = rigthItem;
    // 可添加多个
    self.navigationItem.rightBarButtonItems = @[rigthItem,rigthItem1];

三、控制器的View的生命周期


// 监听控制器的view的生命周期方法
// 控制器的view的生命周期方法都是以view开头

// 控制器的view即将显示的时候调用
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
     NSLog(@"%s",__func__);
}

// 控制器的view完全显示的时候调用
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
     NSLog(@"%s",__func__);
}
// 控制器的view即将消失的时候调
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
     NSLog(@"%s",__func__);
}

// 控制器的view完全消失的时候调
- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
     NSLog(@"%s",__func__);
}

// 控制器的view即将布局子控件的时候调用
- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
     NSLog(@"%s",__func__);
}
// 控制器的view布局子控件完成的时候调用
- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
     NSLog(@"%s",__func__);
}

// 当控制器的view加载完成的时候调用
- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"%s",__func__);
}

执行顺序: viewDidLoad ->  viewWillAppear ->  viewWillLayoutSubviews -> viewDidLayoutSubviews ->  viewDidAppear -> viewWillDisappear -> viewDidDisappear

在非ARC中经常使用

// Unload:卸载这个view
- (void)viewWillUnload
{
    [super viewWillUnload];
}

// 表示控制器的view卸载完成
- (void)viewDidUnload
{
    [super viewDidUnload];

    // 清空界面上的数据
    self.datas = nil;

}
清空界面原理:
- (void)setDatas:(NSMutableArray *)datas
{
    if (_datas != datas) {
        _datas = [datas retain];
        [datas release];
    }
}

四、微博个人详情页



大致的功能如上,导航条和文字的透明度随着移动而变化,粉红色视图有悬浮效果,并且鲨鱼图片随着滚动等比缩放,始终与粉红色视图紧挨在一起

1、搭建框架

首先拖一个Navigation Controller

设置这个控制器的根控制器为右边的View Controller

那么现在主要精力放在View Controller上

首先最底部是View Controller的view

view上面有Table View、粉红色的视图、最上面的头部视图

头部视图上面有鲨鱼图片和鸣人图片

注意:Table View必须铺满整个View Controller的view 【在代码中设置上面的额外滚动高度为(粉红色的视图的高度+最上面的头部视图的高度)】

具体结构图如下:

2、实现代码如下:

  1 #import "ViewController.h"
  2 // 1.项目结构:导航控制器,导航控制器上添加一个个人详情控制器
  3 // 2.分析个人详情页的结构
  4 // 2.1 tableView(尺寸跟控制器尺寸一样大)
  5 // 2.2 头部视图不能是tableView的头部视图 + 粉红色的选项卡视图不能是tabelView的头部视图
  6 // 2.3 tableView的头部视图没有悬停效果,tableView分组的头部视图才有悬停效果
  7
  8 #import "UIImage+Image.h"
  9
 10 @interface ViewController ()<UITableViewDelegate>
 11 @property (weak, nonatomic) IBOutlet UITableView *tableView;
 12
 13 // 记录一开始lastOffsetY
 14 @property (nonatomic, assign) CGFloat lastOffsetY;
 15
 16 //@property (weak, nonatomic) IBOutlet NSLayoutConstraint *headYCons;
 17 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *headHCons;
 18
 19
 20 @property (nonatomic, weak) UILabel *label;
 21
 22 @end
 23
 24 #define XMGHeadH 200
 25 #define XMGHeadMinH 64
 26 #define XMGTabBarH 44
 27
 28 @implementation ViewController
 29
 30 - (void)viewDidLoad {
 31     [super viewDidLoad];
 32     // Do any additional setup after loading the view, typically from a nib.
 33
 34     // 在iOS7之后,导航控制器下的所有UIScrollView默认顶部都会添加64的额外滚动区域.
 35     // 不需要添加额外的滚动区域
 36     self.automaticallyAdjustsScrollViewInsets = NO;
 37
 38     // 一开始y轴滚动区域是-244.
 39     _lastOffsetY = - (XMGHeadH + XMGTabBarH);
 40
 41     // 设置tableView顶部的额外的滚动区域(选项卡的高度 + 头部视图的高度)
 42     self.tableView.contentInset = UIEdgeInsetsMake(XMGHeadH + XMGTabBarH, 0, 0, 0);
 43
 44     // 清空导航条的背景
 45     // 如何快速的清空导航条背景图片,直接传入一个空图片的UIImage对象
 46     [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
 47     // 清空阴影图片
 48     [self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
 49
 50     // 设置导航条标题
 51     UILabel *label = [[UILabel alloc] init];
 52
 53     _label = label;
 54
 55     label.textColor = [UIColor colorWithWhite:1 alpha:0];
 56
 57     label.text = @"chg的个人主页";
 58
 59     // 自动计算当前label文字尺寸,并且设置控件的尺寸和文字尺寸一样.
 60     [label sizeToFit];
 61
 62     self.navigationItem.titleView = label;
 63
 64 }
 65 // 返回tableView有多少行
 66 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 67 {
 68     return 20;
 69 }
 70
 71 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 72 {
 73     static NSString *ID = @"cell";
 74
 75     // 从缓存池中获取cell
 76     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
 77
 78     if (cell == nil) {
 79         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
 80         cell.backgroundColor = [UIColor redColor];
 81     }
 82
 83     cell.textLabel.text = [NSString stringWithFormat:@"%ld",indexPath.row];
 84
 85     return cell;
 86 }
 87
 88 #pragma mark - 监听tableView滚动
 89 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
 90 {
 91     // 获取当前滚动的偏移量值contentOffset
 92     CGFloat offsetY = scrollView.contentOffset.y;
 93
 94
 95     // contentOffset:tableView可视范围顶点与内容开始点的偏移量,内容开始点的contentOffset = 0;
 96
 97     // 计算下用户相对最开始偏移量滚动的多少
 98     CGFloat delta = offsetY - _lastOffsetY;
 99
100     // 移动头部视图
101     // 当往上移动的时候,头部视图需要往上移动,高度值需要减少
102     CGFloat headH = XMGHeadH - delta;
103
104     // 如果小于最小高度,就不在减少了
105     if (headH < XMGHeadMinH) {
106         headH = XMGHeadMinH;
107     }
108
109     _headHCons.constant = headH;
110
111     // 处理导航条
112     // 获取当前透明度,当用户移动136的时候透明度刚好为1,delta就是用户移动的距离.
113     CGFloat alpha = delta / (XMGHeadH - XMGHeadMinH) * 1;
114
115     if (alpha > 1) {
116         alpha = 0.99;
117     }
118
119     // 描述颜色
120     UIColor *color = [UIColor colorWithWhite:1 alpha:alpha];
121
122     // 设置导航条背景图片的透明度
123     [self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:color] forBarMetrics:UIBarMetricsDefault];
124
125     // 设置文字的透明度
126     _label.textColor = [UIColor colorWithWhite:0 alpha:alpha];
127 }
128
129 @end

这里的headHCons是头部视图的约束高度。

3.根据颜色生成一张1*1的相同颜色图片

UIImage+Image.h

#import <UIKit/UIKit.h>

@interface UIImage (Image)

// 根据颜色生成一张尺寸为1*1的相同颜色图片
+ (UIImage *)imageWithColor:(UIColor *)color;

@end

UIImage+Image.m

#import "UIImage+Image.h"

@implementation UIImage (Image)

+ (UIImage *)imageWithColor:(UIColor *)color
{
    // 描述矩形
    CGRect rect=CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);

    // 开启位图上下文
    UIGraphicsBeginImageContext(rect.size);
    // 获取位图上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    // 使用color演示填充上下文
    CGContextSetFillColorWithColor(context, [color CGColor]);
    // 渲染上下文
    CGContextFillRect(context, rect);
    // 从上下文中获取图片
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    // 结束上下文
    UIGraphicsEndImageContext();

    return theImage;
}

@end

到这里功能基本也就实现了

时间: 2024-10-09 13:07:09

IOS开发——UI进阶篇(十)导航控制器、plist存储、微博详情页的相关文章

IOS开发——UI进阶篇(八)pickerView简单使用,通过storyboard加载控制器,注册界面,通过xib创建控制器,控制器的view创建,导航控制器的基本使用

一.pickerView简单使用 1.UIPickerViewDataSource 这两个方法必须实现 // 返回有多少列 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView; // 返回第component有多少行 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;

IOS开发——UI进阶篇(十五)Quartz2D介绍

一.Quartz2D简介 1.什么是Quartz2DQuartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作绘制图形 : 线条\三角形\矩形\圆\弧等绘制文字绘制\生成图片(图像)读取\生成PDF截图\裁剪图片自定义UI控件 2.Quartz2D实例Quartz 2D能做很多强大的事情,例如 裁剪图片 涂鸦\画板 手势解锁 报表:折线图\饼状图\柱状图 二.自定义view 1.Quartz2D在iOS开发中的价值为了便于搭建美观的UI界面,iOS提供了UI

IOS开发——UI进阶篇(十四)modal

一.modal与pushmodal从下面往上盖住原来的控制器,一般上一个控制器和下一个控制器没有什么关联时用modal,比如联系人的加号跳转页面,任何控制器都可以用modal push一般是上下文有关联时用,(比如设置界面的通用跳转页面)导航控制器才能用push A控制器modal出B控制器,那么A控制器就会强引用B,如果不强引用,无法处理B的业务逻辑(比如点击按钮回答A),会报野指针错误 // modal另一个界面 - (IBAction)modal:(id)sender { // 创建mod

IOS开发——UI进阶篇(十一)应用沙盒,归档,解档,偏好设置,plist存储,NSData,自定义对象归档解档

1.iOS应用数据存储的常用方式XML属性列表(plist)归档Preference(偏好设置)NSKeyedArchiver归档(NSCoding)SQLite3 Core Data 2.应用沙盒每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Layer)模拟器应用沙盒的根路径在: (apple是用户名, 8.0是模拟器版本)/Users/apple/Libra

IOS开发——UI进阶篇(十六)Quartz2D实战小例子

一.画线 只有在drawRect中才能获取到跟view相关联的上下文 - (void)drawRect:(CGRect)rect {} 一条线 // 1.获取跟当前View相关联的layer上下文(画板) // 总结:目前获取的所有上下文都是以UIGraphics开头 // CGContextRef:上下文类型 // CG:CoreGraphics Ref:引用 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 2.绘制内容,拼接路径 //

IOS开发——UI进阶篇(十二)事件处理,触摸事件,UITouch,UIEvent,响应者链条,手势识别

触摸事件 在用户使用app过程中,会产生各种各样的事件 一.iOS中的事件可以分为3大类型 触摸事件加速计事件远程控制事件 响应者对象在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件.我们称之为“响应者对象” UIApplication.UIViewController.UIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件 二.UIResponder UIResponder内部提供了以下方法来处理事件触摸事件- (v

iOS开发——UI进阶篇(十九)UISearchBar控件简介

最近用到搜索功能.总结一下 搜索,无疑可以使用UISearchBar控件! 那就先了解一下UISearchBar控件吧! UISearchBar控件就是要为你完成搜索功能的一个专用控件.它集成了很多你意想不到的功能和特点! 首先,还是来普及一下UISearchBar控件API相关的属性和方法吧! UISearchBar属性相关 _searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];// 初始化,不解释 [self.searchBa

IOS开发——UI进阶篇(十八)核心动画小例子,转盘(裁剪图片、自定义按钮、旋转)图片折叠、音量震动条、倒影、粒子效果

一.转盘(裁剪图片.自定义按钮.旋转) 1.裁剪图片 将一张大图片裁剪为多张 // CGImageCreateWithImageInRect:用来裁剪图片 // image:需要裁剪的图片 // rect:裁剪图片的尺寸,传递是像素 CGImageRef norImage = CGImageCreateWithImageInRect(norBigImage.CGImage, clipRect); 2.每次点击按钮立马变为选中状态,并且取消上次的按钮的选中状态 当然还要重写- (void)setH

IOS开发——UI进阶篇(十七)CALayer,核心动画基本使用

一.CALayer简介 1.CALayer在iOS中,文本输入框.一个图标等等,这些都是UIView你能看得见摸得着的东西基本上都是UIView,比如一个按钮.一个文本标签.一个其实UIView之所以能显示在屏幕上,完全是因为它内部的一个图层 在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性可以访问这个层 @property(nonatomic,readonly,retain) CALayer *layer; 当UIView需