UI加强(三)之TabbarController, 键盘弹出的通知小结,modal控制器

 

 

 

 

---恢复内容结束---

未完待续,先把代码上传到文件中去...

 代理属性用weak修饰

block属性用copy修饰

为什么???

还有block的三种写法

1.typedef

2.@property (nonatomic,copy)dispatch_block_t listBlock;

3.直接写

还有:代理,通知,block这三种传递数据方法的总结:

 

 

 

 

 

 

 

1.UITabBarController和UINavigationController的常用属性总结:

 

UINavigationController属性:

1.self.title 和self.navigationItem.title以及self.tabBarItem.title的区别

只要设置self.title,那么self.navigationItem.title和self.tabBarItem.title值不管设置与否都和self.title一致

所以,一般情况下不要直接设置self.title,需要navigationItem.title就设置navigationItem.title,需要tabBarItem.title就设置tabBarItem.title

2.如上图:navigationItem可以设置:title,titleView,left/right barButtonItem,backBarButtonItem

    navigationBar可以设置:tintColor,transluCent

注意:渲染颜色只能用:

vc1.navigationController.navigationBar.barTintColor = [UIColor redColor];

不能写成:

[vc1.navigationController.navigationBar setTintColor:[UIColor redColor]];

因为这种设置不上去

还要注意一点经常很容易犯的错误:见代码红色部分

//
//  AppDelegate.m
//  nav练习第二波
//
//  Created by 曹魏 on 2016/11/30.
//  Copyright © 2016年 itcast. All rights reserved.
//

#import "AppDelegate.h"
#import "FirstTableViewController.h"
@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //1.实例化window
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    //2.设置window的背景颜色
    self.window.backgroundColor = [UIColor whiteColor];
    //3.实例化一个导航控制器
    UINavigationController *nav = [[UINavigationController alloc]init];
    //4.实例化一个tabbleView控制器
    FirstTableViewController *first = [[FirstTableViewController alloc]init];
    //5.设置tabbleView的背景颜色
    first.tableView.backgroundColor = [UIColor blueColor];
//写在这儿是不显示的
// [tabbleVC.navigationController.navigationBar setTranslucent:NO]; //6.管理子控制器 nav.viewControllers = @[first]; //这两行代码的位置要注意,一定要写在第6步下面,如果写在上面是无法显示的,因为,我必须先管理这个控制器再设置navigationBar的一些属性 first.navigationController.navigationBar.barTintColor = [UIColor redColor]; [first.navigationController.navigationBar setTranslucent:NO]; //千万不要设置navigationController的对象nav上,因为是无效的 //7.设置window的根控制器 self.window.rootViewController = nav; //8.使window成为主窗口并可见 [self.window makeKeyAndVisible]; return YES; }

3.基本属性设置如下代码所示:

//
//  AppDelegate.m
//  UINavigationController小结
//
//  Created by 曹魏 on 2016/11/30.
//  Copyright © 2016年 itcast. All rights reserved.
//

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //1.实例化一个window
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    //2.设置window的背景颜色
    self.window.backgroundColor = [UIColor whiteColor];
    //3.实例化一个导航控制器
    UINavigationController *nav = [[UINavigationController alloc]init];
    
    //4.实例化一个控制器
    UITableViewController *vc1 = [[UITableViewController alloc]init];
    vc1.view.backgroundColor = [UIColor grayColor];
    //4.1设置title
    vc1.navigationItem.title = @"隔壁老王";
//    vc1.title = @"主界面";
//    4.2设置titleview(会覆盖title)
    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 60, 35)];
    imageView.image = [UIImage imageNamed:@"navigationbar_friendsearch"];
    
    
    vc1.navigationItem.titleView = imageView;
    //4.3设置返回按钮
    vc1.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil];
    //4.4添加导航栏左边的按钮
    vc1.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];
    //4.5添加导航栏右边的按钮
    vc1.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:nil action:nil];
    
    
//    [vc1.navigationController.navigationBar setBarStyle:UIBarStyleBlack];
    

    
    UITableViewController *vc2 = [[UITableViewController alloc]init];
    vc2.view.backgroundColor = [UIColor purpleColor];
    //设置title
    vc2.navigationItem.title = @"天龙八部";
    //5.管理该控制器
    nav.viewControllers = @[vc1,vc2];
    
    //4.6设置渲染颜色
//    [vc1.navigationController.navigationBar setTintColor:[UIColor redColor]];
    vc1.navigationController.navigationBar.barTintColor = [UIColor redColor];
    [vc1.navigationController.navigationBar setTranslucent:NO];
