tabBar是UITabBar对象, 包含多个UITabBarItem,每一个tabBaritem对应一个viewController.
tabBar高度49
三大视图 :UITabBarController、 UINavigationController、UITabViewController 通常组合出现;
UITabBarController可以嵌套UINavigationController
// block
在使用的过程中可能会产生循环引用。
// 1.
为什么
? (
面试题
:)
//
因为
block
在当时定义的时候
,
相当于使用的是
setter
方法。
,
而且语义设置用的是
copy
。
如果在内部使用
self
的相关属性、实例变量都会对他们的引用加
1.!!!!!!
// 2.怎么解决?
//
为了防止产生循环引用
,
会对使用之前定义一个新的指针变量指向
self,
而且是弱引用即
__block
。
(
在
arc
下用
"__weak")!!
// Block:
匿名函数
// 根据有无返回值、有无参数可以分为四种 :
// 一 : 有返回值 , 有参数
// 二 : 有返回值 , 无参数
// 三 : 无返回值 , 有参数
// 四 : 无返回值 , 无参数
// block 使用分为两部分 : 定义 ( 实现 ), 调用 ( 回调 );
// 第一种 :
// 定义一个字符串类型 , 参数为 int 类型的 Block. 名字为 myBlock 。作用是将 int 类型的数据转化为字符串类型。
// 第一种 : 有返回值 , 有参数
// 1. 定义
NSString *(^myBlock)( int a) = ^ NSString *( int a) {
return [ NSString stringWithFormat : @"%d" , a];
};
// 2. 调用
NSString *str = myBlock( 6 ); // block 的调用
// 上面的 block 中返回值类型是什么 -- NSString; block 名字是什么 -- myBlock; block 类型是什么 ?-- NSString *(^)(int)
// 第二种 : 有返回值 , 无参数
int (^myBlock1)() = ^{
return 1 ;
};
// 第三种 : 无返回值 , 有参数
void (^myBlock2)( int a) = ^( int a) {
NSLog ( @"%d" , a);
};
// 第四种 : 无返回值 , 无参数
void (^myBlock3)() = ^{
NSLog ( @"" );
// 根据有无返回值、有无参数可以分为四种 :
// 一 : 有返回值 , 有参数
// 二 : 有返回值 , 无参数
// 三 : 无返回值 , 有参数
// 四 : 无返回值 , 无参数
// block 使用分为两部分 : 定义 ( 实现 ), 调用 ( 回调 );
// 第一种 :
// 定义一个字符串类型 , 参数为 int 类型的 Block. 名字为 myBlock 。作用是将 int 类型的数据转化为字符串类型。
// 第一种 : 有返回值 , 有参数
// 1. 定义
NSString *(^myBlock)( int a) = ^ NSString *( int a) {
return [ NSString stringWithFormat : @"%d" , a];
};
// 2. 调用
NSString *str = myBlock( 6 ); // block 的调用
// 上面的 block 中返回值类型是什么 -- NSString; block 名字是什么 -- myBlock; block 类型是什么 ?-- NSString *(^)(int)
// 第二种 : 有返回值 , 无参数
int (^myBlock1)() = ^{
return 1 ;
};
// 第三种 : 无返回值 , 有参数
void (^myBlock2)( int a) = ^( int a) {
NSLog ( @"%d" , a);
};
// 第四种 : 无返回值 , 无参数
void (^myBlock3)() = ^{
NSLog ( @"" );
};
Block的传值步骤:
#warning 1.
重定义一个
block
。
(P
首字母大写因为是一个类
)
typedef
void
(^PassValueBlock)(
NSString
*value);
#warning 2.
设置属性
(
在将
block
定义成属性的时候需要将其进行
copy
。
因为定义的
block
本身是在全局区或者栈区
,
为了能够管理
block
需要把它拷贝堆区
,
由程序员管理。
)
@property
(
nonatomic
,
copy
)
PassValueBlock
passValue;
#warning 3.
给
Block
属性赋值
__block
FirstViewController
*Test =
self
;
bVC.
passvalue
= ^
void
(
NSString
*value) {
Test.
label
.
text
= value;
};
#warning 4.
传值
//
不添加返回键
,
系统自带返回方法
!!!
// willDidDisappear(
第二种情况
)
- (
void
)viewWillDisappear:(
BOOL
)animated {
// 1. 先引用系统中父类的方法
[ super viewWillDisappear :animated];
// 2. 对 block 的值进行判断
if ( self . passValue != nil ) {
UITextField *textField = ( UITextField *) self . view . subviews [ 0 ];
self . passValue (textField. text );
// 1. 先引用系统中父类的方法
[ super viewWillDisappear :animated];
// 2. 对 block 的值进行判断
if ( self . passValue != nil ) {
UITextField *textField = ( UITextField *) self . view . subviews [ 0 ];
self . passValue (textField. text );
}
}
属性传值的步骤: (从前往后传)
#warning 1.
定义属性。
(PS:
外界传什么类型的数据,就定义成什么类型的数据。
)
@property
(
nonatomic
,
retain
)
NSString
*text;
#warning 2.
给相关属性赋值。
secondVC.
text
= textField.
text
;
#warning 3.
使用外界传过来的值。
label.
text
=
_text
;
代理传值的步骤:(从后往前传值)
#warning 2-1.
定义协议。
(
协议中的方法参数类型是想从第二个界面往外传什么类型,就是什么类型的。
)
@protocol SecondVCDelegate < NSObject >
- ( void )passValue:( NSString *)value;
@protocol SecondVCDelegate < NSObject >
- ( void )passValue:( NSString *)value;
@end
#warning 2-2
定义
delegate
属性,给外界提供接口。
@property
(
nonatomic
,
assign
)
id
<
SecondVCDelegate
>delegate;
#warning 2-3.
给
delegate
属性赋值。
secondVC.
delegate
=
self
;
#warning
面试题
:
协议指的的是一堆方法的声明
#warning 2-4. 接收协议
#warning 2-4. 接收协议
@interface
RootViewController
() <
SecondVCDelegate
>
#warning 2-5.
实现协议中的方法
#pragma mark - 协议
- ( void )passValue:( NSString *)value {
// 给第一个界面的 textField 的 text 赋值。
UITextField *textField = [ self . view . subviews objectAtIndex : 0 ];
textField. text = value;
#pragma mark - 协议
- ( void )passValue:( NSString *)value {
// 给第一个界面的 textField 的 text 赋值。
UITextField *textField = [ self . view . subviews objectAtIndex : 0 ];
textField. text = value;
}
#warning 2-6.
在某一个时间点让
delegate
去执行协议中的方法
if ( _delegate && [ _delegate respondsToSelector : @selector (passValue:)]) {
UITextField *textField = [ self . view . subviews objectAtIndex : 1 ];
[ _delegate passValue :textField. text ];
if ( _delegate && [ _delegate respondsToSelector : @selector (passValue:)]) {
UITextField *textField = [ self . view . subviews objectAtIndex : 1 ];
[ _delegate passValue :textField. text ];
}