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

UI学习(二)

UI学习(二)

文章目录

  • UI学习(二)
    • 布局子视图
      • 手动布局
      • 自动布局
    • 导航控制器
      • 导航控制器基础
      • 导航控制器的切换
      • 导航栏
      • 工具栏
    • 分栏控制器
    • 分栏控制器协议部分的内容
    • UITableView
      • 基础部分
      • 相关的协议函数
      • 高级协议与单元格
    • 多界面传值

布局子视图

手动布局

这里我要实现的目的是当我们想让父视图变化的时候使子视图也随着进行相应的变化的时候,我们就可以采用这两种方法。

#import <UIKit/UIKit.h>
@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];SuperView* sView = [[SuperView alloc] init];//创建一个子视图sView.frame = CGRectMake(20, 20, 100, 200);[sView creatSubView];sView.backgroundColor = [UIColor blueColor];[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;// Do any additional setup after loading the view.
}
-(void) pressLarge {SuperView* sView = (SuperView*)[self.view viewWithTag:101];[UIView animateWithDuration: 1.0 animations:^{sView.frame = CGRectMake(20, 20, 300, 480);}];
}
-(void) pressSmall {SuperView* sView = (SuperView*)[self.view viewWithTag:101];//通过tag获取到图片的值[UIView animateWithDuration: 1.0 animations:^{sView.frame = CGRectMake(20, 20, 180, 280);}];//现在使用一个新的方法,我们的animation执行写在里面的代码块。
}@endNS_ASSUME_NONNULL_BEGIN@interface SuperView : UIView {UIView* _view1;UIView* _view2;UIView* _view3;UIView* _view4;UIView* _view5;
}
-(void) creatSubView;
@endNS_ASSUME_NONNULL_END
@implementation SuperView
-(void) creatSubView {//设置四个视图_view1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];_view2 = [[UIView alloc] initWithFrame:CGRectMake(self.bounds.size.width - 40, 0, 40, 40)];_view3 = [[UIView alloc] initWithFrame:CGRectMake(self.bounds.size.width - 40, self.bounds.size.height - 40, 40, 40)];_view4 = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height - 40, 40, 40)];_view1.backgroundColor = [UIColor orangeColor];_view2.backgroundColor = [UIColor orangeColor];_view3.backgroundColor = [UIColor orangeColor];_view4.backgroundColor = [UIColor orangeColor];[self addSubview:_view1];[self addSubview:_view2];[self addSubview:_view3];[self addSubview:_view4];
}
//layoutSubviews是UIView类的一个方法,用于对子视图进行布局和调整。当视图的布局需要更新时,系统会自动调用layoutSubviews方法。
//当视图的frame属性发生变化时,例如视图的大小或位置发生改变。
//当视图的bounds属性发生变化时,例如视图的内容区域发生改变。
//当视图的transform属性发生变化时,例如视图进行缩放、旋转等变换操作。
-(void)layoutSubviews {[UIView animateWithDuration: 1.0 animations:^{self->_view1.frame = CGRectMake(0, 0, 40, 40);self->_view2.frame = CGRectMake(self.bounds.size.width - 40, 0, 40, 40);self->_view3.frame = CGRectMake(self.bounds.size.width - 40, self.bounds.size.height - 40, 40, 40);self->_view4.frame = CGRectMake(0, self.bounds.size.height - 40, 40, 40);}];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {// Drawing code
}
*/@end

实现的一个效果:

在这里插入图片描述

自动布局

我们也可以直接使用OC语言中提供的方法直接实现一个改变父视图的同时改变子视图。

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];_superView = [[UIView alloc] initWithFrame:CGRectMake(20, 29, 180, 280)];_superView.backgroundColor = [UIColor blueColor];_label1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];_label1.text = @"1";_label1.backgroundColor = [UIColor orangeColor];_label2 = [[UILabel alloc] initWithFrame:CGRectMake(180 - 40, 0, 40, 40)];_label2.text = @"2";_label2.backgroundColor = [UIColor orangeColor];_label3 = [[UILabel alloc] initWithFrame:CGRectMake(180 - 40, 280 - 40, 40, 40)];_label3.text = @"3";_label3.backgroundColor = [UIColor orangeColor];_label4 = [[UILabel alloc] initWithFrame:CGRectMake(0, 280 - 40, 40, 40)];_label4.text = @"4";_label4.backgroundColor = [UIColor orangeColor];// Do any additional setup after loading the view.[_superView addSubview:_label1];[_superView addSubview:_label2];[_superView addSubview:_label3];[_superView addSubview:_label4];[self.view addSubview: _superView];_viewCenter = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _superView.bounds.size.width, 40)];_viewCenter.center = CGPointMake(180 / 2, 280 / 2);_viewCenter.backgroundColor = [UIColor orangeColor];[_superView addSubview: _viewCenter];//设置自动布局的属性_viewCenter.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;//自动调整到Width,自动调整对于顶部的距离,自动调整对于底部的距离_label2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;_label3.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;_label4.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {static BOOL isLarge = NO;//设置一个变量来控制这一次是变大还是变小[UIView animateWithDuration: 1.0 animations:^ {if (isLarge == NO) {self->_superView.frame = CGRectMake(10, 10, 350, 580);isLarge = YES;} else {self->_superView.frame = CGRectMake(20, 20, 180, 280);isLarge = NO;}}];
}@end