//    [vc1.navigationController.navigationBar setBarStyle:UIBarStyleBlack];
    //6.设置window的根控制器
    self.window.rootViewController = nav;
    //7.使window成为主窗口并可见
    [self.window makeKeyAndVisible];
    
    
    
    
    return YES;
}

@end

UITabBarController的基本属性:

代码没有进行封装,但相对很完整,看效果图

//
//  AppDelegate.m
//  tabbarController的小练习
//
//  Created by 曹魏 on 2016/11/30.
//  Copyright © 2016年 itcast. All rights reserved.
//

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //1.实例化window
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    //2.设置window的背景颜色
    self.window.backgroundColor = [UIColor whiteColor];
    //3.实例化tabbar控制器
    UITabBarController *tab = [[UITabBarController alloc]init];
    //4.实例化taberviewController
    
    UITableViewController *first = [[UITableViewController alloc]init];
    first.tableView.backgroundColor = [UIColor purpleColor];
    //设置第一个控制器的属性
    first.tabBarItem.title = @"微信";
    //设置title文字颜色
//设置title文字颜色这个要注意,这个方法不好记
[first.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor colorWithRed:31/255.0 green:185/255.0 blue:34/255.0 alpha:1.0]} forState:UIControlStateSelected]; //设置图片 first.tabBarItem.image = [UIImage imageNamed:@"tabbar_mainframe"]; //设置选中状态下的图片 first.tabBarItem.selectedImage = [[UIImage imageNamed:@"tabbar_mainframeHL"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

//设置信息


      first.tabBarItem.badgeValue = @"10";


    UITableViewController *second = [[UITableViewController alloc]init];
    second.tableView.backgroundColor = [UIColor redColor];
    second.tabBarItem.title = @"通讯录";
    //设置图片
    second.tabBarItem.image = [UIImage imageNamed:@"tabbar_contacts"];
    //设置选中状态下的图片
    second.tabBarItem.selectedImage = [[UIImage imageNamed:@"tabbar_contactsHL"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    //设置title文字颜色
    [second.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor colorWithRed:31/255.0 green:185/255.0 blue:34/255.0 alpha:1.0]} forState:UIControlStateSelected];
    
    
    UITableViewController *third = [[UITableViewController alloc]init];
    third.tableView.backgroundColor = [UIColor grayColor];
    third.tabBarItem.title = @"发现";
    //设置图片
    third.tabBarItem.image = [UIImage imageNamed:@"tabbar_discover"];
    //设置选中状态下的图片
    third.tabBarItem.selectedImage = [[UIImage imageNamed:@"tabbar_discoverHL"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    //设置title文字颜色
    [third.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor colorWithRed:31/255.0 green:185/255.0 blue:34/255.0 alpha:1.0]} forState:UIControlStateSelected];
    
    UITableViewController *four = [[UITableViewController alloc]init];
    four.tableView.backgroundColor = [UIColor yellowColor];
    four.tabBarItem.title = @"";
    //设置title文字颜色
    [four.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor colorWithRed:31/255.0 green:185/255.0 blue:34/255.0 alpha:1.0]} forState:UIControlStateSelected];
    
    //设置图片
    four.tabBarItem.image = [UIImage imageNamed:@"tabbar_me"];
    //设置选中状态下的图片
    four.tabBarItem.selectedImage = [[UIImage imageNamed:@"tabbar_meHL"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    
    //5.管理控制器
    tab.viewControllers = @[first,second,third,four];
    //6.设置window的根控制器
    self.window.rootViewController = tab;
    //7.使window成为主窗口并可见
    [self.window makeKeyAndVisible];
    return YES;
}@end

       

2.UITabBarController和UINavigationController的区别总结:

TabBarController 在进行界面切换, 没有看到的控制器, 没有被销毁

NavigationController控制器在pop操作后会被销毁

StoryBoard中跳转界面时二者的区别:

NavigationController跳转的时候选择的是用push

TabBarController跳转的时候选择的是view controllers(数组,有序)

 3.键盘弹出的通知小结:

//
//  ViewController.m
//  键盘响应小练习第二种
//
//  Created by 曹魏 on 2016/12/2.
//  Copyright © 2016年 itcast. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()<UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *phoneField;
@property (weak, nonatomic) IBOutlet UITextField *addressField;
@property (nonatomic,assign) CGFloat maxY;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //取消自动联想功能
    _nameField.autocorrectionType = UITextAutocorrectionTypeNo;
    _phoneField.autocorrectionType = UITextAutocorrectionTypeNo;
    _addressField.autocorrectionType = UITextAutocorrectionTypeNo;
    //设置代理
    _nameField.delegate = self;
    _phoneField.delegate = self;
    _addressField.delegate = self;
    
    //当我点击textfield的时候,系统会发出一些通知,我通过添加控制器为监听者来监听各种通知
    //从而实现view的上移
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeKeyboard:) name:UIKeyboardWillChangeFrameNotification object:nil];
    
    
}
- (void)changeKeyboard:(NSNotification *)notification{
    
    NSLog(@"键盘事件 %@",notification);
    //    {name = UIKeyboardWillShowNotification; userInfo = {
    //        UIKeyboardAnimationCurveUserInfoKey = 7;   执行动画的方式,执行动画的样式
    //        UIKeyboardAnimationDurationUserInfoKey = "0.25";  动画执行的时间
    //        UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {375, 258}}"; 键盘的bounds
    //        UIKeyboardCenterBeginUserInfoKey = "NSPoint: {187.5, 796}"; 键盘开始(为显示)的中心点
    //        UIKeyboardCenterEndUserInfoKey = "NSPoint: {187.5, 538}";  键盘结束(已经显示)的中心店
    //        UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 667}, {375, 258}}"; 键盘未显示时的frame
    //        UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 409}, {375, 258}}"; 键盘结束时的frame
    //        UIKeyboardIsLocalUserInfoKey = 1; 是否是当前弹出的键盘
    //    }
    
    NSDictionary *userInfo = notification.userInfo;
    //动画
    CGFloat duration = [userInfo[@"UIKeyboardAnimationDurationUserInfoKey"] floatValue];
    //获取键盘弹出后的frame
    CGFloat keyBoardY = [userInfo[@"UIKeyboardFrameEndUserInfoKey"] CGRectValue].origin.y;
    [UIView animateWithDuration:duration animations:^{
        
        if (_maxY > keyBoardY) {
            CGFloat move = keyBoardY - _maxY - 10;
            self.view.transform = CGAffineTransformMakeTranslation(0, move);
        }else{
            self.view.transform = CGAffineTransformIdentity;
        }
        
    }];
    
}
#pragma mark -- 实现代理方法
- (void)textFieldDidBeginEditing:(UITextField *)textField{
    //获取textfield的frame最大y值
    _maxY = CGRectGetMaxY(textField.frame);
    
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //取消第一响应者
    [self.view endEditing:YES];
}
@end

