OC语言学习笔记——UI(二)

目录

布局子视图

手动布局子视图

自动布局子视图

导航控制器

导航控制器基础

导航控制器切换

导航栏和工具栏

分栏控制器

分栏控制器基础

分栏控制器高级

多界面传值

UITableView

UITableView基础

UITableView协议

UITableView高级协议与单元格

UIView动画基础

导航控制器动画


布局子视图

当父视图大小发生变化时,我们想让子视图跟着父视图一起变化,可以使用自动布局和手动布局两种方式

手动布局子视图

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface superView : UIView
{
    UIView* _view01;
    UIView* _view02;
    UIView* _view03;
    UIView* _view04;
    UIView* _view05;
}

- (void)createSubViews;
@end
#import "superView.h"

@implementation superView

- (void)createSubViews {
    _view01 = [[UIView alloc] init];
    _view01.frame = CGRectMake(0, 0, 40, 40);
    
    _view02 = [[UIView alloc] init];
    _view02.frame = CGRectMake(self.bounds.size.width - 40, 0, 40, 40);
    
    _view03 = [[UIView alloc] init];
    _view03.frame = CGRectMake(self.bounds.size.width - 40, self.bounds.size.height - 40, 40, 40);
    
    _view04 = [[UIView alloc] init];
    _view04.frame = CGRectMake(0, self.bounds.size.height - 40, 40, 40);
    
    _view01.backgroundColor = [UIColor cyanColor];
    _view02.backgroundColor = [UIColor cyanColor];
    _view03.backgroundColor = [UIColor cyanColor];
    _view04.backgroundColor = [UIColor cyanColor];
    [self addSubview:_view01];
    [self addSubview:_view02];
    [self addSubview:_view03];
    [self addSubview:_view04];
}

//当需要重新布局时调用此函数
//通过此函数重新设定子视图的位置
//手动调整子视图的位置
- (void)layoutSubviews {
    [UIView animateWithDuration:1 animations:^{
        self->_view01.frame = CGRectMake(0, 0, 40, 40);
        self->_view02.frame = CGRectMake(self.bounds.size.width - 40, 0, 40, 40);
        self->_view03.frame = CGRectMake(self.bounds.size.width - 40, self.bounds.size.height - 40, 40, 40);
        self->_view04.frame = CGRectMake(0, self.bounds.size.height - 40, 40, 40);
    }];
}

#import "ViewController.h"
#import "superView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //创建父亲视图
    superView* sView = [[superView alloc] init];
    sView.frame = CGRectMake(20, 20, 180, 280);
    [sView createSubViews];
    sView.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:sView];
    UIButton* btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btn.frame = CGRectMake(240, 480, 80, 40);
    [btn setTitle:@"放大" forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(pressLarge) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
    UIButton* btn1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btn1.frame = CGRectMake(240, 520, 80, 40);
    [btn1 setTitle:@"缩小" forState:UIControlStateNormal];
    [btn1 addTarget:self action:@selector(pressSmall) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn1];
    sView.tag = 101;
}

//放大父视图
- (void)pressLarge {
    superView* sView = (superView*)[self.view viewWithTag:101];
    [UIView animateWithDuration:1 animations:^{
        sView.frame = CGRectMake(20, 20, 300, 480);
    }];
}
//缩小父视图
- (void)pressSmall {
    superView* sView = (superView*)[self.view viewWithTag:101];
    [UIView animateWithDuration:1 animations:^{
        sView.frame = CGRectMake(20, 20, 180, 280);
    }];
}

@end

效果如下:

自动布局子视图

自动布局子视图通过OC语言提供的属性和方法来完成

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController {
    UIView* _superView;
    UILabel* _label1;
    UILabel* _label2;
    UILabel* _label3;
    UILabel* _label4;
    UIView* _viewCenter;
}


@end

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    _superView = [[UIView alloc] init];
    _superView.frame = CGRectMake(20, 20, 180, 280);
    _superView.backgroundColor = [UIColor orangeColor];
    
    _label1 = [[UILabel alloc] init];
    _label1.frame = CGRectMake(0, 0, 40, 40);
    _label1.text = @"1";
    _label1.backgroundColor = [UIColor cyanColor];
    _label1.textAlignment = NSTextAlignmentCenter;
    
    _label2 = [[UILabel alloc] init];
    _label2.frame = CGRectMake(140, 0, 40, 40);
    _label2.text = @"2";
    _label2.backgroundColor = [UIColor cyanColor];
    _label2.textAlignment = NSTextAlignmentCenter;
    
    _label3 = [[UILabel alloc] init];
    _label3.frame = CGRectMake(140, 240, 40, 40);
    _label3.text = @"3";
    _label3.backgroundColor = [UIColor cyanColor];
    _label3.textAlignment = NSTextAlignmentCenter;
    
    _label4 = [[UILabel alloc] init];
    _label4.frame = CGRectMake(0, 240, 40, 40);
    _label4.text = @"4";
    _label4.backgroundColor = [UIColor cyanColor];
    _label4.textAlignment = NSTextAlignmentCenter;
    
    [_superView addSubview:_label1];
    [_superView addSubview:_label2];
    [_superView addSubview:_label3];
    [_superView addSubview:_label4];
    
    [self.view addSubview:_superView];
    
    _viewCenter = [[UIView alloc] init];
    _viewCenter.frame = CGRectMake(0, 0, _superView.bounds.size.width, 40);
    _viewCenter.center = CGPointMake(90, 140);
    _viewCenter.backgroundColor = [UIColor magentaColor];
    [_superView addSubview:_viewCenter];
    
    //自动布局属性,通过此变量来调整视图在父亲视图中的位置和大小
    _label1.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
    _label2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
    _label3.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin;
    _label4.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
    _viewCenter.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleBottomMargin;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    static BOOL isLarge = NO;
    [UIView animateWithDuration:1 animations:^{
        if (isLarge == NO) {
            self->_superView.frame = CGRectMake(10, 10, 300, 480);
        } else {
            self->_superView.frame = CGRectMake(20, 20, 180, 280);
        }
        isLarge = !isLarge;
    }];
}

