当前位置: 首页 > news >正文

UI学习笔记(一)

UI学习

  • 一:UIView基础
    • frame属性
    • 隐藏视图对象:
    • UIView的层级关系
  • 二:UIWindow对象
  • 三:UIViewController基础
    • UIViewController使用
  • 四:定时器与视图移动
  • 五:UISwitch控件
  • 六:滑动条和进度条
  • 七:步进器和分栏控件
  • 八:警告对话框和等待提示器
  • 九:UITextField
  • 滚动视图
    • 滚动视图基础
    • 滚动视图高级
  • 总结


一:UIView基础

我们先来介绍一下frame属性

frame属性

frame框架可以理解为视图在父视图中的位置和大小的描述。具体来说,frame框架包括视图的原点坐标和宽高两个属性。

  1. 原点坐标(origin):原点坐标表示视图在父视图坐标系统中的位置,通常是相对于父视图左上角的距离。原点坐标是一个CGPoint对象,包括x和y两个属性。
  2. 宽高(size):宽高表示视图在父视图中的大小,通常是视图的宽度和高度。宽高是一个CGSize对象,包括width和height两个属性

而CGRectMake是一个用来创建CGRect结构体的函数,该函数传入四个参数,分别为原点坐标的x和y,宽高的width和height。

简而言之,我们对frame属性初始化,传入前两个参数确定开始位置,传入后两个参数作为视图的大小。这也是其他控件的基本属性。


UIview是iOS的视图对象,是显示在屏幕上的所有对象的基础类,
也就是说,所有显示在屏幕上的对象一定都继承与UIView,屏幕上所有能看到的对象都是UIView的子类

  • UIView是一个矩形对象,有背景颜色,可以显示,有层级关系
  • frame属性是UIView的基本属性,而UiView是其他对象的父类,因此所有对象都有该属性。

下面使用代码来展示UIView的基础内容:

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//初始化一个UIview对象UIView *view = [[UIView alloc] init];//设置UIview的位置view.frame = CGRectMake(100, 100, 100, 200);view.backgroundColor = [UIColor orangeColor];//将新建的视图添加到父亲视图上//1:将新建的视图显示到屏幕上//2:将视图作为父亲视图的子视图管理起来[self.view addSubview:view];//将自己从父亲视图删除掉//1.从父亲视图的管理中删除//2.不会显示在屏幕。//[view removeFromSuperview] ;
}

效果:
在这里插入图片描述

隐藏视图对象:

分别有三种方法:

  1. 设置hidde属性:是否隐藏
  2. 设置alpha属性:设置透明度
  3. 设置opaque属性:是否显示不透明
    //是否隐藏视图对象//YES:不显示//NO:显示,默认值为NOview.hidden = YES;//设置视图的透明度//alpha= 1:不透明//a = 0 :透明//a = 0.5: 半透明view.alpha = 1;//设置是否显示不透明view.opaque = YES;

UIView的层级关系

UIview是在父视图中可以用self.view.subviews[]的数组下标来查看,而这个数组是有顺序的,即层级关系。

  • 先加入的视图,在数组的开始,即在屏幕的最底层。
  • 重复加入,不会开辟新的数组位置,而是移动数组的排序方式。
  • 可以使用bringSubviewToFront、sendSubviewToBack等方法来改变视图的顺序。
  • removeFromSuperview方法可以删除子视图。
- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.UIView *view1 = [[UIView alloc] init];view1.frame = CGRectMake(100, 100, 150, 150);view1.backgroundColor = [UIColor orangeColor];UIView *view2 = [[UIView alloc] init];view2.frame = CGRectMake(125, 125, 150, 150);view2.backgroundColor = [UIColor blueColor];UIView *view3 =[[UIView alloc] init];view3.frame = CGRectMake(150, 150, 150, 150);view3.backgroundColor = [UIColor blackColor];//将三个视图对象显示到屏幕上并且添加到父亲视图上。//重复加入已有元素,不会扩大数组,而是移动数组[self.view addSubview:view1];[self.view addSubview:view2];[self.view addSubview:view3];[self.view addSubview:view1];//[self.view addSubview:view2];//将某一个视图调整到最前面显示//参数:UIView对象,调整到一个视图到最前方//实际上也移动了数组的位置。//   [self.view bringSubviewToFront:view1];//将某一个视图调整到最后显示//参数:UIView对象,调整哪一个视图到最后//实际上也移动了数组的位置//   [self.view sendSubviewToBack:view3];UIView *viewFront = self.view.subviews[0];//    [view1 removeFromSuperview];UIView *viewBack = self.view.subviews[2];if (viewFront == view2) {NSLog(@"等于");}if (viewBack == view1) {NSLog(@"等于");}
}

效果:

在这里插入图片描述

同时,我们可以验证重复添加视图,是移动数组位置而不是创建新的数组。
在这里插入图片描述


二:UIWindow对象

注意:在XCode13之后我们使用代码来创建初始化一个UIWindow对象不在AppDelegate类中进行,而是在SceneDelegate类进行,并且不需要创建UIWindow对象,只需要为其初始化视图管理器后即可进行使用。

UIWindow对象是UIView最顶层的容器,包含应用并显示所有的UIView对象。同时,也可以反映传递事件给UIView。
下面是UIWindow的一些基本使用。

SceneDelegate.m文件


#import "SceneDelegate.h"@interface SceneDelegate ()@end@implementation SceneDelegate- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {//对UIWindow对象创建视图控制器self.window.rootViewController = [[UIViewController alloc] init] ;//设置背景颜色self.window.backgroundColor = [UIColor blackColor];//直接给window上添加视图UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 200)];view1.backgroundColor = [UIColor blueColor];UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(150, 0, 50, 200)];view2.backgroundColor = [UIColor redColor];//当创建一个新的背景视图,然后将这个视图作为window的子视图,再让view1作为背景视图的子视图,就会有一个层级关系//当移动背景视图的时候,view1视图也会随着移动,子视图是参照父视图的坐标系UIView *backview = [[UIView alloc] initWithFrame:CGRectMake(100, 400, 200, 200)];backview.backgroundColor = [UIColor whiteColor];//将子视图添加到爸爸视图上[backview addSubview:view1];[backview addSubview:view2];[self.window addSubview:backview];NSLog(@"%@", view1.window);NSLog(@"%@", backview.window);NSLog(@"%@", self.window);//使window有效并显示到屏幕上[self.window makeKeyAndVisible];}