实现的效果:

在这里插入图片描述

导航控制器

导航控制器(UINavigationController)是一种非常常用的容器视图控制器。它负责管理一个视图控制器的层次结构,提供导航栏、返回按钮等功能,让用户能够方便地在应用程序的各个页面之间进行导航,这里主要讲解一下有关导航控制器的使用。

导航控制器基础

#import "SceneDelegate.h"@interface SceneDelegate ()@end@implementation SceneDelegate- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {self.window.frame = [UIScreen mainScreen].bounds;VCRoot* vc = [[VCRoot alloc] init];//创建导航控制器,用于管理多个视图控制器的切换//采用层级的方式来管理多个视图的一个切换//创建的时候一定要有一个根视图控制器UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:vc];//设置一个根视图self.window.rootViewController = nav;[self.window makeKeyAndVisible];// 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).
}- (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

这里有关根视图部分的代码

#import "VCRoot.h"@interface VCRoot ()@end@implementation VCRoot- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor yellowColor];self.title = @"根视图";//设置为一个标题内容,如果没设置下面的就显示上面的,否则显示下面的,self.navigationItem.title = @"title";//p1按钮上的文字//p2按钮风格//p3事件持有者//p4按钮事件UIBarButtonItem* leftBtn = [[UIBarButtonItem alloc] initWithTitle:@"左侧" style:UIBarButtonItemStyleDone target:self action:@selector(pressleft)];//将导航元素项左侧按钮赋值self.navigationItem.leftBarButtonItem = leftBtn;//根据系统风格来创建按钮,系统风格的按钮内容或标题文字不能改变UIBarButtonItem *rightBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFastForward target: self action: @selector(pressRight)];self.navigationItem.rightBarButtonItem = rightBtn;UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 50, 40)];label.text = @"text";label.textAlignment = NSTextAlignmentCenter;label.textColor = [UIColor blueColor];//将任何类型的控件添加到导航按钮的方法UIBarButtonItem * item3 = [[UIBarButtonItem alloc] initWithCustomView:label];//创建一个按钮数组NSArray* arryBtn = [NSArray arrayWithObjects:item3, rightBtn, nil];//元素顺序决定如何呈现的//将右侧按钮数组赋值 self.navigationItem.rightBarButtonItems = arryBtn;// Do any additional setup after loading the view.
}/*
#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.
}
*/
- (void) pressleft {NSLog(@"left");
}
- (void) pressRight {NSLog(@"right");
}
@end

实现的效果:

在这里插入图片描述

导航控制器的切换

这里就涉及到我们从一个界面推出到另一个界面的问题,这里有一个视图控制器堆栈的事情,我们需要了解一下这个视图控制器堆栈。

  • 导航控制器维护一个视图控制器的栈结构,用于管理应用程序的导航层次。
  • 用户在应用程序中导航时,新的视图控制器会被压入栈中,返回时则从栈中弹出。

我们主要通过两种方法来操控这部分内容:

  • pushViewController:animated: 将一个视图控制器压入栈顶
  • popViewController:animated: 将一个栈顶的视图控制器退出出这个栈中
#import "VCRoot.h"
#import "VCSecond.h"
@interface VCRoot ()@end@implementation VCRoot- (void)viewDidLoad {[super viewDidLoad];//设置透明度,yes透明,no不透明self.navigationController.navigationBar.translucent = YES;self.title = @"title";self.navigationItem.title = @"根视图";self.view.backgroundColor = [UIColor blueColor];//设置导航栏的风格默认为Defaultself.navigationController.navigationBar.barStyle = UIBarStyleDefault;UIBarButtonItem* next = [[UIBarButtonItem alloc] initWithTitle:@"下一级别" style:UIBarButtonItemStylePlain target:self action:@selector(pressRight)];self.navigationItem.rightBarButtonItem = next;// Do any additional setup after loading the view.
}
#import "VCThird.h"@interface VCThird ()@end@implementation VCThird- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor redColor];UIBarButtonItem* btnleft = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(press)];self.navigationItem.rightBarButtonItem = btnleft;// Do any additional setup after loading the view.
}
-(void) press {//弹回根视图[self.navigationController popToRootViewControllerAnimated:YES];
}#import "VCSecond.h"
#import "VCThird.h"
@interface VCSecond ()@end@implementation VCSecond- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor greenColor];UIBarButtonItem* btnNext = [[UIBarButtonItem alloc] initWithTitle:@"next" style:UIBarButtonItemStylePlain target:self action:@selector(press)];self.navigationItem.rightBarButtonItem = btnNext;// Do any additional setup after loading the view.
}
- (void)press {VCThird* vc = [[VCThird alloc] init];[self.navigationController pushViewController:vc animated:YES];
}