@end

 效果如下:

导航控制器

导航控制器基础

导航控制器(UINavigationController)是一个控制导航栏(navigationBar)的控件,在导航栏上的按钮叫UINavigationIitm,在导航控制器中控制一个视图控制器(UIViewController),而每个视图控制器中对应一个导航引入项(navigationItem),导航引入项也就是显示在导航栏上的内容,包括leftBarButtonItem(导航栏左侧按钮),titleView(导航栏中间标题),rightBarButtonItem(导航栏右侧按钮)

用代码来演示一下导航控制器的创建和使用:

#import "SceneDelegate.h"
#import "VCRoot.h"

@interface SceneDelegate ()

@end

@implementation SceneDelegate


- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    self.window.frame = [UIScreen mainScreen].bounds;
    
    //创建一个根视图控制器
    VCRoot *root = [[VCRoot alloc] init];
    
    //创建导航控制器,它主要是用于管理多个视图控制器的切换
    //用层级的方式来管理多个视图的切换
    //创建导航控制器的时候一定要有一个根视图控制器
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController: root];
    
    
    //将window的根视图设置为导航控制器
    self.window.rootViewController = nav;
    
    [self.window makeKeyAndVisible];
}
#import "VCRoot.h"

@interface VCRoot ()

@end

@implementation VCRoot

- (void)viewDidLoad {
    [super viewDidLoad];
    //设置根视图颜色
    self.view.backgroundColor = [UIColor cyanColor];
    
    //设置导航栏文字内容
    self.title = @"根视图";
    //设置导航元素项的标题,它和上面那一条的区别是
    //如果没有设置navigationItem的title,为nil,系统会自动使用self.title作为标题
    //如果navigationItem的title不为nil,则将navigationItem的title设置为标题
    //如果navigationItem的title和self.title都为nil,则没有标题
    self.navigationItem.title = @"title";
    
    //创建一个导航栏左侧的按钮,这是根据title文字来创建的,传入四个参数
    //第一个参数是按钮上的文字内容;第二个参数是按钮风格
    //第三个参数是事件的拥有者;第四个参数是按钮的事件函数
    UIBarButtonItem *leftBtn = [[UIBarButtonItem alloc] initWithTitle: @"左侧" style: UIBarButtonItemStyleDone target: self action: @selector(pressLeft)];
    
    //给导航栏的左侧按钮属性赋值为我们创建好的左侧按钮
    self.navigationItem.leftBarButtonItem = leftBtn;
    
    //右侧按钮
    //和左侧按钮不同的是,这里创建右侧按钮的时候我们使用的初始化方法是不一样的
    //这里的初始化方法不需要输入文字内容,而是指定了系统提供的风格样式,系统风格的按钮内容或标题文字不可更改
    UIBarButtonItem *rightBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemAdd target: self action: @selector(pressRight)];
    self.navigationItem.rightBarButtonItem = rightBtn;
    
    //创建多按钮:
    //先创建一个标签对象
    UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(10, 10, 50, 40)];
    label.text = @"test";
    
    //将label设置为居中
    label.textAlignment = NSTextAlignmentCenter;
    label.textColor = [UIColor blueColor];
    
    //将UIlabel类型的控件添加到导航栏按钮
    //initWithCustomView就代表以自定义控件来初始化
    UIBarButtonItem *item3 = [[UIBarButtonItem alloc] initWithCustomView: label];
    
    //创建一个按钮数组
    NSArray *arrayBtn = [NSArray arrayWithObjects: rightBtn, item3, nil];
    
    //将右侧按钮数组赋值
    self.navigationItem.rightBarButtonItems = arrayBtn;
    
}

- (void) pressLeft {
    NSLog(@"左侧按钮被按下");
}

- (void) pressRight {
    NSLog(@"右侧按钮被按下");
}
/*
 #pragma mark - Navigation
 
 // In a storyboard-based application, you will often want to do a little preparation before navigation
 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
 // Get the new view controller using [segue destinationViewController].
 // Pass the selected object to the new view controller.
 }
 */

@end

 效果如下:

导航控制器切换

导航控制器切换一般用这一对方法:

pushViewController:推入视图控制器

popViewController:弹出视图控制器

#import "SceneDelegate.h"
#import "VCRoot.h"

@interface SceneDelegate ()

@end

@implementation SceneDelegate


- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController: [[VCRoot alloc] init]];
    [self.window makeKeyAndVisible];
}
#import "VCRoot.h"
#import "VCsecond.h"

@interface VCRoot ()

@end

@implementation VCRoot

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //设置导航栏的透明度
    //默认透明度为YES:可透明的
    //NO:使导航栏不透明
    self.navigationController.navigationBar.translucent = NO;
    self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
    self.view.backgroundColor = [UIColor blueColor];
    self.title = @"根视图";
    
    UIBarButtonItem* next = [[UIBarButtonItem alloc] initWithTitle:@"下一级" style:UIBarButtonItemStylePlain target:self action:@selector(pressNext)];
    
    self.navigationItem.rightBarButtonItem = next;
}

-(void) pressNext {
    //创建一个新的视图控制器
    VCsecond* vcSecond = [[VCsecond alloc] init];
    
    //使用当前视图控制器的导航控制器对象
    //注意两种切换视图的写法的区别
    //[self presentViewController:vcSecond animated:YES completion:nil];
    //[self.navigationController presentViewController:vcSecond animated:YES completion:nil];
    [self.navigationController pushViewController:vcSecond animated:YES];
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
#import "VCsecond.h"
#import "VCthird.h"

@interface VCsecond ()

@end

@implementation VCsecond

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor greenColor];
    self.title = @"视图二";
    UIBarButtonItem* btnNext = [[UIBarButtonItem alloc] initWithTitle:@"第三级" style:UIBarButtonItemStylePlain target:self action:@selector(pressNext)];
    self.navigationItem.rightBarButtonItem = btnNext;
}

- (void)pressNext {
    VCthird* vc = [[VCthird alloc] init];
    //推入第三个视图控制器
    [self.navigationController pushViewController:vc animated:YES];
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
#import "VCthird.h"

@interface VCthird ()

@end

@implementation VCthird

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor orangeColor];
    self.title = @"第三级";
    
    UIBarButtonItem* btnLeft = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(pressBack)];
    //当自己设定左侧按钮时,返回按钮会自动被替代
    self.navigationItem.leftBarButtonItem = btnLeft;
    
    UIBarButtonItem* btnR = [[UIBarButtonItem alloc] initWithTitle:@"返回根视图" style:UIBarButtonItemStylePlain target:self action:@selector(pressRight)];
    self.navigationItem.rightBarButtonItem = btnR;
}

-(void) pressRight{
    //直接返回到根视图
    [self.navigationController popToRootViewControllerAnimated:YES];
}

- (void)pressBack {
    NSLog(@"返回上一级");
    [self.navigationController popViewControllerAnimated:YES];
}
/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

这里三个视图控制器的头文件过于简单 就省略了

效果如下:

导航栏和工具栏

在iOS13之后,设置导航栏的颜色等样式要按如下方式:

UIBarAppearance是iOS13后推出的一个对相应空间设置外观样式的类,可以统一配置NavigationBar、TabBar、ToolBar等的外观样式

UINavigationBarAppearance可以设置导航栏对象的外观样式

在使用这些方法设置导航栏外观样式之前,需要创建一个UINavigationBarAppearance对象

#import "VCRoot.h"
#import "VCSecond.h"

@interface VCRoot ()

@end

@implementation VCRoot

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor yellowColor];
    
    //设置导航栏风格颜色 默认是透明的
    //UIBarStyleBlack 透明的
    self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
    //将风格设置为不透明
    self.navigationController.navigationBar.translucent = NO;
    
    //设置导航栏的风格颜色
    //self.navigationController.navigationBar.barTintColor = [UIColor redColor];
    //UIBarAppearance是iOS13后推出的一个对相应空间设置外观样式的类,可以统一配置NavigationBar、TabBar、ToolBar等的外观样式
    //UINavigationBarAppearance可以设置导航栏对象的外观样式
    //创建一个UINavigationBarAppearance对象
    UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
    //设置该对象的背景颜色
    appearance.backgroundColor = [UIColor cyanColor];
    //创建该对象的阴影图像
    appearance.shadowImage = [[UIImage alloc] init];
    //设置该对象的阴影颜色
    appearance.shadowColor = nil;
    //self.navigationController.navigationBar.standardAppearance = appearance;
    self.navigationController.navigationBar.scrollEdgeAppearance = appearance;
    
    //设置导航元素项目按钮的风格颜色
    self.navigationController.navigationBar.tintColor = [UIColor greenColor];
    
    //self.navigationController.navigationBarHidden = YES;
    //self.navigationController.navigationBar.hidden = YES;
    //隐藏导航栏 一个是导航控制器的属性 一个是导航栏属性
    
    self.navigationController.toolbarHidden = NO;
    
    self.title = @"根视图";
    
    UIBarButtonItem* btn = [[UIBarButtonItem alloc] initWithTitle:@"右侧按钮" style:UIBarButtonItemStylePlain target:nil action:nil];
    
    self.navigationItem.rightBarButtonItem = btn;
    
    //实现工具栏对象
    //默认工具栏是隐藏的
    self.navigationController.toolbarHidden = NO;
    self.navigationController.toolbar.translucent = NO;
    
    //创建三个工具栏按钮
    UIBarButtonItem* btn1 = [[UIBarButtonItem alloc] initWithTitle:@"left" style:UIBarButtonItemStylePlain target:nil action:nil];
    UIBarButtonItem* btn2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(pressNext)];
    UIButton* btnImage = [UIButton buttonWithType:UIButtonTypeCustom];
    [btnImage setImage:[UIImage imageNamed:@"1.jpg"] forState:UIControlStateNormal];
    btnImage.frame = CGRectMake(0, 0, 60, 60);
    UIBarButtonItem* btn3 = [[UIBarButtonItem alloc] initWithCustomView:btnImage];
    
    //固定宽度分割占位按钮
    UIBarButtonItem* btnf01 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    btnf01.width = 100;
    
    UIBarButtonItem* btnf02 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace menu:nil];
    
    //按钮数组的创建
    NSArray* arrayBtns = [NSArray arrayWithObjects:btn1, btnf02, btn2, btn3, nil];
    self.toolbarItems = arrayBtns;
    
    // Do any additional setup after loading the view.
}