效果:
在这里插入图片描述
同时,通过对三个window对象的打印,我们可以印证整个程序仅有一个UIWindow对象。
在这里插入图片描述


三:UIViewController基础

UIViewController是视图控制器的意思。整个UIKit框架中只能有一个根视图控制器,属于window属性,但是可以有多个视图控制器,视图控制器用来管理界面和处理界面的逻辑类对象,程序启动前必须对根视图控制器赋值。
我们在SceneDelegate.m文件中实现对根视图控制器的初始化。

#import "SceneDelegate.h"
#import "ViewController.h"
@interface SceneDelegate ()@end@implementation SceneDelegate- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {ViewController *vcRoot = [[ViewController alloc] init];self.window.rootViewController = vcRoot;self.window.backgroundColor = [UIColor redColor];}

UIViewController使用

通过对UIViewController的学习,我们可以实现视图控制界面的切换。下面我们实操来加深学习。

首先,我们需要创建视图控制器,并为其初始化不同的颜色。
之后我们可以调用presentViewController方法,实现显示一个新的视图控制器界面到屏幕上。再在新的view文件中使用dismissViewControllerAnimated方法(关闭当前视图控制器界面),回到原来的视图控制器界面。

具体实现代码:

ViewController.m文件

#import "ViewController.h"
#import "ViewC02.h"
@interface ViewController ()@end@implementation ViewController-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{//创建视图控制器二ViewC02* vc = [[ViewC02 alloc] init];//整个屏幕vc.modalPresentationStyle = UIModalPresentationFullScreen;//显示一个新的视图控制器到屏幕上//P1:新的视图控制器对象//P2:使用动画切换动画效果//P3:切换结束后功能调用,不需要则穿nil[self presentViewController:vc animated:YES completion:nil];
}
//第一次程序加载视图时调用
//只调用一次
- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.self.view.backgroundColor = [UIColor blueColor];NSLog(@"viewDidLoad 第一次加载!");
}//当视图控制器的视图即将显示时,调用次函数
//视图分为:1.显示前 2.正在处于显示状态 3.已经被隐藏
//参数:是否用动画切换后显示
- (void) viewWillAppear:(BOOL)animated
{NSLog(@"viewWillAppear,视图即将显示!");
}
//视图即将消失,调用次函数
//参数:表示是否用动画切换后消失
//当前的状态:视图还显示在屏幕上
-(void) viewWillDisAppear:(BOOL)animated
{NSLog(@"视图即将消失!");
}//当视图已经显示到屏幕后到瞬间调用次函数
//参数:表示是否用动画切换显示的
//当前状态:已经显示到屏幕上
-(void) viewDidAppear:(BOOL)animated
{NSLog(@"视图已经显示");
}//当前视图已经从屏幕上消失
//参数:表示是否用动画切换显示的
//当前状态:当前视图控制器视图已经消失
-(void) viewDidDisappear:(BOOL)animated
{NSLog(@"视图已经消失!");
}
@end

ViewC02.m文件:

#import "ViewC02.h"@interface ViewC02 ()@end@implementation ViewC02- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.self.view.backgroundColor = [UIColor orangeColor];
}-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{	//点击屏幕后使当前视图控制器界面消失。[self dismissViewControllerAnimated:YES completion:nil];
}

效果:点击前:
在这里插入图片描述
点击后:
在这里插入图片描述

上图代码中,我们还加入了一些操作函数,来显示屏幕的调用。
注意:添加下述代码后,才会使整个屏幕切换,从而显示viewDidDisappear操作函数。

vc.modalPresentationStyle = UIModalPresentationFullScreen;

代码运行结果:
在这里插入图片描述


四:定时器与视图移动

创建一个定时器,先要在接口文件中创建NSTimer属性。

@property (retain, nonatomic) NSTimer *timerVier;

之后,采用scheduledTimerWithTimeInterval:的类方法来创建定时器。并启动该定时器。
该方法有五个参数:

P1:每隔多长时间调用定时器函数,以秒为单位
P2:表示实现定时器函数的对象(指针)
P3:定时器函数对象
P4:可以传入定时器函数中一个参数,无参数可以传nil
P5:定时器是否重复操作,YES为重复,NO只完成一次函数调用

而我们要实现使指定view对象移动,需要先为view对象设置一个标签值,在定时器的事件函数中进行使用。
下列代码中的view.frame =CGRectMake(view.frame.origin.x+1, view.frame.origin.y+1, 80, 80);即实现这一功能,使view视图的x,y轴随时间移动。