这部分代码我们只是简单的设置了一下从一个视图控制器中推出另一个视图控制器:

实现的效果为:

在这里插入图片描述

导航栏

在新的iOS中我们对于导航栏要使用UINavigationBarAppearance* apperance来设置我们的一个导航栏的样式

- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor yellowColor];//在iOS13之后我们需要通过下面的方式来设置空间外观样式UINavigationBarAppearance* apperance = [[UINavigationBarAppearance alloc] init];//设置该对象的背景风格apperance.backgroundColor = [UIColor whiteColor];//背景颜色apperance.shadowImage = [[UIImage alloc] init];//阴影图像apperance.shadowColor = nil;//阴影颜色self.title = @"title";//设置按钮的颜色self.navigationController.navigationBar.tintColor = [UIColor purpleColor];//设置普通样式的导航栏self.navigationController.navigationBar.standardAppearance = apperance;//设置滚动样式的导航栏self.navigationController.navigationBar.scrollEdgeAppearance = apperance;//隐藏导航栏的两个方法//1、下面这一条的hidden是继承于UIView的self.navigationController.navigationBar.hidden = NO;//2、下面这一条的navigationBarHidden是一个属性self.navigationController.navigationBarHidden = NO;// Do any additional setup after loading the view.
}

工具栏

/显示工具栏对象//隐藏工具栏,默认为YES:即隐藏;NO:不隐藏self.navigationController.toolbarHidden = NO;//设置工具栏是否透明,默认为YES:半透明self.navigationController.toolbar.translucent = NO;UIBarButtonItem *btn1 = [[UIBarButtonItem alloc] initWithTitle: @"left" style: UIBarButtonItemStylePlain target: nil action: nil];UIBarButtonItem *btn2 = [[UIBarButtonItem alloc] initWithTitle: @"right" style: UIBarButtonItemStylePlain target: self action: @selector(press)];//设置一个自定义类型的button,使用图片创建UIButton *btnC = [UIButton buttonWithType: UIButtonTypeCustom];[btnC setImage: [UIImage imageNamed: @"1.jpg"] forState: UIControlStateNormal];btnC.frame = CGRectMake(0, 0, 60, 60);UIBarButtonItem *btn3 = [[UIBarButtonItem alloc] initWithCustomView: btnC];//设置一个占位按钮,放到数组中可以用来分隔开各按钮//设置宽度固定的占位按钮,注:此处方法名为UIBarButtonSystemItemFixedSpace(FixedSpace!!!!!)UIBarButtonItem *btnF1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFixedSpace target: nil action: nil];btnF1.width = 110;UIBarButtonItem *btnF2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace target: nil action: nil];NSArray *arrayBtn = [NSArray arrayWithObjects: btn1, btnF2, btn3, btnF2, btn2, nil];self.toolbarItems = arrayBtn;

实现的效果为:
在这里插入图片描述

分栏控制器

分栏控制器(UITabBarController)是另一种常用的容器视图控制器,分栏控制器可以包含多个子视图控制器,并通过底部的分栏菜单(UITabBar)进行切换。

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {self.window.frame = [UIScreen mainScreen].bounds;[self.window makeKeyAndVisible];VCFirst* vc1 = [[VCFirst alloc] init];VC_Second* vc2 = [[VC_Second alloc] init];VCThrid* vc3 = [[VCThrid alloc] init];vc1.view.backgroundColor = [UIColor orangeColor];vc2.view.backgroundColor = [UIColor blueColor];vc3.view.backgroundColor = [UIColor greenColor];vc1.title = @"first";vc2.title = @"second";vc3.title = @"third";UITabBarController* tbContoller = [[UITabBarController alloc] init];NSArray* arrayVC = @[vc1, vc2, vc3];//决定下面按钮的一个顺序tbContoller.viewControllers = arrayVC;tbContoller.tabBar.translucent = NO;//设置工具栏的透明度tbContoller.tabBar.backgroundColor = [UIColor whiteColor];//设置背景颜色tbContoller.tabBar.tintColor = [UIColor redColor];//设置一下按钮的self.window.rootViewController = tbContoller;tbContoller.selectedIndex = 2;//设置初始化时候显示的一个视图控制器NSLog(@"%d", tbContoller.selectedViewController == vc3);//将分栏控制器作为跟视图// 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).
}