小结:1:当我点击textField的时候,如果是在storyBoard中添加控件并连线的方式的话,系统会自动在我点击的时候,让该textField成为第一响应者(效果也就是弹出键盘)

当我用纯代码写的时候,我点击textField是不会自动弹出键盘的,这个时候必须要加一句代码:[self.textField becomeFirstResponder];才可以.

2:当我点击textField的时候,系统会发出相应的通知,详细见下方,可根据相应的通知采取相应的办法去完成键盘的变化

UIKIT_EXTERN NSNotificationName const UIWindowDidBecomeVisibleNotification; // nil
UIKIT_EXTERN NSNotificationName const UIWindowDidBecomeHiddenNotification;  // nil
UIKIT_EXTERN NSNotificationName const UIWindowDidBecomeKeyNotification;     // nil
UIKIT_EXTERN NSNotificationName const UIWindowDidResignKeyNotification;     // nil

// Each notification includes a nil object and a userInfo dictionary containing the
// begining and ending keyboard frame in screen coordinates. Use the various UIView and
// UIWindow convertRect facilities to get the frame in the desired coordinate system.
// Animation key/value pairs are only available for the "will" family of notification.
UIKIT_EXTERN NSNotificationName const UIKeyboardWillShowNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIKeyboardDidShowNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIKeyboardWillHideNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIKeyboardDidHideNotification __TVOS_PROHIBITED;

UIKIT_EXTERN NSString *const UIKeyboardFrameBeginUserInfoKey        NS_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED; // NSValue of CGRect
UIKIT_EXTERN NSString *const UIKeyboardFrameEndUserInfoKey          NS_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED; // NSValue of CGRect
UIKIT_EXTERN NSString *const UIKeyboardAnimationDurationUserInfoKey NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED; // NSNumber of double
UIKIT_EXTERN NSString *const UIKeyboardAnimationCurveUserInfoKey    NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED; // NSNumber of NSUInteger (UIViewAnimationCurve)
UIKIT_EXTERN NSString *const UIKeyboardIsLocalUserInfoKey           NS_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED; // NSNumber of BOOL

// Like the standard keyboard notifications above, these additional notifications include
// a nil object and begin/end frames of the keyboard in screen coordinates in the userInfo dictionary.
UIKIT_EXTERN NSNotificationName const UIKeyboardWillChangeFrameNotification  NS_AVAILABLE_IOS(5_0) __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIKeyboardDidChangeFrameNotification   NS_AVAILABLE_IOS(5_0) __TVOS_PROHIBITED;

