「OC」UI学习笔记(二)
手动布局子视图
//父视图的.h文件
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface JCSuperView : UIView
{
UIView *_v1;
UIView *_v2;
UIView *_v3;
UIView *_v4;
}
-(void)makeView;
@end
NS_ASSUME_NONNULL_END
—————————————————————————————————————————————————————————————————————————————————————————————————————————
//父视图.m文件内容
#import "JCSuperView.h"
@implementation JCSuperView
//布局父视图
-(void)makeView {
//左上角
_v1 = [[UIView alloc] init];
_v1.frame = CGRectMake(0, 0, 40, 40);
//右上角
_v2 = [[UIView alloc] init];
_v2.frame = CGRectMake(self.bounds.size.width - 40, 0, 40, 40);
//右下角
_v3 = [[UIView alloc] init];
_v3.frame = CGRectMake(self.bounds.size.width - 40, self.bounds.size.height - 40, 40, 40);
//左下角
_v4 = [[UIView alloc] init];
_v4.frame = CGRectMake(0, self.bounds.size.height - 40, 40, 40);
_v1.backgroundColor = [UIColor redColor];
_v2.backgroundColor = [UIColor redColor];
_v3.backgroundColor = [UIColor redColor];
_v4.backgroundColor = [UIColor redColor];
[self addSubview:_v1];
[self addSubview:_v2];
[self addSubview:_v3];
[self addSubview:_v4];
}
//当需要重新布局时会调用此函数
-(void)layoutSubviews {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
_v1.frame = CGRectMake(0, 0, 40, 40);
_v2.frame = CGRectMake(self.bounds.size.width - 40, 0, 40, 40);
_v3.frame = CGRectMake(self.bounds.size.width - 40, self.bounds.size.height - 40, 40, 40);
_v4.frame = CGRectMake(0, self.bounds.size.height - 40, 40, 40);
[UIView commitAnimations];
}
@end
—————————————————————————————————————————————————————————————————————————————————————————————————————————
#import <UIKit/UIKit.h>
#import "ViewController.h"
#import "JCViewViewController.h"
#import "JCSuperView.h"
@interface ViewController ()
@end
@implementation ViewController
//在第一次加载被使用
- (void)viewDidLoad {
[super viewDidLoad];
[self makeSuper];
}
-(void)makeSuper {
JCSuperView *superview = [[JCSuperView alloc] initWithFrame:CGRectMake(20, 20, 200, 300)];
[superview makeView];
superview.backgroundColor = [UIColor greenColor];
superview.tag = 101;
UIButton *b1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
b1.frame = CGRectMake(300, 600, 80, 40);
[b1 setTitle:@"放大" forState:UIControlStateNormal];
[b1 addTarget:self action:@selector(beBig) forControlEvents:UIControlEventTouchUpInside];
UIButton *b2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
b2.frame = CGRectMake(300, 700, 80, 40);
[b2 setTitle:@"缩小" forState:UIControlStateNormal];
[b2 addTarget:self action:@selector(beSmall) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:superview];
[self.view addSubview: b1];
[self.view addSubview: b2];
}
//事件放大功能
-(void)beBig {
JCSuperView *sview = (JCSuperView*)[self.view viewWithTag:101];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
sview.frame = CGRectMake(50, 50, 300, 400);
[UIView commitAnimations];
}
//实现缩小功能
-(void)beSmall {
JCSuperView *sview = (JCSuperView*)[self.view viewWithTag:101];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
sview.frame = CGRectMake(50, 50, 200, 300);
[UIView commitAnimations];
}
自动布局子视图
-(void)makeAutoView {
_sview = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 180, 280)];
_sview.backgroundColor = [UIColor blueColor];
_v1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
_v1.backgroundColor = [UIColor redColor];
_v1.text = @"1";
_v2 = [[UILabel alloc] initWithFrame:CGRectMake(140, 0, 40, 40)];
_v2.backgroundColor = [UIColor redColor];
_v2.text = @"2";
_v3 = [[UILabel alloc] initWithFrame:CGRectMake(140, 240, 40, 40)];
_v3.backgroundColor = [UIColor redColor];
_v3.text = @"3";
_v4 = [[UILabel alloc] initWithFrame:CGRectMake(0, 240, 40, 40)];
_v4.backgroundColor = [UIColor redColor];
_v4.text = @"4";
[_sview addSubview:_v1];
[_sview addSubview:_v2];
[_sview addSubview:_v3];
[_sview addSubview:_v4];
[self.view addSubview:_sview];
_center = [[UIView alloc]initWithFrame:CGRectMake(0, 0, _sview.bounds.size.width, 40)];
_center.center = CGPointMake(90, 140);
_center.backgroundColor = [UIColor redColor];
[_sview addSubview:_center];
//自动布局属性,设置子视图和父视图的相对关系
_center.autoresizingMask = UIViewAutoresizingFlexibleWidth| UIViewAutoresizingFlexibleTopMargin| UIViewAutoresizingFlexibleBottomMargin;
//设置左边为可变距离
_v2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
_v3.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
_v4.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
static BOOL flag = NO;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
if (flag == NO) {
_sview.frame = CGRectMake(20, 20, 360, 480);
flag = YES;
} else {
_sview.frame = CGRectMake(20, 20, 180, 280);
flag = NO;
}
[UIView commitAnimations];
}
在iOS13.0版本中beginAnimations
和commitAnimations
方法已经被废弃,不推荐在新的iOS开发中使用。现在的iOS开发更常用的是使用UIView
的动画块(animateWithDuration:animations:
)或UIViewPropertyAnimator
等更高级的API来实现动画效果。这些新的API提供了更灵活、更强大的动画控制能力,并提供了更好的性能和可读性。
以下是对上面程序使用animateWithDuration:animations:
进行改写
-(void)makeAutoView {
_sview = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 180, 280)];
_sview.backgroundColor = [UIColor blueColor];
_v1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
_v1.backgroundColor = [UIColor redColor];
_v1.text = @"1";
_v2 = [[UILabel alloc] initWithFrame:CGRectMake(140, 0, 40, 40)];
_v2.backgroundColor = [UIColor redColor];
_v2.text = @"2";
_v3 = [[UILabel alloc] initWithFrame:CGRectMake(140, 240, 40, 40)];
_v3.backgroundColor = [UIColor redColor];
_v3.text = @"3";
_v4 = [[UILabel alloc] initWithFrame:CGRectMake(0, 240, 40, 40)];
_v4.backgroundColor = [UIColor redColor];
_v4.text = @"4";
[_sview addSubview:_v1];
[_sview addSubview:_v2];
[_sview addSubview:_v3];
[_sview addSubview:_v4];
[self.view addSubview:_sview];
_center = [[UIView alloc]initWithFrame:CGRectMake(0, 0, _sview.bounds.size.width, 40)];
_center.center = CGPointMake(90, 140);
_center.backgroundColor = [UIColor redColor];
[_sview addSubview:_center];
//自动布局属性,设置子视图和父视图的相对关系
_center.autoresizingMask = UIViewAutoresizingFlexibleWidth| UIViewAutoresizingFlexibleTopMargin| UIViewAutoresizingFlexibleBottomMargin;
//设置左边为可变距离
_v2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
_v3.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
_v4.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
static BOOL flag = NO;
//参数一:动画时长
//参数二:代码块实现功能
[UIView animateWithDuration:1 animations:^{
if (flag == NO) {
self->_sview.frame = CGRectMake(20, 20, 360, 480);
flag = YES;
} else {
self->_sview.frame = CGRectMake(20, 20, 180, 280);
flag = NO;
}
}];
}
导航控制器
导航控制器的切换
//SceneDelegate.m的内容
#import "SceneDelegate.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#import "JCRootController.h"
@interface SceneDelegate ()
@end
@implementation SceneDelegate
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
_window.frame = [UIScreen mainScreen].bounds;
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[JCRootController alloc] init]];
[_window makeKeyAndVisible];
}
—————————————————————————————————————————————————————————————————————————————————————————————————————————
//根视图控制器的内容
#import "JCRootController.h"
#import "FirstViewController.h"
@interface JCRootController ()
@end
@implementation JCRootController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blueColor];
//设置导航栏风格
self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
self.title = @"第一级";
UIBarButtonItem *next = [[UIBarButtonItem alloc] initWithTitle:@"下一级" style:UIBarButtonItemStylePlain target:self action:@selector(pressNext)];
self.navigationItem.rightBarButtonItem = next;
}
-(void)pressNext {
FirstViewController *first = [[FirstViewController alloc] init];
[self.navigationController pushViewController:first animated:YES];
}
—————————————————————————————————————————————————————————————————————————————————————————————————————————
#import "FirstViewController.h"
#import "SecondViewController.h"
@interface FirstViewController ()
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
self.title = @"第二级";
//系统会自动生成左侧的按钮,其按钮名称默认为上一级的title
UIBarButtonItem *next = [[UIBarButtonItem alloc] initWithTitle:@"下一级" style:UIBarButtonItemStylePlain target:self action:@selector(pressNext)];
self.navigationItem.rightBarButtonItem = next;
// Do any additional setup after loading the view
}
-(void)pressNext {
SecondViewController *second = [[SecondViewController alloc] init];
[self.navigationController pushViewController:second animated:YES];
}
—————————————————————————————————————————————————————————————————————————————————————————————————————————
//第三个controller的内容
#import "SecondViewController.h"
@interface SecondViewController ()
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"第三级";
self.view.backgroundColor = [UIColor yellowColor];
// Do any additional setup after loading the view.
}
@end
导航栏和工具栏
-
barStyle
:导航栏风格 -
barTintColor
:导航栏颜色 -
tintColor
:导航栏风格颜色 -
toolBarItems
:工具栏元素数组 -
UIBarItemFlexibleSpace
:自动调整距离按钮#import "JCRootController.h" #import "FirstViewController.h" @interface JCRootController () @end @implementation JCRootController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor orangeColor]; // 设置导航栏风格颜色 self.navigationController.navigationBar.barStyle = UIBarStyleBlack; // 设置导航栏为不透明 self.navigationController.navigationBar.translucent = NO; // 设置导航栏的背景颜色 UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init]; appearance.backgroundColor = [UIColor redColor]; self.navigationController.navigationBar.scrollEdgeAppearance = appearance; // 设置导航栏的标题颜色 self.title = @"导航栏"; //工具栏按钮创建 self.navigationController.toolbarHidden = NO; UIBarButtonItem *btn1 = [[UIBarButtonItem alloc] initWithTitle:@"left" style:UIBarButtonItemStyleDone target:nil action:nil]; UIBarButtonItem *btn2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:nil action:nil]; UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; UIImage *image = [UIImage imageNamed:@"1.jpg"]; [btn setImage:image forState:UIControlStateNormal]; btn.frame = CGRectMake(0, 0, 30, 30); // 调整按钮的frame大小以适应图片 UIBarButtonItem *btn3 = [[UIBarButtonItem alloc] initWithCustomView:btn]; //设置一个占位按钮,放到数组中可以用来分隔开各按钮 //设置宽度固定的占位按钮,注:此处方法名为UIBarButtonSystemItemFixedSpace(FixedSpace!!!!!) UIBarButtonItem *btnF1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFixedSpace target: nil action: nil]; btnF1.width = 110; //设置自动计算宽度的占位按钮,注:此处方法名为UIBarButtonSystemItemFlexibleSpace (FlexibleSpace!!!!!) UIBarButtonItem *btnF2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace target: nil action: nil]; NSArray *arrayBtn = [NSArray arrayWithObjects: btn1, btnF2, btn3, btnF2, btn2, nil]; self.toolbarItems = arrayBtn; }
分栏控制器
基础
//SceneDelegate.m
#import "SceneDelegate.h"
#import "ViewController.h"
#import "JCRootViewController.h"
@interface SceneDelegate ()
@end
@implementation SceneDelegate
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
self.window.frame = [UIScreen mainScreen].bounds;
//创建视图控制器
JCRootViewController *root = [[JCRootViewController alloc] init];
//创建导航控制器——主要用于管理多个视图控制器的切换
//在创建控制器,一定要有一个根视图控制器
//参数一:就是作为导航控制器的根视图控制器
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:root];
//将根视图设置为导航控制器
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
}
- (void)sceneDidDisconnect:(UIScene *)scene {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
- (void)sceneDidBecomeActive:(UIScene *)scene {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
- (void)sceneWillResignActive:(UIScene *)scene {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
- (void)sceneWillEnterForeground:(UIScene *)scene {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
- (void)sceneDidEnterBackground:(UIScene *)scene {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
@end
—————————————————————————————————————————————————————————————————————————————————————————————————————————
//创建一个新的controller的子类,作为新的主根视图
#import"JCRootViewController.h"
@interface JCRootViewController ()
@end
@implementation JCRootViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor yellowColor];
//设置导航栏文字
self.title = @"根视图";
//设置导航元素项目标题
self.navigationItem.title = @"Title";//优先使用title为标题
//只能指定风格样式,系统风格的按钮内容或者标题字体不能改变
UIBarButtonItem *left = [[UIBarButtonItem alloc] initWithTitle:@"回退" style:UIBarButtonItemStyleDone target:self action:@selector(pressLeft)];
//向导航栏左侧的按钮进行赋值
self.navigationItem.leftBarButtonItem = left;
UIBarButtonItem *right = [[UIBarButtonItem alloc] initWithTitle:@"详情" style:UIBarButtonItemStylePlain target:self action:@selector(pressRight)];
//向导航栏右侧的按钮进行赋值
self.navigationItem.rightBarButtonItem = right;
//添加多个按钮,将多个控件添加至导航栏右侧之中
UILabel *l = [[UILabel alloc] init];
l.text = @"test";
l.textAlignment = NSTextAlignmentCenter;
UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithCustomView:l];
NSArray *arr = [NSArray arrayWithObjects:btn, right, nil];
self.navigationItem.rightBarButtonItems = arr;
}
-(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
高级使用
-
UITabBarltem
:分栏按钮元素对象 -
badgeValue
:分栏按钮提示信息 -
selectedIndex
:分栏控制器选中的控制索引 -
viewControllers
:分栏控制器管理数组 -
selectedViewController
:分栏控制器选中的控制器对象
//SceneDelegate.m
#import "SceneDelegate.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#import "ThirdViewController.h"
#import "fourthViewController.h"
#import "fifthViewController.h"
#import "sixthViewController.h"
@interface SceneDelegate ()
@end
@implementation SceneDelegate
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
_window.frame = [UIScreen mainScreen].bounds;
// 创建视图控制器
FirstViewController *v1 = [[FirstViewController alloc] init];
SecondViewController *v2 = [[SecondViewController alloc] init];
ThirdViewController *v3 = [[ThirdViewController alloc] init];
fourthViewController *v4 = [[fourthViewController alloc] init];
fifthViewController *v5 = [[fifthViewController alloc] init];
sixthViewController *v6 = [[sixthViewController alloc] init];
// 创建 UITabBarController 并设置视图控制器数组
UITabBarController *tabBarController = [[UITabBarController alloc] init];
//通过edit修改会修改数组之中元素的顺序
tabBarController.viewControllers = @[v1, v2, v3, v4, v5, v6];
// 设置每个选项卡的标题
v1.title = @"Tab 1";
v2.title = @"Tab 2";
v3.title = @"Tab 3";
v4.title = @"Tab 4";
v5.title = @"Tab 5";
v6.title = @"Tab 6";
// 将每个视图控制器设置不同的背景颜色
v1.view.backgroundColor = [UIColor redColor];
v2.view.backgroundColor = [UIColor blueColor];
v3.view.backgroundColor = [UIColor greenColor];
v4.view.backgroundColor = [UIColor yellowColor];
v5.view.backgroundColor = [UIColor purpleColor];
v6.view.backgroundColor = [UIColor orangeColor];
//导航栏颜色
tabBarController.tabBar.barTintColor = [UIColor whiteColor];
//改变按钮风格颜色
tabBarController.tabBar.tintColor = [UIColor blackColor];
// 将导航控制器设置为根视图控制器
_window.rootViewController = tabBarController;
//设置代理
tabBarController.delegate = self;
[_window makeKeyAndVisible];
}
//即将开始编辑时调用
-(void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(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 {
NSLog(@"已经结束编辑");
}
-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(@"选中后控制器对象 —— %lu",(unsigned long)tabBarController.selectedIndex);
}
- (void)sceneDidDisconnect:(UIScene *)scene {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
- (void)sceneDidBecomeActive:(UIScene *)scene {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
- (void)sceneWillResignActive:(UIScene *)scene {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
- (void)sceneWillEnterForeground:(UIScene *)scene {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
- (void)sceneDidEnterBackground:(UIScene *)scene {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
@end