实现的效果为:

在这里插入图片描述

分栏控制器协议部分的内容

这部分内容主要是有关**< UITabBarControllerDelegate>**这个协议实现的相关函数,主要是因为当我们的视图多于5个时候他增加一个按钮也就是more按钮,这个按钮然后有编辑呈现在页面上的五个视图的顺序。

  • (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers 在编辑前
  • (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed //编辑即将结束
  • -(void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed //编辑结束
  • -(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController //选中了那个视图控制器

这四个是协议里的相关函数

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {self.window.frame = [UIScreen mainScreen].bounds;[self.window makeKeyAndVisible];VCFirst *vcFirst = [[VCFirst alloc] init];VCSecond *vcSecond = [[VCSecond alloc] init];VCThird *vcThird = [[VCThird alloc] init];VCFourth *vcFourth = [[VCFourth alloc] init];VCFifth *vcFifth = [[VCFifth alloc] init];VCSixth *vcSixth = [[VCSixth alloc] init];// 设置视图控制器的背景颜色vcFirst.view.backgroundColor = [UIColor redColor];vcSecond.view.backgroundColor = [UIColor orangeColor];vcThird.view.backgroundColor = [UIColor yellowColor];vcFourth.view.backgroundColor = [UIColor greenColor];vcFifth.view.backgroundColor = [UIColor blueColor];vcSixth.view.backgroundColor = [UIColor purpleColor];vcFirst.title = @"第一页";vcSecond.title = @"第二页";vcThird.title = @"第三页";vcFourth.title = @"第四页";vcFifth.title = @"第五页";vcSixth.title = @"第六页";NSArray* ary = @[vcFirst, vcSecond, vcThird, vcFourth, vcFifth, vcSixth];UITabBarController* tabContoller = [[UITabBarController alloc] init];tabContoller.viewControllers = ary;tabContoller.tabBar.translucent = NO;tabContoller.tabBar.backgroundColor = [UIColor whiteColor];tabContoller.tabBar.tintColor = [UIColor redColor];self.window.rootViewController = tabContoller;//设置代理!tabContoller.delegate = self;// 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).
}
- (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 {if (changed == YES) {NSLog(@"顺序改变");}NSLog(@"结束编辑");
}
-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {NSLog(@"选中控制器对象");
}

实现的一个效果:

在这里插入图片描述

控制台打印结果:

在这里插入图片描述

UITableView

基础部分

这个UI组件是非常重要的一个组件,在实际开发中有非常重要的作用,这里只做简单介绍,后面笔者会单独总结一下这部分的内容

在创建UITableView这个组件的时候,他的步骤比较多。这里来介绍一下他的相关步骤:

  • 首先要继承两个协议<UITableViewDelegate, UITableViewDataSource>

  • 设置两个代理`_tableView.delegate = self; _tableView.dataSource = self;

  • 实现协议中必须实现的三个协议函数:1、-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section(获取每组元素的个数);2、numberOfSectionsInTableView(设置数据视图的组数);3、tableView: cellForRowAtIndexPath:(创建单元格对象函数)

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style: UITableViewStyleGrouped];//设置两个代理_tableView.delegate = self;_tableView.dataSource = self;[self.view addSubview:_tableView];// Do any additional setup after loading the view.
}
//获取每组元素的个数
//必须要实现的协议函数
//程序在显示数据视图会调用次函数
//p1:数据视图对象本身
//p2:那一组需要的行数
- (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

实现效果:

在这里插入图片描述

相关的协议函数

这里我们可以通过相应的协议函数来修改单元格的样式来满足我们的

  • -(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
  • -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
  • -(CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
  • -(NSString*) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
  • -(NSString*) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section

实现效果:

在这里插入图片描述

高级协议与单元格

这部分重要的协议函数是:

  • -(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
  • (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 选中单元格
  • (void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath 取消选中单元格
  • tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 编辑单元格
- (void)viewDidLoad {[super viewDidLoad];[self creatBtn];_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];_arryData = [[NSMutableArray alloc] init];for (int i = 1; i < 20; i++) {NSString* str = [NSString stringWithFormat:@"A %d", i];[_arryData addObject:str];}//当数据的数据源发生变化时候//跟新数据视图,重新加载数据[_tableView reloadData];}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return _arryData.count;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {return  1;
}
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {NSString* str = @"ID";UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:str];//尝试获取可复用的单元格//有足够多的单元格if (cell == nil) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:str];}cell.textLabel.text = [_arryData objectAtIndex:indexPath.row];cell.detailTextLabel.text = @"子标题";NSString* str1 = [NSString stringWithFormat:@"1.jpg"];UIImage* image = [UIImage imageNamed:str1];cell.imageView.image = image;return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {return 60;
}
-(void) creatBtn {_isEdit = NO;_btnEdit = [[UIBarButtonItem alloc] initWithTitle:@"编辑" style:UIBarButtonItemStylePlain target:self action:@selector(press1)];_btnDelete = [[UIBarButtonItem alloc] initWithTitle:@"删除" style:UIBarButtonItemStylePlain target:self action:@selector(press2)];_btnFinish = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStylePlain target:self action:@selector(press3)];self.navigationItem.rightBarButtonItem = _btnEdit;
}
-(void)press1 {_isEdit = YES;self.navigationItem.rightBarButtonItem = _btnFinish;[_tableView setEditing:YES];self.navigationItem.leftBarButtonItem = _btnDelete;
}
-(void)press2 {}
//显示编辑状态,当手指在单元格上移动时候
-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {[_arryData removeObjectAtIndex:indexPath.row];[tableView reloadData];NSLog(@"delete");
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {NSLog(@"选中单元格,%ld,%ld", indexPath.section,indexPath.row);
}
-(void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {NSLog(@"取消选中,%ld,%ld", indexPath.section, indexPath.row);
}
//单元格显示效果协议
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {return UITableViewCellEditingStyleDelete;//插入状态//默认为删除UITableViewCellEditingStyleDelete//默认为删除UITableViewCellEditingStyleNone//UITableViewCellEditingStyleDelete | UITableViewCellEditingStyleInsert;多选
}
-(void)press3 {_isEdit = YES;self.navigationItem.rightBarButtonItem = _btnEdit;[_tableView setEditing:NO];self.navigationItem.leftBarButtonItem = nil;
}
@end

实现的效果

在这里插入图片描述

多界面传值

这里主要是通过一个协议传值的方式去实现两个界面的传值

代码实现:

#import <UIKit/UIKit.h>
#import "ViewSecond.h"
NS_ASSUME_NONNULL_BEGIN@interface ViewFirst : UIViewController<VCSecondDelegate>
-(void) changeColor:(UIColor*) color;
@endNS_ASSUME_NONNULL_END
#import "ViewFirst.h"@interface ViewFirst ()@end@implementation ViewFirst- (void)viewDidLoad {[super viewDidLoad];self.title = @"根视图";self.view.backgroundColor = [UIColor orangeColor];self.navigationController.navigationBar.translucent = NO;UINavigationBarAppearance* app = [[UINavigationBarAppearance alloc] init];app.backgroundColor = [UIColor whiteColor];app.shadowImage = [[UIImage alloc] init];app.shadowColor = nil;self.navigationController.navigationBar.standardAppearance = app;self.navigationController.navigationBar.scrollEdgeAppearance = app;// Do any additional setup after loading the view.
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {ViewSecond* vc = [[ViewSecond alloc] init];//作为一个代理来传值vc.delegate = self;[self.navigationController pushViewController:vc animated:YES];
}
-(void)changeColor:(UIColor *)color {self.view.backgroundColor = color;
}
/*
#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

第二个界面:

NS_ASSUME_NONNULL_BEGIN
//定义代理协议,视图控制器二的协议
@protocol VCSecondDelegate <NSObject>
-(void) changeColor:(UIColor*) color;
@end@interface ViewSecond : UIViewController
//定义一个协议函数,改变背景颜色
@property (nonatomic, assign) NSInteger tag;
@property (nonatomic, weak) id<VCSecondDelegate> delegate;
@end#import "ViewSecond.h"@interface ViewSecond ()@end@implementation ViewSecond- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor redColor];UIBarButtonItem* btnChange = [[UIBarButtonItem alloc] initWithTitle:@"改变颜色" style:UIBarButtonItemStyleDone target:self action:@selector(pressbtn)];self.navigationItem.rightBarButtonItem = btnChange;// Do any additional setup after loading the view.
}
-(void) pressbtn {[_delegate changeColor:[UIColor purpleColor]];
}
/*
#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

实现效果:

在这里插入图片描述

相关文章:

UI学习(二)

UI学习&#xff08;二&#xff09; 文章目录 UI学习&#xff08;二&#xff09;布局子视图手动布局自动布局 导航控制器导航控制器基础导航控制器的切换导航栏工具栏 分栏控制器分栏控制器协议部分的内容UITableView基础部分相关的协议函数高级协议与单元格 多界面传值 布局子视…...

【嵌入式】波特率9600,发送8个字节需要多少时间,如何计算?

问题&#xff1a; 波特率9600&#xff0c;发送 01 03 00 00 00 04 44 09 (8字节) 需要多少时间&#xff0c;如何计算&#xff1f; 在计算发送数据的时间时&#xff0c;首先要考虑波特率以及每个字符的数据格式。对于波特率9600和标准的UART数据格式&#xff08;1个起始位&…...

jmeter -n -t 使用非GUI模式运行脚本说明

命令模式下执行jmx文件 jmeter -n -t fatie.jmx -l results\t4.jtl -e -o results\h1 表示以命令行模式运行当前目录下的脚本fatie.jmx,将结果存入当前目录下的results\t1.jtl,并且生成html格式的报告&#xff0c;写入文件夹results\h1。 说明&#xff1a;生成结果的文件夹r…...

网络流媒体协议——HLS协议

HTTP 实时流媒体&#xff08;HTTP Live Streaming&#xff0c;HLS&#xff09;协议是苹果公司提出的主要用于直播的流媒体协议。一个完整的基于HLS协议的流媒体直播系统由四部分组成&#xff0c;即音视频采集器、媒体服务器、媒体分发器和播放客户端。 媒体服务器 媒体服务器的…...

Linux服务器扩容及磁盘分区(LVM和非LVM)

Linux扩容及磁盘分区&#xff08;LVM和非LVM&#xff09; 本文主要介绍了阿里云服务器centos的扩容方法&#xff1a;非LVM分区扩容方法&#xff08;系统盘&#xff09;&#xff0c;以及磁盘改LVM并分区&#xff08;数据盘&#xff09;。主要是ext4文件系统及xfs磁盘scsi MBR分…...

支持向量机

支持向量机&#xff08;SVM&#xff09; 支持向量机&#xff08;Support Vector Machine, SVM&#xff09;是一种用于分类和回归任务的监督学习算法。SVM 的核心思想是找到一个最优的决策边界&#xff08;或称为超平面&#xff09;&#xff0c;以最大化不同类别之间的间隔。以…...

Kafka 架构

1 整体架构 1.1 Zookeeper Zookeeper 是一个分布式协调服务&#xff0c;用于管理 Kafka 的元数据。它负责维护 Kafka 集群的配置信息、Broker 列表和分区的 Leader 信息。 Zookeeper 确保了 Kafka 集群的高可用性和可靠性。 但 Zookeeper 已经成为 Kafka 性能瓶颈&#xff0c;…...

iOS 查看runtime源码的几种方法

目录 前言 查看runtime 源码方法 1.下载 Apple 官方提供的源代码 2.通过 GitHub 访问镜像 3.使用命令行工具查看 4.示例 前言 这篇博客主要介绍了查看iOS runtime源代码的方法。 查看runtime 源码方法 查看iOS runtime源码的方法包括以下几个步骤&#xff1a; 1.下载 A…...

底板外设倒灌到处理器分析

在嵌入式系统中&#xff0c;底板外设通常与处理器通过各种接口&#xff08;如UART、SPI、I2C、GPIO等&#xff09;进行连接。这些外设可能包括传感器、执行器、存储器、通信模块等。倒灌是指当外设向处理器提供的信号电平超出了处理器能够接受的范围&#xff0c;导致处理器无法…...

使用贝塞尔曲线实现一个iOS时间轴

UI效果 实现的思路 就是通过贝塞尔曲线画出时间轴的圆环的路径&#xff0c;然后 使用CAShaper来渲染UI&#xff0c;再通过 animation.beginTime [cilrclLayer convertTime:CACurrentMediaTime() fromLayer:nil] circleTimeOffset 来设置每个圆环的动画开始时间&#xff0c; …...

【深度学习】深度学习之巅:在 CentOS 7 上打造完美Python 3.10 与 PyTorch 2.3.0 环境

【深度学习】深度学习之巅&#xff1a;在 CentOS 7 上打造完美Python 3.10 与 PyTorch 2.3.0 环境 大家好 我是寸铁&#x1f44a; 总结了一篇【深度学习】深度学习之巅&#xff1a;在 CentOS 7 上打造完美Python 3.10 与 PyTorch 2.3.0 环境✨ 喜欢的小伙伴可以点点关注 &#…...

在docker容器中使用gdb调试python3.11的进程

gdb调试python进程的前提条件 安装python及python调试信息安装gdb工具安装python-gdb.py扩展 安装过程 我们使用docker来安装以上内容&#xff0c;Dockerfile文件内容如下&#xff1a; FROM docker.io/centos:7.4.1708# 安装依赖 RUN yum install -y -q epel-release &…...

堆排序要点和难点以及具体案例应用

堆排序(Heap Sort)是一种基于堆数据结构的排序算法。下面我将以分点表示和归纳的方式,结合相关数字和信息,详细描述堆排序的PTA(Programming and Testing Approach,编程与测试方法)。 1. 堆排序原理 堆排序是一种树形选择排序,利用了完全二叉树的性质,通过构建最大堆…...

pyspark中使用mysql jdbc报错java.lang.ClassNotFoundException: com.mysql.jdbc.Driver解决

报错信息&#xff1a; py4j.protocol.Py4JJavaError: An error occurred while calling o33.load. : java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 我的解决方法&#xff1a; 这个报错就是提示你找不到jar包&#xff0c;所以你需要去下载一个和你mysql版本匹配的j…...

对称加密系统解析

目录​​​​​​​ 1.概述 2. 对称密码类型 3. 对称加密优缺点 4. 对称加密算法 4.1 DES 4.2 3DES 4.3 AES ​​​​​​4.4 SM1 4.5 SM4 1.概述 对称加密&#xff0c;是指在加密和解密时使用同一秘钥的方式。秘钥的传送和保存的保护非常重要&#xff0c;务必不要让秘…...

初识 java 2

1. idea 的调试 1. 点击鼠标左键设置断点 2.运行到断点处 点击 或点击鼠标右键&#xff0c;再点击 使代码运行到断点处&#xff0c;得到 2. 输出到控制台 System.out.println(value);//输出指定的内容&#xff0c;并换行 value 要打印的内容System.out.print(value);…...

云端狂飙:Django项目部署与性能优化的极速之旅

Hello&#xff0c;我是阿佑&#xff0c;这次阿佑将手把手带你亲自踏上Django项目从单机到云端的全过程&#xff0c;以及如何通过Docker实现项目的无缝迁移和扩展。不仅详细介绍了Docker的基本概念和操作&#xff0c;还深入探讨Docker Compose、Swarm和Kubernetes等高级工具的使…...

GDPU JavaWeb 大结局篇(持续更新中)

GDPUJavaWeb程序设计复习&#xff0c;习题集&#xff0c;重点知识总结&#xff0c;一篇就够了。 实验复习 JavaWeb代码复习&#xff0c;在专栏也可查阅。 课后巩固习题 1 【单选题】下列说法正确的是( D ) A、在B/S结构中,结果应用软件发生了改变,就必须通知所有的客户端重新…...

Linux系统信息的查看

目录 前言一、系统环境二、查看系统IP地址信息2.1 ifconfig命令2.2 ip address命令 三、查看系统端口信息3.1 nmap命令3.2 netstat命令 四、查看系统进程信息4.1 ps命令4.2 kill命令 五、查看系统监控信息5.1 top命令5.2 df命令iostat命令5.3 sar命令 总结 前言 本篇文章介绍查…...

LE Audio音频广播新功能Auracast介绍

LE Audio音频广播新功能Auracast介绍 /*! \copyright Copyright (c) 2019-2022 Qualcomm Technologies International, Ltd. All Rights Reserved. Qualcomm Technologies International, Ltd. Confidential and Proprietary. \file audio_sources.h \defgroup audio_so…...

一文学习yolov5 实例分割:从训练到部署

一文学习yolov5 实例分割&#xff1a;从训练到部署 1.模型介绍1.1 YOLOv5结构1.2 YOLOv5 推理时间 2.构建数据集2.1 使用labelme标注数据集2.2 生成coco格式label2.3 coco格式转yolo格式 3.训练3.1 整理数据集3.2 修改配置文件3.3 执行代码进行训练 4.使用OpenCV进行c部署参考文…...

【设计模式】行为型设计模式之 策略模式学习实践

介绍 策略模式&#xff08;Strategy&#xff09;&#xff0c;就是⼀个问题有多种解决⽅案&#xff0c;选择其中的⼀种使⽤&#xff0c;这种情况下我们 使⽤策略模式来实现灵活地选择&#xff0c;也能够⽅便地增加新的解决⽅案。⽐如做数学题&#xff0c;⼀个问题的 解法可能有…...

lua中大数相乘的问题

math.maxinteger * 2 --> -2 原因&#xff1a;math.maxinteger的二进制 &#xff1a; 0111111111111111111111111111111111111111111111111111111111111111 往左移位&#xff0c;最右加一个0&#xff0c;是 1111111111111111111111111111111111111111111111111111111111111…...

第一个SpringBoot项目

目录 &#x1f4ad;1、新建New Project IDEA2023版本创建Sping项目只能勾选17和21&#xff0c;却无法使用Java8&#xff1f;&#x1f31f; 2、下载JDK 17&#x1f31f; &#x1f4ad;2、项目创建成功界面 1、目录 &#x1f31f; 2、pom文件&#x1f31f; &#x1f4ad;3、…...

Android 10.0 Launcher修改density禁止布局改变功能实现

1.前言 在10.0的系统rom定制化开发中,在关于Launcher3的定制化功能中,在有些功能需要要求改变系统原有的density屏幕密度, 这样就会造成Launcher3的布局变化,所以就不符合要求,接下来就来看下如何禁止改变density造成Launcher3布局功能 改变的实现 2.Launcher修改densit…...

CAN协议简介

协议简介 can协议是一种用于控制网络的通信协议。它是一种基于广播的多主机总线网络协议&#xff0c;常用于工业自动化和控制领域。can协议具有高可靠性、实时性强和抗干扰能力强的特点&#xff0c;被广泛应用于汽车、机械、航空等领域。 can协议采用了先进的冲突检测和错误检测…...

(二)JSX基础

什么是JSX 概念&#xff1a;JSX是JavaScript和XML&#xff08;HTML&#xff09;的缩写&#xff0c;表示在JS代码中编写HTML模版结构&#xff0c;它是React中编写UI模板的方式。 优势&#xff1a;1.HTML的声明式模版方法&#xff1b;2.JS的可编程能力 JSX的本质 JSX并不是标准…...

GB 38469-2019 船舶涂料中有害物质限量检测

船舶涂料是指涂于船舶各部位&#xff0c;能防止海水、海洋大气腐蚀和海生物附着及满足船舶特种要求的各种涂料的统称。 GB 38469-2019船舶涂料中有害物质限量检测项目&#xff1a; 测试指标 测试方法 挥发性有机化合物VOC GB 30981 甲苯 GB 24408 苯 GB 30981 甲醇 G…...

汇编:数组-寻址取数据

比例因子寻址&#xff1a; 比例因子寻址&#xff08;也称为比例缩放索引寻址或基址加变址加比例因子寻址&#xff09;是一种复杂的内存寻址方式&#xff0c;常用于数组和指针操作。它允许通过一个基址寄存器、一个变址寄存器和一个比例因子来计算内存地址。 语法 比例因子寻…...

ROS自带的OpenCV库和自己安装版本冲突问题现象及解决方法

文章目录 1. 问题现象1.1 编译过程警告1.2 程序运行报错 2. 分析问题原因3. 解决方法 1. 问题现象 1.1 编译过程警告 warning: lipopencv_improc.so.406, needed by /usr/local/lib/libopencv_xfeatures2d.so.4.6.0, may conflict with libopencv_imgproc.so.4.21.2 程序运行…...

做中药材生意哪个网站靠谱/重庆专业seo

提前把mongodb-linux-x86_64-rhel70-3.2.4.tgz放到和脚本相同目录下,然后把下复制到脚本里面&#xff0c;开始执行#!/usr/bin/python #-*- codinig: UTF-8 -*- from __future__ import print_function import os import shutil import tarfile import subprocessos.chdir(/root…...

一个小胖子从网站做任务的色情故事/互联网app推广具体怎么做

前面我写了三篇关于利用OBS推流服务在抖音上直播电脑游戏或者画面的教程&#xff0c;访问量挺大的&#xff0c;于是有好多小伙伴加我微信或者QQ说他自己按照我的教程设置的OBS推流直播抖音&#xff0c;但是会出现各种问题&#xff0c;比如黑屏的、卡顿的、延迟高的、无法连接服…...

吉林省建设厅安全证查询网站/免费的电脑优化软件

具体请看正文&#xff08;文章中部&#xff09; 随着AndroidStudio升级到3.0&#xff0c;自带的build插件也从2.x升级到3.x时代&#xff0c;有升级就会有调整&#xff0c;下面把遇到的语法改变列出&#xff1a; 针对依赖资源库&#xff1a; compile 》 implementationdepende…...

东莞网站建设 服饰/百度seo排名点击

一、伪元素的应用 1. 清除浮动 父元素中有子元素&#xff0c;并且父元素没有设置高度&#xff0c;子元素在父元素中浮动&#xff0c;结果必然是父元素的高度为 0&#xff0c;这也就导致了父元素高度塌陷&#xff0c;我们就需要清除浮动。 给浮动元素的容器添加一个 clearfix 的…...

企业中标信息查询网/seo推广是什么意思呢

搞了两三年AX&#xff0c;越来越困惑。 技术层面可以通过多读代码去解决大多数问题&#xff0c;毕竟AX里的那么多源代码是可以模仿的&#xff0c;加上AX本身是个很不错的开发平台&#xff0c;技术方面可能不需要太多时间就差不多可以应付了。 做AX最大的动力或许来自于实施AX确…...

用wordpress做网站页面显示404/so导航 抖音

基于韦东山的驱动修改的&#xff0c;由于内核版本不一样&#xff0c;包含到头文件有所变化&#xff0c;内核API函数也有所改变。 #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <l…...