ViewController.m文件

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController@synthesize timerVier = _timerVier;- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];btn.frame = CGRectMake(100, 100, 80, 40);[btn setTitle:@"启动定时器" forState:UIControlStateNormal];[btn addTarget:self action:@selector((pressStart)) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:btn];UIButton *btnStop = [UIButton buttonWithType:UIButtonTypeRoundedRect];btnStop.frame = CGRectMake(100, 200, 80, 40);[btnStop setTitle:@"停止定时器" forState:UIControlStateNormal];[btnStop addTarget:self action:@selector(pressStop) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:btnStop];UIView *view = [[UIView alloc] init];view.frame = CGRectMake(0, 0, 80, 80);view.backgroundColor = [UIColor blueColor];[self.view addSubview:view];//设置view对标签值//通过爸爸视图对象以及view的标签值可以获得相应的对象view.tag = 101 ;
}//按下开始按钮函数
- (void) pressStart
{//NSTimer的类方法创建一个定时器并启动这个定时器//P1:每隔多长时间调用定时器函数,以秒为单位//P2:表示实现定时器函数的对象(指针)//P3:定时器函数对象//P4:可以传入定时器函数中一个参数,无参数可以传nil//P5:定时器是否重复操作,YES为重复,NO只完成一次函数调用//返回值为一个新建好的定时器对象_timerVier = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(updateTimer:) userInfo:@"lyf" repeats:YES];
}//定时器函数
//可以将定时器本身作为参数传入
-(void) updateTimer:(NSTimer*) timer
{   //userInfo为id类型NSLog(@"test!!  name = %@", timer.userInfo);//tag最好从100开始UIView *view = [self.view viewWithTag:101];view.frame =CGRectMake(view.frame.origin.x+1, view.frame.origin.y+1, 80, 80);
}
//按下停止按钮时调用
-(void) pressStop
{if (_timerVier != nil) {//停止定时器[_timerVier invalidate];}
}
@end

效果:
在这里插入图片描述
在这里插入图片描述
还有一点需要注意:如果对上述代码连续点击两次启动定时器,此时再按停止定时器将无法停止视图移动。
原因:每次点击都创造出一个定时器对象,从而使第一次点击的定时器对象无法覆盖。即无法再停止第一个定时器对象,只能停止新建立的定时器对象。
解决办法:将该属性变成单例模式,或者每次进入pressStart时,调用一遍结束方法。即:

- (void) pressStart
{[self pressStop];//每次调用前先关闭前一个定时器。_timerVier = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(updateTimer:) userInfo:@"lyf" repeats:YES];
}

五:UISwitch控件

UISwitch控件是苹果官方库提供的一个控件,与定时器相同,需要先在接口部分声明一个属性,在实现部分实现其具体功能。
但是,作为苹果官方的控件,苹果对其作出了一定的限制:如无法改变宽度高度值和设计样式。
下例代码详细展示了该控件的使用:

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController@synthesize  mySwitch = _mySwitch;- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//创建一个开关对象_mySwitch = [[UISwitch alloc] init];//苹果官方的控件的位置设置//位置X,Y的值可以改变//宽度高度值是无法改变。系统默认设置了_mySwitch.frame = CGRectMake(100, 100, 0, 0);//开关状态设置属性//YES:开启状态//NO:关闭状态//_mySwitch.on = YES;//[_mySwitch setOn:YES];//设置开关状态//P1:状态设置//P2:是否开启动画效果[_mySwitch setOn:YES animated:YES];[self.view addSubview:_mySwitch];//设置开启状态的风格颜色[_mySwitch setOnTintColor:[UIColor orangeColor]];//设置开关圆按钮的风格颜色[_mySwitch setThumbTintColor:[UIColor blueColor]];//设置整体风格颜色 没作用原因已截图[_mySwitch setTintColor:[UIColor redColor]];//向开关控件添加事件函数//P1:函数实现对象//P2:函数对象//P3:事件响应时的事件类型UIControlEventValueChanged:状态发生变化[_mySwitch addTarget:self action:@selector(swChange:) forControlEvents:UIControlEventValueChanged];
}
- (void) swChange:(UISwitch*) sw
{if (sw.on == YES) {NSLog(@"哈哈,打开咯");}else {NSLog(@"哈哈,关闭咯");}NSLog(@"我变质了");
}@end

在这里插入图片描述
代码结果:
在这里插入图片描述


六:滑动条和进度条

滑动条与进度条也需要在接口部分定义属性,在实现部分实现功能。
除了对这两个的基本使用,我们还可以实现用滑动条来控制进度条的长短,当滑动条与进度条不是相同长度时,我们可以使用下面的代码来实现等比例控制。

pView.progress = (_slider.value - _slider.minimumValue) / (_slider.maximumValue - _slider.minimumValue);

ViewController.h

#import <UIKit/UIKit.h>@interface ViewController : UIViewController
{//进度条对象//一般用来表示下载或者视频播放的进度UIProgressView *    pView;//滑动条定义//一般用来进行调整音频音乐的音量等UISlider *_slider;
}
//定义一个进度条属性
@property (retain, nonatomic) UIProgressView *pView;
//定义一个滑动条属性
@property (retain, nonatomic) UISlider *slider;
@end

ViewController.m

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController@synthesize  slider = _slider;
@synthesize pView = _pView;- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//进度条的创建pView = [[UIProgressView alloc] init];//进度条的位置大小设置//进度条的高度是不可以变化的.P4不可变pView.frame = CGRectMake(50, 100, 300, 40);pView.progressTintColor = [UIColor greenColor];pView.trackTintColor = [UIColor blackColor];//设置进度条的进度值//范围从0-1//最小值为0,最大值为1pView.progress = 0;//设置进度条的风格特征pView.progressViewStyle = UIProgressViewStyleBar;[self.view addSubview:   pView];//创建滑动条对象_slider = [[UISlider alloc] init];//位置设置,高度不可变更_slider.frame = CGRectMake(10, 200, 300, 40);//设置滑动条的最大值_slider.maximumValue = 100;//设置滑动条的最小值,可以为负_slider.minimumValue = -100;//设置滑动条的滑块位置_slider.value = 0;//左侧滑条背景颜色// _slider.minimumTrackTintColor = [UIColor blueColor];//右侧滑动条背景颜色_slider.maximumTrackTintColor = [UIColor greenColor];//设置滑块颜色_slider.thumbTintColor = [UIColor orangeColor];[_slider addTarget:self action:@selector(pressSlider) forControlEvents:UIControlEventValueChanged];[self.view addSubview:_slider];
}-(void) pressSlider
{pView.progress = (_slider.value - _slider.minimumValue) / (_slider.maximumValue - _slider.minimumValue);NSLog(@"value = %f", _slider.value);
}@end