- (void)pressNext {
    VCSecond* vc = [[VCSecond alloc] init];
    [self.navigationController pushViewController:vc animated:YES];
}

//导航栏和工具栏是公用的,但是导航栏和工具栏上的按钮是独立的

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
#import "VCSecond.h"

@interface VCSecond ()

@end

@implementation VCSecond

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor orangeColor];
}
#import "SceneDelegate.h"
#import "VCRoot.h"

@interface SceneDelegate ()

@end

@implementation SceneDelegate


- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:[[VCRoot alloc] init]];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
}

效果如下:

在以上代码中有一些方法:

barStyle:导航栏风格

barTintColor:导航栏颜色

tintColor:导航栏风格颜色

toolBarItems:工具栏元素数组

UIBarItemFlexibleSpace:自动调整距离按钮

分栏控制器

分栏控制器基础

分栏控制器就是一个可以在几个视图控制器间切换的控件

#import "VCFirst.h"

@interface VCFirst ()

@end

@implementation VCFirst

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //创建一个分栏按钮对象
    //第一个参数是文字
    //第二个参数表示是否显示图片图标
    //第三个参数是设置按钮的tag值
    //方法一
    //UITabBarItem* tabBarItem = [[UITabBarItem alloc] initWithTitle:@"111" image:nil tag:101];
    //self.tabBarItem = tabBarItem;
    
    //根据系统风格创建分栏按钮
    //第一个参数表示系统风格
    UITabBarItem* tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemContacts tag:101];
    //按钮右上角的提示信息
    //通常用来提示未读的信息
    tabBarItem.badgeValue = @"22";
    self.tabBarItem = tabBarItem;
}
#import "VCSecond.h"

@interface VCSecond ()

@end

@implementation VCSecond

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}
#import "VCThird.h"

@interface VCThird ()

@end

@implementation VCThird

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}
#import "SceneDelegate.h"
#import "VCFirst.h"
#import "VCSecond.h"
#import "VCThird.h"

@interface SceneDelegate ()

@end

@implementation SceneDelegate


- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    
    //显示window
    [self.window makeKeyAndVisible];
    
    //创建视图控制器一
    VCFirst* vcFirst = [[VCFirst alloc] init];
    
    
    //创建视图控制器二
    VCSecond* vcSecond = [[VCSecond alloc] init];
    
    vcSecond.view.backgroundColor = [UIColor yellowColor];
    
    //创建控制视图器三
    VCThird* vcThird = [[VCThird alloc] init];
    //橘色背景
    vcThird.view.backgroundColor = [UIColor orangeColor];
    vcFirst.title = @"视图1";
    vcSecond.title = @"视图2";
    vcThird.title = @"视图3";
    
    vcFirst.view.backgroundColor = [UIColor whiteColor];
    
    //创建分栏控制器对象
    UITabBarController* tbController = [[UITabBarController alloc] init];
    
    //创建一个控制器数组对象
    //将所有要被分栏控制器管理的对象添加到数组中
    NSArray* arrayVC = [NSArray arrayWithObjects:vcFirst, vcSecond, vcThird, nil];
    
    //将分栏控制器管理数组赋值
    tbController.viewControllers = arrayVC;
    
    //将分栏控制器作为根视图控制器
    self.window.rootViewController = tbController;
    
    //设置选中视图控制器的索引
    //通过索引来确定显示哪一个控制器
    tbController.selectedIndex = 2;
    
    //当前选中的控制器对象
    if (tbController.selectedViewController == vcThird) {
        NSLog(@"当前显示的是控制器三~");
    }
    

效果如下:

可以归纳出以下属性:

UITabBarltem:分栏按钮元素对象

badgeValue:分栏按钮提示信息

selectedIndex:分栏控制器选中的控制索引

viewControllers:分栏控制器管理数组

selectedViewController:分栏控制器选中的控制器对象

分栏控制器高级

有一些关于分栏控制器的高级方法:

willBeginCustomizingViewControllers:即将显示编辑方法

willEndCustomizingViewControllers:即将结束编辑方法

didEndCustomizingViewControllers:已经结束编辑方法

didSelectViewController:选中控制器切换方法

调用这些方法需要遵守UITabBarControllerDelegate协议

当分栏控制器按钮多于五个时,会将第五个替换成more,点击more可以点击右上角edit按钮来编辑分栏控制器上展现的按钮