上述只是第一种思路去让键盘弹出发出通知达到输入框上移的效果,这种思路比较有针对性,就是经过了一个判断:当键盘没有盖住输入框时,不上移,盖住了才上移,下面还有一种方法是无论盖不盖住都上移固定的距离,代码如下:

//
//  ViewController.m
//  键盘响应小练习
//
//  Created by 曹魏 on 2016/12/1.
//  Copyright © 2016年 itcast. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *birthdayField;
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *addressField;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //取消键盘的自动联想功能
    self.birthdayField.autocorrectionType = UITextAutocorrectionTypeNo;
    self.nameField.autocorrectionType = UITextAutocorrectionTypeNo;
    self.addressField.autocorrectionType = UITextAutocorrectionTypeNo;
    //键盘将要显示
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeKeyboard:) name:UIKeyboardWillShowNotification object:nil];
    //键盘将要隐藏
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeKeyboard:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)changeKeyboard:(NSNotification *)notification{
    //获取额外信息
    NSDictionary *userInfo = notification.userInfo;
    //获取结束时的frame
    CGRect endFrame = [userInfo[@"UIKeyboardFrameEndUserInfoKey"] CGRectValue];
    //计算要移动的距离
    CGFloat move = endFrame.origin.y - self.view.bounds.size.height;
    //让界面跟着移动
    self.view.transform = CGAffineTransformMakeTranslation(0, move);
    
}




- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.view endEditing:YES];
}
@end

说实话:这个方法的心机好重,很绕弯子!!!!

小知识点:

@property 和_实例变量的区别:

@property多了set 和get 方法的声明和实现

 

 

4.用户偏好设置的封装 

采用分类的方式对NSUserDefaults进行封装,很简单的,就是在分类中提供一些接口,接口做成类方法,供NSUserDefaults使用,主要注意枚举的写法.

//
//  NSUserDefaults+WP.h
//  01-通讯录
//
//  Created by apple on 16/8/1.
//  Copyright © 2016年 itcast. All rights reserved.
//

#import <Foundation/Foundation.h>

/**
 分类的主要目的: 帮我们保存和获取 存储的value
 */


// 定义 枚举, 来分辨 是那种开关
typedef NS_ENUM(NSInteger, SwitchType) {
    SwitchTypeRecord,
    SwitchTypeAuto

};

@interface NSUserDefaults (WP)

/**
 返回值 
 
 传递的参数
 
 key 值, 保存的值
 */


// 保存 按钮状态
+ (void)saveBoolValue:(BOOL)value forType:(SwitchType)type;


// 获取按钮状态
+ (BOOL)getBoolVlaueWithType:(SwitchType)type;


@end
//
//  NSUserDefaults+WP.m
//  01-通讯录
//
//  Created by apple on 16/8/1.
//  Copyright © 2016年 itcast. All rights reserved.
//

#import "NSUserDefaults+WP.h"

#define kAutoSwitch @"autoSwitch"

#define kRecordSwitch @"recordSwitch"


@implementation NSUserDefaults (WP)


// 保存 按钮状态
+ (void)saveBoolValue:(BOOL)value forType:(SwitchType)type {
    
    // 根据type的类型, 来决定key值
    NSString *key = type == SwitchTypeAuto ? kAutoSwitch : kRecordSwitch;
    
    [[NSUserDefaults standardUserDefaults] setBool:value forKey:key];
    // 强制写入一次
    [[NSUserDefaults standardUserDefaults] synchronize];
}


// 获取按钮状态
+ (BOOL)getBoolVlaueWithType:(SwitchType)type {
    // 根据type的类型, 来决定key值
    NSString *key = type == SwitchTypeAuto ? kAutoSwitch : kRecordSwitch;
    
    
    return [[NSUserDefaults standardUserDefaults] boolForKey:key];
    
}


+ (void)resetAllValues {
    
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kRecordSwitch];
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kAutoSwitch];
    
//    [[NSUserDefaults standardUserDefaults] setObject:@"" forKey:kUserName];
//    [[NSUserDefaults standardUserDefaults] setObject:@"" forKey:kPassword];
}
@end

 

 

 

 

5.修改分割线缩进:

解释:就是将tableview的线距离屏幕左右为0 ,达到没有间距的效果.

所以,可以把这个当成万能代码直接拷贝!!!

 

/** 修改分割线缩进为0 */
- (void)viewDidLayoutSubviews
{
    if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    }
    
    if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
        [self.tableView setLayoutMargins:UIEdgeInsetsMake(0, 0, 0, 0)];
    }
}