效果:
在这里插入图片描述

七:步进器和分栏控件

先要在接口文件中定义步进器对象和分栏控制器对象。

ViewController.h

#import <UIKit/UIKit.h>@interface ViewController : UIViewController
{//定义步进器对象//按照一定的数字来调整某个数据UIStepper *_stepper;//分栏控制器定义UISegmentedControl *_segControl;
}@property (retain, nonatomic) UIStepper *stepper;
@property (retain, nonatomic) UISegmentedControl *segControl;@end

在.m文件中,我们不仅可以以文本来初始化分拦控件,还可以以照片来初始化分拦控件。
ViewController.m

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController@synthesize stepper = _stepper;
@synthesize segControl = _segControl;- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view._stepper = [[UIStepper alloc] init];//只能设置位置,宽高不能改变_stepper.frame = CGRectMake(100, 100, 80, 40);//设置步进器的最小值_stepper.minimumValue = 0;//设置步进器的最大值_stepper.maximumValue = 100;//设置步进器的当前值,默认值为0_stepper.value = 10;//设置步进器每次向前或者向后步进的步伐值_stepper.stepValue = 5;//是否可以重复响应事件操作_stepper.autorepeat = YES;//是否将步进结果通过事件函数响应出来//不显示中间过程,长按直接显示结果。_stepper.continuous = NO;//添加事件函数[_stepper addTarget:self action:@selector(stepChange) forControlEvents:UIControlEventValueChanged];[self.view addSubview:_stepper];_segControl = [[UISegmentedControl alloc] init];//宽度可变,高度不可变_segControl.frame = CGRectMake(10, 200, 300, 40);//添加一个按钮元素[_segControl insertSegmentWithTitle:@"0元" atIndex:0 animated:NO];//参数一:按钮选项文字//参数二:按钮索引位置//参数三:是否有插入的动画效果[_segControl insertSegmentWithTitle:@"5元" atIndex:1 animated:NO];[_segControl insertSegmentWithTitle:@"10元" atIndex:2 animated:NO];// [_segControl insertSegmentWithTitle:@"30元" atIndex:0 animated:NO];//以照片作为分拦控件的图像。//注意要将照片放入当前视图内。UIImage *image = [UIImage imageNamed:@"WechatIMG26890.jpg"];image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];[_segControl setImage:image forSegmentAtIndex:2];//当前默认按钮索引设置_segControl.selectedSegmentIndex = 0;[_segControl addTarget:self action:@selector(segChange) forControlEvents:UIControlEventValueChanged];[self.view addSubview:_segControl];
}-(void) segChange
{NSLog(@"%d", _segControl.selectedSegmentIndex);
}-(void) stepChange
{NSLog(@"step press! value = %f", _stepper.value);
}@end

效果
在这里插入图片描述
代码结果:
在这里插入图片描述


八:警告对话框和等待提示器

在遇到电量不足等特殊情况时,可以弹出警告对话框提示用户。
在下载或加载比较大的文件时,可以显示等待提示器提示用户。
我们在ViewController 的接口文件中定义这两个对象。

@interface ViewController : UIViewController
{//定义一个警告对话框视图对象UIAlertController *_alertView;//等待提示对象//当下载,或加载比较大的文件时,可以显示此控件,处于提示等待状态UIActivityIndicatorView *_activityIndicator;
}@property (retain, nonatomic) UIAlertController *alertVier;
@property (retain, nonatomic) UIActivityIndicatorView *act;@end

在实现部分,我们先建立两个按钮,用来弹出提示器。
随后开始实现这两个提示器。

  • 警告对话框
[UIAlertController alertControllerWithTitle:@"警告" message:@"你的手机已经被劫持!!!" preferredStyle:UIAlertControllerStyleAlert];

使用如上代码,设置样式为弹出警告式的对话框。参一为标题,参二为警告内容。

 UIAlertAction* action01 = [UIAlertAction actionWithTitle:@"打钱" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){/* 在这里编写执行该选项的代码*/}];

随后创建三个不同的action对象,如上所示参一为提示,参二为样式,参三为需要执行的代码块
样式为以下四种:

  1. UIAlertActionStyleDefault:默认样式,用于表示用户可以选择的主要操作。
  2. UIAlertActionStyleCancel:取消样式,通常用于取消操作,只能有一个取消按钮。
  3. UIAlertActionStyleDestructive:破坏性样式,用于表示执行此操作可能有破坏性后果。
  4. UIAlertActionStyleTextInput:输入样式,允许用户在弹出的警告框中输入文本。

最后将操作对象加入到警告框中,再使该警告框显示。

  • 等待提示器
    等待提示器的高度和宽度由苹果官方设定,不可改变。可以设置四种不同风格的等待指示器。
  1. UIActivityIndicatorViewStyleWhiteLarge:表示一个白色的大号等待提示器。
  2. UIActivityIndicatorViewStyleWhite:表示一个白色的普通大小等待提示器。
  3. UIActivityIndicatorViewStyleGray:表示一个灰色的普通大小等待提示器。
  4. UIActivityIndicatorViewStyleMedium:表示一个中等大小的等待提示器,通常是灰色的。
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController@synthesize alertVier = _alertVier;
@synthesize act = _act;- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.for (int i = 0; i < 2; i++){UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];btn.frame = CGRectMake(100, 100 + 100 * i, 100, 40);if (i == 0){[btn setTitle:@"警告对话框" forState:UIControlStateNormal];} else if (i == 1) {[btn setTitle:@"等待指示器" forState:UIControlStateNormal];}btn.tag = 101 + i;[btn addTarget:self action:@selector(pressBtn:) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:btn];}}- (void)pressBtn:(UIButton*) btn {//警告对话框创建if (btn.tag == 101) {_alertView = [UIAlertController alertControllerWithTitle:@"警告" message:@"你的手机已经被劫持!!!" preferredStyle:UIAlertControllerStyleAlert];UIAlertAction* action01 = [UIAlertAction actionWithTitle:@"打钱" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){/* 在这里编写执行该选项的代码*/}];UIAlertAction* action02 = [UIAlertAction actionWithTitle:@"打钱" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){/* 在这里编写执行该选项的代码*/}];UIAlertAction* action03 = [UIAlertAction actionWithTitle:@"投降" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){/* 在这里编写执行该选项的代码*/}];[_alertView addAction:action01];[_alertView addAction:action02];[_alertView addAction:action03];[self presentViewController:_alertView animated:YES completion:nil];} else if (btn.tag == 102){//宽度和高度不可改变_activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(100, 300, 80, 80)];//设定提示的风格_activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium;_activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleLarge;[self.view addSubview:_activityIndicator];//启动动画并显示[_activityIndicator startAnimating];//停止动画并隐藏//[_activityIndicator stopAnimating];}
}@end