用代码来演示一下:

首先创建六个视图控制器,这里就省略不写了

在scenedelegate中创建分栏控制器:

#import "SceneDelegate.h"
#import "VCFirst.h"
#import "VCSecond.h"
#import "VCThird.h"
#import "VCFourth.h"
#import "VCFifth.h"
#import "VCSixth.h"

@interface SceneDelegate ()

@end

@implementation SceneDelegate


- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    
    VCFirst* vc01 = [[VCFirst alloc] init];
    VCSecond* vc02 = [[VCSecond alloc] init];
    VCThird* vc03 = [[VCThird alloc] init];
    VCFourth* vc04 = [[VCFourth alloc] init];
    VCFifth* vc05 = [[VCFifth alloc] init];
    VCSixth* vc06 = [[VCSixth alloc] init];
    
    vc01.view.backgroundColor = [UIColor blueColor];
    vc02.view.backgroundColor = [UIColor purpleColor];
    vc03.view.backgroundColor = [UIColor grayColor];
    vc04.view.backgroundColor = [UIColor greenColor];
    vc05.view.backgroundColor = [UIColor orangeColor];
    vc06.view.backgroundColor = [UIColor yellowColor];
    
    vc01.title = @"视图1";
    vc02.title = @"视图2";
    vc03.title = @"视图3";
    vc04.title = @"视图4";
    vc05.title = @"视图5";
    vc06.title = @"视图6";
    
    //创建数组
    NSArray* arrayVC = [NSArray arrayWithObjects:vc01, vc02, vc03, vc04, vc05, vc06, nil];
    
    UITabBarController* tbc = [[UITabBarController alloc] init];
    tbc.viewControllers = arrayVC;
    tbc.tabBar.translucent = YES;
    self.window.rootViewController = tbc;
    //这个修改没用
    tbc.tabBar.barTintColor = [UIColor redColor];
    tbc.tabBar.tintColor = [UIColor blackColor];
    
    //设置代理
    tbc.delegate = self;
}

//开始编辑前调用
-(void) tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(nonnull NSArray<__kindof UIViewController *> *)viewControllers {
    NSLog(@"编辑器前");
}

//
-(void) tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed {
    NSLog(@"即将结束前!");
}

-(void) tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed {
    if (changed == YES) {
        NSLog(@"顺序发生改变!");
    }
    NSLog(@"已经结束编辑!");
}

- (void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
    NSLog(@"选中控制器对象");
}

效果如下:

多界面传值

可以通过代理来完成多界面之间的传值,通过代理可以将第二个对象访问不到的第一个对象的情况下,将代理(delegate)做为类之间的接收对象。代理对象必须实现代理函数

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

//定义一个视图控制器二的代理协议
@protocol SecondVCDelegate <NSObject>

- (void)changeColor: (UIColor*)color;

@end
@interface SecondViewController : UIViewController

@property (assign, nonatomic) NSInteger tag;
//定义一个代理对象,代理对象会执行协议函数
//通过代理对象实现协议函数,达到代理对象改变本身属性的目的
//代理对象一定要实现代理协议
@property (assign, nonatomic) id<SecondVCDelegate> delegate;


@end
#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.view.backgroundColor = [UIColor purpleColor];
    UIBarButtonItem* btnChange = [[UIBarButtonItem alloc] initWithTitle:@"改变颜色" style:UIBarButtonItemStyleDone target:self action:@selector(pressChange)];
    
    self.navigationItem.rightBarButtonItem = btnChange;
}

- (void) pressChange {
    [_delegate changeColor:[UIColor purpleColor]];
}