- (void)tableView:(UITableView*)tableView willDisplayCell:(UITableViewCell*)cell forRowAtIndexPath:(NSIndexPath*)indexPath
{
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }
    
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}
/** 修改分割线缩进为0 */

 6.模态控制器的使用:

 效果:由下往上弹出一个控制器,覆盖上一个控制器,但原控制器并没有消失

注意点:谁model(present) 谁dismiss

注意:模态控制器有个小问题:见红色部分

//
//  FirstViewController.m
//  模态控制器的小练习
//
//  Created by 曹魏 on 2016/12/4.
//  Copyright © 2016年 itcast. All rights reserved.
//

#import "FirstViewController.h"
#import "SecondViewController.h"
@interface FirstViewController ()

@end

@implementation FirstViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor redColor];
}

#pragma mark -- 点击屏幕跳转界面
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    SecondViewController *second = [[SecondViewController alloc]init];
//下面这个方法是模态时的样式选择,是个枚举,我想说的是枚举方法四中的
UIModalTransitionStylePartialCurl
翻转效果是很特殊的,当我选择这个效果样式时,模态到另一个控制器,再点击界面上任何一点是可以回去的,但别的样式方法不行.


// second.modalTransitionStyle = UIModalTransitionStylePartialCurl; /* typedef NS_ENUM(NSInteger, UIModalTransitionStyle) { UIModalTransitionStyleCoverVertical = 0, UIModalTransitionStyleFlipHorizontal __TVOS_PROHIBITED, UIModalTransitionStyleCrossDissolve, UIModalTransitionStylePartialCurl NS_ENUM_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED, }; */ second.modalTransitionStyle = UIModalTransitionStylePartialCurl; UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:second]; [self presentViewController:nav animated:YES completion:nil]; } @end

 

 特别简单,模态控制器是可以同时管理UITabBarController和UINavigationController的,所以更简单了,从一个控制器模态到第二个控制器,第一个控制器失去响应,例如很多

弹窗就是这样的,下举个小小栗子说明一下:

#import "AppDelegate.h"
#import "OneViewController.h"
@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    OneViewController *one = [[OneViewController alloc]init];
    self.window.rootViewController = one;
    
    
    
    
    [self.window makeKeyAndVisible];
    
    
    
    
    return YES;
}
#import "OneViewController.h"
#import "TwoViewController.h"
@interface OneViewController ()
@property (weak, nonatomic) IBOutlet UIButton *modal;

@end

@implementation OneViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}
- (IBAction)didClickModal:(UIButton *)sender {
    TwoViewController *two = [[TwoViewController alloc]init];
    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:two];
    [self presentViewController:nav animated:YES completion:^{
        
    }];
    
}
#import "TwoViewController.h"

@interface TwoViewController ()

@end

@implementation TwoViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"第二个控制器";
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(cancel)];
    
}
- (void)cancel{
#pragma mark -- 以下两种方式都可以进行dismiss操作,one-->nav是present操作过来(模态),self.navigationController dismiss属于理所应当,但其实其子控制器也可以执行操作达到同样的效果
//    [self dismissViewControllerAnimated:YES completion:^{
//        
//    }];
    [self.navigationController dismissViewControllerAnimated:YES completion:^{
        
    }];
}
@end

很简单,注意一下红色字体即可.

 

 

 

 

 

 

 

 

 

iOS中dismissViewController实现多级模态跳转

当我要用到dismiss实现多级模态跳转的时候,即我想从present 顺序是:A->B->C,当我点击C 的时候直接回到A控制器,由于dismiss操作本质上是由上个发出present操作的控制器所发出的,即假设:B控制器采用dismiss方法回到A控制器,在B中我们通常会写:[self dismissViewControllerAnimated:YES completion:nil];这个方法,本质上这个方法的调用其实是A控制器,B中写这个方法会通知A控制器去执行,表面上是B执行,但本质上是A控制器去执行,

还有注意点:当我点击C控制器回到A控制器时肯定要用到block或者代理通知,

也就是说,其实在present多个视图控制器的时候,系统维护了一个栈,以我们现在这个情况为例,从栈底到栈顶依次是A->B->C。当栈中某个位置的视图控制器执行dismissViewController方法的时候,栈中所有在它之上的视图控制器都会被dismiss,不同的是,栈顶的视图控制器将会以动画方式被dismiss,而中间的视图控制器只是简单的remove掉

可以参考官方文档:http://m.blog.csdn.net/article/details?id=50950915

 

posted @ 2016-11-29 20:03  忆缘晨风  阅读(378)  评论(0编辑  收藏  举报