效果:
(点击警告对话框)
在这里插入图片描述
(点击等待指示器):
在这里插入图片描述

九:UITextField

先要在ViewController的接口部分中定义一个UITextField属性,在接口部分实现。
作为一个文本控件,该控件只能输入一行文本,不能输入或显示多行,常用来做登录界面。
我们可以设置文本的大小,位置,边框风格和键盘风格,字体的大小和颜色。此处主要介绍边框风格和键盘风格
边框风格:

  1. UITextBorderStyleRoundedRect圆角风格
  2. UITextBorderStyleLine线框风格
  3. UITextBorderStyleBezel:bezel风格
  4. UITextBorderStyleNone:无边框风格

键盘风格(常用):

  1. UIKeyboardTypeDefault:默认风格
  2. UIKeyboardTypeNamePhonePad:字母和数字组合风格
  3. UIKeyboardTypeNumberPad:纯数字风格
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController@synthesize textField = _textField;- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//设定一个文本输入区对象self.textField = [[UITextField alloc] init];//设定文字输入区的位置self.textField.frame = CGRectMake(100, 100, 180, 40);//设置textField的内容文字self.textField.text = @"用户名";//设置文字的字体大小self.textField.font = [UIFont systemFontOfSize:15];//设置字体的颜色self.textField.textColor = [UIColor blueColor];//设置边框风格//UITextBorderStyleRoundedRect圆角风格//UITextBorderStyleLine线框风格//UITextBorderStyleBezel:bezel风格//UITextBorderStyleNone:无边框风格self.textField.borderStyle = UITextBorderStyleLine;//设置虚拟键盘风格//UIKeyboardTypeDefault:默认风格//UIKeyboardTypeNamePhonePad:字母和数字组合风格//UIKeyboardTypeNumberPad:纯数字风格self.textField.keyboardType = UIKeyboardTypeNumberPad;//提示文字信息//当text属性为空self.textField.placeholder = @"请输入用户名....";//是否作为密码输入//YES作为密码加密,NO正常显示self.textField.secureTextEntry = NO;[self.view addSubview:self.textField];
}- (void) textFieldDidBeginEditing:(UITextField *)textField
{NSLog(@"开始编辑了!");
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{self.textField.text = @"";NSLog(@"编辑输入结束了");
}//是否可以进行输入
//如果返回值为YES:可以进行输入,默认为YES
//NO:不能输入文字,无权限的时候
-(BOOL) textFieldShouldBeginEditing:(UITextField *)textField
{return YES;
}//是否可以结束输入
//如果返回值为YES:可以结束输入,默认为YES
//NO:不能结束文字,输入密码位数不够
-(BOOL) textFieldShouldEndEditing:(UITextField *)textField
{if (self.textField.text.length < 9) {return NO;} else {return YES;}
}//点击屏幕空白处调用此函数
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{//使虚拟键盘回收,不再做为第一消息响应者[self.textField resignFirstResponder];
}@end

UITextField控件的四个协议:
开始编辑协议:手机键盘弹出瞬间调用

- (void) textFieldDidBeginEditing:(UITextField *)textField

结束编辑协议:手机键盘收回瞬间调用

-(void) textFieldDidEndEditing:(UITextField *)textField

是否可以进行输入
如果返回值为YES:可以进行输入,默认为YES
NO:不能输入文字
使用场景:无权限的时候使用

-(BOOL) textFieldShouldBeginEditing:(UITextField *)textField

是否可以结束输入
如果返回值为YES:可以结束输入,默认为YES
NO:不能结束文字
使用场景:输入密码位数不够

-(BOOL) textFieldShouldEndEditing:(UITextField *)textField

在这里插入图片描述

滚动视图

手机屏幕较小,通常情况下无法完全展示内容,此时我们可以通过手势来滚动屏幕,达到移动视图的效果,而这个应用就是滚动视图。
像我们常用的QQ聊天页面,微信聊天页面等,就是滚动视图的实际应用。

滚动视图基础

我们可以设置上下滚动的视图,也可以设置左右滚动的视图,对应的画布大小需要跟着改变。
滚动视图的创建在视图控制器中进行,即ViewController文件中进行。
图片的添加我们采用循环的方式简略。


#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.UIScrollView *sv = [[UIScrollView alloc] init];//设置滚动视图的位置,使用矩形来定位视图位置sv.frame = CGRectMake(0, 0, 394, 852);//是否按照整页来滚动视图sv.pagingEnabled = YES;//是否可以开启滚动效果sv.scrollEnabled = YES;//设置画布的大小,画布显示在滚动视图内部,一般大于Frame的大小sv.contentSize = CGSizeMake(394*6, 852*2);//是否可以边缘弹动效果sv.bounces = YES;//开启横向弹动效果sv.alwaysBounceHorizontal = YES;//开启纵向弹动效果sv.alwaysBounceVertical = YES;//显示横向滚动效果sv.showsHorizontalScrollIndicator = YES;//显示纵向滚动条sv.showsVerticalScrollIndicator = YES;//设置背景颜色sv.backgroundColor = [UIColor whiteColor];//使用循环创建5张图片视图for (int i = 0; i < 5; i++){NSString *strName = [NSString stringWithFormat:@"%d.jpg", i+1];UIImage *image = [UIImage imageNamed:strName];UIImageView *iView = [[UIImageView alloc] initWithImage:image];iView.frame = CGRectMake(394*i, 0, 394, 952);[sv addSubview:iView];}[self.view addSubview:sv];
}@end