/*
#pragma mark - Navigation
#import <UIKit/UIKit.h>
#import "SecondViewController.h"

NS_ASSUME_NONNULL_BEGIN

@interface FirstViewController : UIViewController <SecondVCDelegate>

- (void)changeColor : (UIColor *)color;

@end
#import "FirstViewController.h"
#import "SecondViewController.h"

@interface FirstViewController ()

@end

@implementation FirstViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

//点击视图空白处,推出视图控制器二
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    SecondViewController* vc2 = [[SecondViewController alloc] init];
    vc2.view.backgroundColor = [UIColor orangeColor];
    //将当前视图控制器设置为代理对象
    vc2.delegate = self;
    [self.navigationController pushViewController:vc2 animated:YES];
}

//实现视图控制器二的代理协议
- (void)changeColor:(UIColor *)color {
    self.view.backgroundColor = color;
}

效果如下:

UITableView

UITableView基础

UITableView也叫数据视图,例如表格,在创建时要注意实现协议中的几个函数:

1、tableView(获取每组元素的个数);

2、numberOfSectionsInTableView(设置数据视图的组数);

3、tableView: cellForRowAtIndexPath:(创建单元格对象函数)

另外,在数据视图的协议中,还有以下几个函数:

dataSource:设置数据代理对象

delegate:设置普通代理对象

numberOfSectionsInTableView:获取组数

numberOfRowsInSection:获取行数

cellForRowAtIndexPath:创建单元格

下面用代码来演示一下:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <
//实现数据视图的普通协议
//数据视图的普通事件处理
UITableViewDelegate,
//实现数据视图的数据代理协议
//处理数据视图的数据代理
UITableViewDataSource>
{
    //定义一个数据视图对象
    //数据视图用来显示大量相同格式的信息的视图
    //例如:电话通讯录、qq好友、微信朋友圈
    UITableView* _tableView;
}

@end
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    //创建数据视图
    //第一个参数是数据视图的位置
    //第二个参数是数据视图的风格
    //UITableViewStylePlain:普通风格
    //UITableViewStyleGrouped:分组风格
    _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
    //UITableViewStyleGrouped:分组风格
    //UITableViewStylePlain:普通风格
    
    //设置数据视图的代理对象
    _tableView.delegate = self;
    //设置数据视图的数据源对象
    _tableView.dataSource = self;
    
    [self.view addSubview:_tableView];
}

//获取每组元素的个数
//必须要实现的协议函数
//程序在现实数据视图时会调用此函数
//返回值是表示每组元素的个数
//第一个参数是数据视图本身
//第二个参数是那一组需要的行数
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 5;
}

- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
    return 3;
}

//创建单元格对象函数
//第一个参数是数据视图 第二个参数是索引

- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString* cellStr = @"cell";
    UITableViewCell* cell = [_tableView dequeueReusableCellWithIdentifier:cellStr];
    
    if (cell == nil) {
        //创建一个单元格对象
        //第一个参数是单元格的样式
        //第二个参数是单元格的复用标记
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellStr];
    }
    NSString* str = [NSString stringWithFormat:@"第%ld组,第%ld行",indexPath.section, indexPath.row];
    //将单元格的主文字内容赋值
    cell.textLabel.text = str;
    return cell;
}

@end

效果图:

UITableView协议

UITableView有关的协议UITableViewDelegate,UITableViewDataSource中有几个函数:

heightForRowAtIndexPath:获得单元格高度协议

heightForHeaderInSection:数据视图头部高度协议

heightForFooterInSection:数据视图尾部高度协议

titleForFooterInSection:数据视图尾部的标题协议

titleForHeaderInSection:数据视图头部标题协议

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <
//数据代理协议
UITableViewDataSource,
//普通代理协议
UITableViewDelegate> {
    //定义数据视图对象
    UITableView* _tableView;
    //声明一个数据源
    NSMutableArray* _arrayData;
}


@end
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //创建数据视图对象
    _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 40, 320, 536) style:UITableViewStyleGrouped];
    //设置代理对象
    _tableView.delegate = self;
    //设置数据代理对象
    _tableView.dataSource =self;
    //数据视图显示
    [self.view addSubview:_tableView];
    
    //创建一个可变数组
    _arrayData = [[NSMutableArray alloc] init];
    
    for (int i = 'A'; i <= 'Z'; i++) {
        //定义小数组
        NSMutableArray* arraySmall = [[NSMutableArray alloc] init];
        
        for (int j = 1; j < 5; j++) {
            NSString* str = [NSString stringWithFormat:@"%c%d",i,j];
            
            [arraySmall addObject:str];
        }
        //生成一个二维数组
        [_arrayData addObject:arraySmall];
    }
}

//获取组数
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
    return _arrayData.count;
}

//获取每组的元素个数
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    //因为前面创建了一个二维数组,这里的section返回的是_arrayData二维数组中的以行为元素的一维数组,然后再对用其count方法取这个一维数组的元素个数
    NSInteger numRow = [[_arrayData objectAtIndex:section] count] ;
    return numRow;
}

- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString* str = @"cell";
    UITableViewCell* cell = [_tableView dequeueReusableCellWithIdentifier:str];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:str];
    }
    cell.textLabel.text = _arrayData[indexPath.section][indexPath.row];
    return cell;
}

//获取单元格高度
- (CGFloat) tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 100;
}

//获取每组头部标题
- (NSString*) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    return @"头部标题!";
}

//获取每组尾部标题
- (NSString*) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
    return @"尾部标题!";
}

//获取头部高度
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 40;
}

//获取尾部高度
- (CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return 20;
}
@end

效果如下:

UITableView高级协议与单元格

UITableView有关协议中有以下几个高级协议函数:

commitEditingStyle:提交编辑函数

canEditRowAtIndexPath:开启关闭编辑单元格

editingStyleForRowAtIndexPath:编辑单元格风格设定

didSelectRowAtIndexPath:选中单元格相应协议

didDeselectRowAtIndexPath:反选单元格相应协议

在使用这些协议函数时,首先要创建一个导航控制器作为根视图控制器

@interface SceneDelegate ()

@end

@implementation SceneDelegate


- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    self.window.frame = [UIScreen mainScreen].bounds;
    UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
}

然后应用协议并实现协议函数:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
    //数据视图
    UITableView* _tableView;
    //数据源
    NSMutableArray* _arrayData;
    
    //添加导航按钮
    UIBarButtonItem* _btnEdit;
    UIBarButtonItem* _btnFinish;
    UIBarButtonItem* _btnDelete;
    
    //设置编辑状态
    BOOL _isEdit;
}


@end
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
    
    //自动调整子视图的大小
    _tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
    
    //设置代理
    _tableView.delegate = self;
    _tableView.dataSource = self;
    
    //数据视图的头部视图的设定
    _tableView.tableHeaderView = nil;
    //数据视图的尾部视图
    _tableView.tableFooterView = nil;
    
    [self.view addSubview: _tableView];
    
    //初始化数据源数组
    _arrayData = [[NSMutableArray alloc] init];
    
    for (int i = 1; i < 20; i++) {
        NSString* str = [NSString stringWithFormat:@"A %d", i];
        [_arrayData addObject:str];
    }
    
    //当数据的数据源发生变化时
    //更新数据视图,重新加载数据
    [_tableView reloadData];
    
}

- (void) createBtn {
    _isEdit = NO;
    
    //创建功能按钮
    _btnEdit = [[UIBarButtonItem alloc] initWithTitle:@"编辑" style:UIBarButtonItemStylePlain target:self action:@selector(pressEdit)];
    _btnFinish = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStylePlain target:self action:@selector(pressFinish)];
    _btnDelete =[[UIBarButtonItem alloc] initWithTitle:@"删除" style:UIBarButtonItemStylePlain target:self action:@selector(pressDelete)];
    self.navigationItem.rightBarButtonItem = _btnEdit;
}

//单元格显示效果协议
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    //UITableViewCellEdit
    //默认为删除
    return UITableViewCellEditingStyleDelete;
    //添加状态
    //return UITableViewCellEditingStyleInsert
    //空状态
    //return UITableViewCellEditingstyleNone
    //组合在一起就会表现多选状态
    //return UITableViewCellEditingStyleDelete|UITableViewCellEditingStyleInsert
}

//当手指在单元格上移动时可以显示编辑状态
//这里通过手指滑动来实现删除按钮的功能
- (void)pressEdit {
    //修改对象编辑状态
    _isEdit = YES;
    self.navigationItem.rightBarButtonItem = _btnFinish;
    //开启编辑状态
    [_tableView setEditing:YES];
    self.navigationItem.leftBarButtonItem = _btnDelete;
}

- (void)pressFinish {
    _isEdit = NO;
    self.navigationItem.rightBarButtonItem = _btnEdit;
    [_tableView setEditing:NO];
    self.navigationItem.leftBarButtonItem = nil;
}

-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _arrayData.count;
}
//默认数组返回1
//-(NSInteger) numberOfSectionInTableView:(UITableView *)tableView {
//return 1;
//}

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString* strID = @"ID";
    //尝试获得可复用的单元格
    //如果得不到 返回为nil
    UITableViewCell* cell = [_tableView dequeueReusableCellWithIdentifier:strID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strID];
    }
    //单元格文字赋值
    cell.textLabel.text = [_arrayData objectAtIndex:indexPath.row];
    [self createBtn];
    return cell;
}

//当手指在单元格上移动时可以显示编辑状态
//这里通过手指滑动来实现删除按钮的功能
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    //删除对应数据
    [_arrayData removeObjectAtIndex:indexPath.row];
    //数据源更新
    [_tableView reloadData];
    NSLog(@"删除");
}

//选中单元格时执行
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"选中单元格!%lu, %lu", indexPath.section, indexPath.row);
}

//反选函数:使选择某单元格时,取消选中上一个单元格
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"取消选中单元格!%lu, %lu", indexPath.section, indexPath.row);
}

- (void)pressDelete {
    NSLog(@"没用!");
}

@end

效果如下:

UIView动画基础

现在UI中使用动画效果一般都使用如下函数:

    [UIView transitionWithView:@"动画视图" duration:@"时间" options:@"上述动画效果" animations:^{
 
        dispatch_async(dispatch_get_main_queue(), ^{
 
           //动画执行过程中的动作,可以是跳页的等
 
        });
 
    } completion:^(BOOL finished) {
 
    
 
    }];

此处options有以下几个选择:

UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动

UIViewAnimationOptionAllowUserInteraction:动画过程中允许用户交互。

UIViewAnimationOptionBeginFromCurrentState:所有视图从当前状态开始运行。

UIViewAnimationOptionRepeat:重复运行动画。

UIViewAnimationOptionAutoreverse :动画运行到结束点后仍然以动画方式回到初始点。

UIViewAnimationOptionOverrideInheritedDuration:忽略嵌套动画时间设置。

UIViewAnimationOptionOverrideInheritedCurve:忽略嵌套动画速度设置。

UIViewAnimationOptionAllowAnimatedContent:动画过程中重绘视图(注意:仅仅适用于转场动画)。

UIViewAnimationOptionShowHideTransitionViews:视图切换时直接隐藏旧视图、显示新视图,而不是将旧视图从父视图移除(仅仅适用于转场动画

UIViewAnimationOptionOverrideInheritedOptions :不继承父动画设置或动画类型。

有一些跳页时经常使用的:

UIViewAnimationOptionTransitionNone:没有动画效果。

UIViewAnimationOptionTransitionFlipFromLeft :从左侧翻转效果。

UIViewAnimationOptionTransitionFlipFromRight:从右侧翻转效果。

UIViewAnimationOptionTransitionCurlUp:向后翻页的动画过渡效果。

UIViewAnimationOptionTransitionCurlDown :向前翻页的动画过渡效果。

UIViewAnimationOptionTransitionCrossDissolve:旧视图溶解消失显示下一个新视图的效果。

UIViewAnimationOptionTransitionFlipFromTop :从上方翻转效果。    

UIViewAnimationOptionTransitionFlipFromBottom:从底部翻转效果。

还有一些和时间有关的:

UIViewAnimationOptionCurveEaseInOut:动画效果先缓后逐渐加速再逐渐减速。

UIViewAnimationOptionCurveEaseIn :动画效果逐渐变慢。

UIViewAnimationOptionCurveEaseOut:动画效果逐渐加速。

UIViewAnimationOptionCurveLinear :动画效果匀速执行(默认)。

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController {
    //图像视图对象
    UIImageView* _imageView;
}

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //创建视图对象
    _imageView = [[UIImageView alloc] init];
    _imageView.frame = CGRectMake(100, 100, 80, 80);
    _imageView.image = [UIImage imageNamed:@"7.jpg"];
    [self.view addSubview:_imageView];
    //设置移动按钮
    UIButton* btnMove = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btnMove.frame = CGRectMake(120, 360, 80, 40);
    [btnMove setTitle:@"移动" forState:UIControlStateNormal];
    [btnMove addTarget:self action:@selector(pressMove) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btnMove];
    //设置圆角按钮
    UIButton* btnScale = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btnScale.frame = CGRectMake(120, 400, 80, 40);
    [btnScale setTitle:@"缩放" forState:UIControlStateNormal];
    [btnScale addTarget:self action:@selector(pressScale) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btnScale];
}

- (void)pressMove {
    //设置动画的执行时间和执行动作
    //    [UIView animateWithDuration: 3 animations: ^ {
    //        self->_imageView.frame = CGRectMake(50, 700, 130, 130);
    //    }];
        
        //设置动画开始的延时时间长度
        //进行延时动画的处理
        //options有几个属性:UIViewAnimationOptionRepeat表示动画重复执行;UIViewAnimationOptionAutoreverse表示动画结束后再逆执行动画
        [UIView animateWithDuration: 3 delay: 4 options: UIViewAnimationOptionCurveLinear animations: ^{
            self->_imageView.frame = CGRectMake(50, 700, 130, 130);
        } completion:^(BOOL finished) {
        }];
}

- (void)pressScale {
    
}

@end

效果如下:

导航控制器动画

先用代码展示一下导航控制器的语法:

#import "SceneDelegate.h"
#import "VCFirst.h"

@interface SceneDelegate ()

@end

@implementation SceneDelegate


- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    self.window.frame = [UIScreen mainScreen].bounds;
    //创建导航控制器
    VCFirst* vcFirst = [[VCFirst alloc] init];
    UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:vcFirst];
    vcFirst.title = @"控制器一";
    self.window.rootViewController = nav;
    nav.navigationBar.translucent = NO;
    [self.window makeKeyAndVisible];
}
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

//第一视图控制器
@interface VCFirst : UIViewController {
    //视图对象
    UIImageView* _imageView;
}

@end
#import "VCFirst.h"
#import "VCSecond.h"

@interface VCFirst ()

@end

@implementation VCFirst

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    _imageView = [[UIImageView alloc] init];
    _imageView.frame = CGRectMake(40, 40, 260, 380);
    _imageView.image = [UIImage imageNamed:@"images (1).jpg"];
    [self.view addSubview:_imageView];
    self.view.backgroundColor = [UIColor whiteColor];
}

- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    //定义一个动画变换对象,层动画对象
    //类方法获取动画对象
    CATransition* amin = [CATransition animation];
    //设置动画的时间长度
    amin.duration = 1;
    //设置动画的类型,决定动画的效果形式
    //reveal 消失
    //pageCurl 翻页
    //pageUncurl 翻回
    //suckEffect 飞毯
    //fade 溶解
    //ripplEffect 水波纹
    amin.type = @"rippleEffect";
    //设置动画的子类型,例如动画的方向
    amin.subtype = kCATransitionFromLeft;
    //设置动画的轨迹模式
    amin.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut];
    
    //将动画设置对象添加到动画上
    [self.navigationController.view.layer addAnimation:amin forKey:nil];
    
    //创建控制器二
    VCSecond* vcSecond = [[VCSecond alloc] init];
    //推出到前台显示
    [self.navigationController pushViewController:vcSecond animated:YES];
}
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

//第二视图控制器
@interface VCSecond : UIViewController {
    UIImageView* _imageView;
}

@end
#import "VCSecond.h"

@interface VCSecond ()

@end

@implementation VCSecond

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.title = @"控制器二";
    _imageView = [[UIImageView alloc] init];
    _imageView.frame = CGRectMake(40, 40, 260, 380);
    _imageView.image = [UIImage imageNamed:@"images (5).jpg"];
    [self.view addSubview:_imageView];
    self.view.backgroundColor = [UIColor whiteColor];
}

//点击屏幕空白处,返回到控制器一
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    CATransition* ami = [CATransition animation];
    ami.duration = 1;
    ami.type = @"rippleEffect";
    ami.subtype = kCATransitionFromRight;
    ami.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseOut];
    [self.navigationController.view.layer addAnimation:ami forKey:nil];
    [self.navigationController popViewControllerAnimated:YES];
}

效果如下:

不难看出:

CATransition:动画对象

duration:设置动画时间长度

type:设置动画类型

timingFunction:设置动画运动类型

subType:设置动画子类型

  • 29
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值