在这里插入图片描述

滚动视图高级

滚动视图中还有一个协议叫UIScrollViewDelegate,这个协议可以让我们实现更多控制效果。我们新建一个竖屏滚动效果来学习这个协议的方法。

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.scrollView = [[UIScrollView alloc] init];scrollView.frame = CGRectMake(10, 50, 384, 802);//取消弹动效果scrollView.bounces = NO;//是否允许通过点击屏幕让滚动视图响应事件//YES:滚动视图可以接受触碰事件//NO:不接受触屏事件//scrollView.userInteractionEnabled = NO;//设置画布大小,纵向效果scrollView.contentSize = CGSizeMake(384, 802*9);for (int i = 0; i < 9; i++){//生成图片名称NSString *strName = [NSString stringWithFormat:@"%d.jpg", i+1];UIImage *image = [UIImage imageNamed:strName];UIImageView *iView = [[UIImageView alloc] init];iView.image = image;iView.frame = CGRectMake(0, 802 * i, 384, 802);[scrollView addSubview:iView];}[self.view addSubview:scrollView];//取消按页滚动效果scrollView.pagingEnabled = NO;//滚动视图画布的移动位置,偏移位置//功能:决定画笔显示的最终图像结果scrollView.contentOffset = CGPointMake(0, 0);//将当前视图控制器作为代理对象scrollView.delegate = self;
}//当滚动视图移动时,只要offset坐标发生变化,都会调用此函数
//参数:调用次协议的滚动视图对象
//可以使用此函数来监控滚动视图的位置
//- (void) scrollViewDidScroll:(UIScrollView *)scrollView
//{
//    NSLog(@"y = %f", scrollView.contentOffset.y);
//}- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{//scrollView.contentOffset = CGPointMake(0, 0);//让滚动视图移动到指定位置,动画移动[scrollView scrollRectToVisible:CGRectMake(0, 0, 384, 802) animated:YES];
}//结束滑动时调用
-(void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{NSLog(@"Did End Drag!");
}
//将要开始滑动时调用
-(void) scrollViewWillBeginDragging:(UIScrollView *)scrollView
{NSLog(@"will Begin Drag");
}
//结束滑动视图后,准备结束滑行调用该函数
-(void) scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{NSLog(@"Will End Drag!");
}
//准备开始滑动时调用该方法
-(void) scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{NSLog(@"Will Begin Deceleratege!");
}
//停止滑动时调用该方法
-(void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{NSLog(@"视图停止移动");
}
@end

注意:当结束滑动后,会有一个类似于惯性的滑动效果,此时会调用不同的方法。
效果:
在这里插入图片描述


总结

多多学习,多多思考。这篇博客的总结让我加深了对UI控件的认识,并且熟练了很多UI控件的使用

相关文章:

UI学习笔记(一)

UI学习 一&#xff1a;UIView基础frame属性隐藏视图对象&#xff1a;UIView的层级关系 二&#xff1a;UIWindow对象三&#xff1a;UIViewController基础UIViewController使用 四&#xff1a;定时器与视图移动五&#xff1a;UISwitch控件六&#xff1a;滑动条和进度条七&#xf…...

【C语言训练题库】扫雷->简单小游戏!

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 目录 1. 题目 2. 解析 3. 代码 4. 小结 1. 题目 小sun上课的时候非常喜欢玩扫雷。他现小sun有一个初始的雷矩阵&#xff0c;他希望你帮他生成一个扫雷矩阵。 扫雷…...

WMS仓储管理系统高效驱动制造企业物料管理

在现代制造业的快速发展中&#xff0c;仓储管理作为供应链的核心环节&#xff0c;其效率直接影响到企业的生产力和市场竞争力。随着科技的进步&#xff0c;实施WMS仓储管理系统逐渐成为推动仓储管理向智能化转型的关键力量。本文将深入探讨WMS仓储管理系统如何以创新的方式驱动…...

python使用appium打开程序后,为什么没有操作后程序就自动退出了

当使用Appium打开应用程序并在没有执行任何操作后它自动退出&#xff0c;这可能是由于几个不同的原因。以下是一些可能的原因和相应的解决方案&#xff1a; 应用程序的默认行为&#xff1a; 有些应用程序在启动后如果没有用户交互&#xff0c;可能会因为超时或其他逻辑而自动关…...

MacBook M系列芯片安装php8.2

适用于M1\M2\M3等系列的MacBook&#xff0c;记录下安装过程 安装brew 打开终端&#xff0c;执行如下命令&#xff1a; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"安装zsh&#xff08;非必须&#xff09; …...

OlSoul系统调校程序v2024.06.05

软件介绍 OlSoul是一款能够适配用于Win各个系统的系统调校软件&#xff0c;OlSoul内置有众多调校功能可以直接使用&#xff0c;如有启用无线网络功能、启用打印机功能、系统快速休眠与休眠开关、快捷方式小箭头去除功能等&#xff0c;具体的调校功能多达几十项&#xff0c;可自…...

图像特征提取 python

1. 边缘检测 (Edge Detection) 1.1 Sobel 算子 Sobel 算子是一种边缘检测算子&#xff0c;通过计算图像梯度来检测边缘。 import cv2 import numpy as np# 读取图像 image cv2.imread(image.jpg, 0)# 应用 Sobel 算子 sobel_x cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize5)…...

width: 100%和 width: 100vw这两种写法有什么区别

width: 100%; 和 width: 100vw; 是两种不同的 CSS 写法&#xff0c;它们在实际应用中会有不同的效果。以下是这两种写法的主要区别&#xff1a; width: 100%; 定义&#xff1a;将元素的宽度设置为其包含块&#xff08;通常是父元素&#xff09;宽度的 100%。效果&#xff1a;元…...

如何在另一台电脑上使用相同的Python环境和依赖包

如果您想在另一台电脑上使用相同的Python环境和依赖包&#xff0c;有几种方法可以实现&#xff1a; 使用requirements.txt&#xff1a; 在您当前的虚拟环境中&#xff0c;您可以使用pip freeze > requirements.txt命令生成一个包含所有已安装包及其版本的文件。然后&#x…...

Vue3 响应式 API:工具函数(一)

isRef() isRef 是一个简单的工具函数&#xff0c;它接受一个参数并返回一个布尔值&#xff0c;指示该参数是否是一个由 ref 创建的响应式引用。 在某些情况下&#xff0c;你可能需要编写一些通用逻辑或函数&#xff0c;这些逻辑或函数需要处理不同类型的响应式数据&#xff08…...

开发常用软件

开发相关 代码编译 Visual Studio 2019 Visual Studio 2022 代码测试工具 LINQPad Premium 5 LINQPad 7 打包工具 Advanced Installer 反编译工具 ILSpy dnSpy spy 数据库相关 SQLite Expert Professional 5 DLL扫描工具 depends 界面设计 SvgToXaml Materi…...

conntrack如何限制您的k8s网关

1.1 conntrack 介绍 对于那些不熟悉的人来说,conntrack简单来说是Linux内核的一个子系统,它跟踪所有进入、出去或通过系统的网络连接,允许它监控和管理每个连接的状态,这对于诸如NAT(网络地址转换)、防火墙和保持会话连续性等任务至关重要。它作为Netfilter的一部分运行,…...

SwiftUI六组合复杂用户界面

代码下载 应用的首页是一个纵向滚动的地标类别列表&#xff0c;每一个类别内部是一个横向滑动列表。随后将构建应用的页面导航&#xff0c;这个过程中可以学习到如果组合各种视图&#xff0c;并让它们适配不同的设备尺寸和设备方向。 下载起步项目并跟着本篇教程一步步实践&a…...

高考分数查询结果自动推送至微信

又是一年高考时&#xff0c;祝各位学子金榜题名&#xff0c;天遂人愿! 在您阅读以下内容时&#xff0c;请注意&#xff1a;各省查分API接口可能不相同&#xff0c;本人仅就技术层面谈谈&#xff0c; 纯属无聊&#xff0c;因为实用意义不大&#xff0c;毕竟一年一次&#xff0c;…...

flask_sqlalchemy时间缓存导致datetime.now()时间不变问题

问题是这样的&#xff0c;项目在本地没什么问题&#xff0c;但是部署到服务器过一阵子发现&#xff0c;这个时间会在某一刻定死不变。 重启uwsgi后&#xff0c;发现第一条数据更新到了目前最新时间&#xff0c;过了一会儿再次发送也变了时间&#xff0c;但是再过几分钟再发就会…...

使用 PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理

教程简述 在本教程中&#xff0c;您将学习在阿里云交互式建模平台PAI-DSW x Free Prompt Editing&#xff08;CVPR2024中选论文算法&#xff09;图像编辑算法&#xff0c;开发个人AIGC绘图小助理&#xff0c;实现文本驱动的图像编辑功能单卡即可完成AIGC图片风格变化、背景变化…...

Nginx03-动态资源和LNMP介绍与实验、自动索引模块、基础认证模块、状态模块

目录 写在前面Nginx03案例1 模拟视频下载网站自动索引autoindex基础认证auth_basic模块状态stub_status模块模块小结 案例2 动态网站&#xff08;部署php代码&#xff09;概述常见的动态网站的架构LNMP架构流程数据库Mariadb安装安全配置基本操作 PHP安装php修改配置文件 Nginx…...

山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(二十九)- 微服务(9)

目录 12. ElastisSearch 12.1 安装es 12.2 部署kibana 12.2.1 部署 12.2. 2 DevTools 12.3 索引库操作 12.3.1 mapping映射 12.3.2 创建索引库 12.3.3 查询索引库 12.3.4 删除索引库 12.3.5 修改索引库 12.4 文档操作 12.4.1 新增文档 12.4.2 查询文档 12.4.3 删…...

Matplotlib常见图汇总

Matplotlib是python的一个画图库&#xff0c;便于数据可视化。 安装命令 pip install matplotlib 常用命令&#xff1a; 绘制直线&#xff0c;连接两个点 import matplotlib.pyplot as plt plt.plot([0,5],[2,4]) plt.show() 运行结果如下&#xff1a; 多条线&#xff1a;…...

MTK联发科MT6897(天玑8300)5G智能移动处理器规格参数

天玑 8300 采用台积电第二代 4nm 制程&#xff0c;基于 Armv9 CPU 架构&#xff0c;八核 CPU 包含 4 个 Cortex-A715 性能核心和 4 个 Cortex-A510 能效核心&#xff0c;CPU 峰值性能较上一代提升 20%&#xff0c;功耗节省 30%。 此外&#xff0c;天玑 8300 搭载 6 核 GPU Mal…...

【AIoT-Robot】3d hand pose

手语是聋哑人士的主要沟通工具,它是利用手部和身体的动作来传达意义。虽然手语帮助它的使用者之间互相沟通,但聋哑人士与一般人的沟通却十分困难,这个沟通障碍是源于大部分人不懂得手语。 1. 手势&&手语 手势:手的姿势 ,通常称作手势。它指的是人在运用手臂时,所…...

使用 tc (Traffic Control)控制网络延时

设置网络延时 1500ms 800ms tc qdisc add dev eth0 root netem delay 1500ms 800msping 测试 ping www.baidu.com取消设置网络延时 sudo tc qdisc del dev eth0 root...

android原生TabLayout之自定义指示器效果

“com.google.android.material.tabs.TabLayout” 这个玩意说起来大家都不陌生。结合viewPager或者单独使用。场景非常多。当然市面上的三方也数不胜数。但是毕竟是亲儿子。用起来终归是顺手一些。下面说一下TabLayout的具体用法细节&#xff1a; 首先&#xff0c;xml布局引入…...

最新 HUAWEI DevEco Studio 使用技巧

最新 HUAWEI DevEco Studio 使用技巧 HUAWEI DevEco Studio 作为我们 harmonyos 应用的开发工具&#xff0c;有必要好好打磨一下。 Chinese(Simplified) 中文汉化插件 GitToolBox 编辑器中显示git历史 保存时自动格式化 写了一堆代码&#xff0c;当保存时&#xff0c;自动帮…...

开源大模型与闭源大模型浅析

引言 技术发展背景 早期语言模型 预训练与微调的范式 开源与闭源模型的兴起 当前的技术前沿 未来发展趋势 开源大模型的特点与优势 技术共享与创新加速 成本效益 社区驱动的发展 透明度和可审计性 促进教育与人才培养 灵活性和自定义 闭源大模型的特点与优势 商…...

docker 命令 ps,inspect,top,logs详解

docker常用命令教程-4 docker ps docker ps 命令用于列出当前正在运行的容器。默认情况下&#xff0c;它只显示正在运行的容器&#xff0c;但你可以使用 -a 或 --all 选项来显示所有容器&#xff08;包括已停止的容器&#xff09;。 常用的选项和示例&#xff1a; -a 或 --…...

Windows 找不到文件‘shell:sendto‘。请确定文件名是否正确后,再试一次

执行“shell:sendto”命令的时候&#xff0c;报错&#xff1a;Windows 找不到文件’shell:sendto’。请确定文件名是否正确后&#xff0c;再试一次 解决办法&#xff1a; 在桌面新建一个记事本文件命名为fix.reg&#xff0c;注意后缀是reg&#xff0c;文件中填写以下内容&…...

【算法】模拟算法——外观数组(medium)

题解&#xff1a;模拟算法——外观数组(medium) 目录 1.题目2.题解3.参考代码4.总结 1.题目 题目链接&#xff1a;LINK 2.题解 首先应该理解题意&#xff1a; 就是开始给你一个字符串&#xff0c;然后你对其进行描述。 描述规则是&#xff1a;连续的数字为一组&#xff0c;…...

2024年会计、金融与工商管理国际会议(ICAFBA 2024)

2024年会计、金融与工商管理国际会议 2024 International Conference on Accounting, Finance, and Business Administration 【1】会议简介 2024年会计、金融与工商管理国际会议是一场集合了全球会计、金融与工商管理领域专家学者的学术盛会。此次会议旨在深入探讨会计、金融与…...

关于 spring boot 的 目录详解 和 配置文件 以及 日志

目录 配置文件 spring boot 的配置文件有两种格式&#xff0c;分别是 properties 和 yml&#xff08;yaml&#xff09;。这两种格式的配置文件是可以同时存在的&#xff0c;此时会以 properties 的文件为主&#xff0c;但一般都是使用同一种格式的。 格式 properties 语法格…...

深圳网站建设骏域网站建设/宁波网站推广制作

java问题 定义一个Point点类定义一个Point点类&#xff0c;成员变量有x,y,成员函数set()设置x,y的值&#xff0c;get()获取x,y的值&#xff0c;并定义一个点对象调用set()和get(),并定义一个点对象调用set()和get()构造方法重载&#xff0c;distance()表示2点间的距离。实例pub…...

视频网站可以做B2C模式吗/怎么推广公众号让人关注

题大意: 给你n 和r&#xff1b;r表示最大半径不能超过这个数 后面给定n个点的坐标&#xff0c;y 大于零&#xff0c; 输出如果不能全部覆盖输出 -1 一开始还以为只要有一个满足就输出-1 结果我错了 这是一道区间选点问题 #include<iostream>#include<cmath>#…...

专做写字楼出租的网站/北京搜索引擎优化seo

ViewPager中切换界面Fragment被销毁的问题分析 原文链接http://www.cnblogs.com/monodin/p/3866441.html1、使用场景 ViewPagerFragment实现界面切换&#xff0c;界面数量>32、Fragment生命周期以及与Activity生命周期对比 3、问题描述 按上图所说&#xff0c;只有当Fragmen…...

wordpress主题列表封面/西安seo教程

我正在尝试平均化熊猫的一组数据。csv文件中的数据。我有一个系列节目叫“轨道”。在前面的阶段中&#xff0c;我使用了dropna()方法来删除在读取csv文件时导入的一些空白行。在我使用的方法是平均5行以上的列。我不能使用滚动平均法&#xff0c;因为我希望使用当前值之前的两行…...

网站建设策划方案如何写/小程序seo推广技巧

问题&#xff1a;RadioButton中使用android:gravity"center"使其图片文字居中&#xff0c;在我的华为荣耀7手机上居中显示了&#xff0c;但在HUAWEI G606-T00却显示在右侧了。 解决&#xff1a;在RadioButton中设置属性 android:paddingLeft"0dp" 或者 and…...

wordpress登录 小工具/广东省广州市白云区

使用 JSP 设置 cookie 使用 JSP 设置 cookie 包含三个步骤&#xff1a; (1)创建一个 cookie 对象&#xff1a; 调用 cookie 的构造函数&#xff0c;使用一个 cookie 名称和值做参数&#xff0c;它们都是字符串。 Cookie cookie new Cookie("key","value"…...