iOS ------ UIKit相关

news2024/11/24 22:41:52

UIView和CALayer

UIView

UIView表示屏幕上的一块矩形区域,它是基本上iOS中所有可视化控件的父类。UIView可以管理矩形区域里的内容,处理矩形区域的事件,包括子视图的管理以及动画的实现。

UIKit相关类的继承关系
在这里插入图片描述

UIView继承自UIResponder,所以UIView可以做事件响应,它也是所有视图(控件)直接或间接的父类

CALayer

CALayer继承于NSObject,我们称之为层,CALayer类的概念与UIView非常类似,可以包含图片、文本、背景色等。CALayer直接继承自NSObject,没有事件响应的功能。CALayer中包含API,可判断某点是否在图层范围内,但是没有响应链的存在

UIView和CALayer的关系

在每一个UIView实例当中,都有一个默认的支持图层layer,UIView负责创建并且管理这个图层。UIView因为里面有layer层,才具有显示的功能。UIView仅仅是对layer的一层封装,实现了CALayer的delegate,提供了处理事件交互的具体功能,还有动画底层方法的高级API。可以说,CALayer是UIView的内部实现细节。

UIView和CALayer的区别

1,UIView可以响应事件,CALayer不可以响应事件
2,一个 Layer 的 frame 是由它的 anchorPoint,position,bounds,和 transform 共同决定的,而一个 View 的 frame 只是简单的返回 Layer的 frame
3,UIView主要对显示的内容的管理而CALayer主要侧重显示内容的绘制
4,在做 iOS 动画的时候,修改非 RootLayer的属性(譬如位置、背景色等)会默认产生隐式动画,而修改UIView则不会。

UIView的CALayer类似于UIView的子view树状结构,也可以向它的layer上添加子layer,来完成某些特殊的表示

    UIView *firstView = [[UIView alloc] init];
    firstView.frame = CGRectMake(200, 200, 200, 200);
    firstView.backgroundColor = [UIColor redColor];
    [self.view addSubview:firstView];
    
    CALayer *layer = [[CALayer alloc] init];
    layer.backgroundColor = [[UIColor greenColor] CGColor];
    layer.position = CGPointMake(100,100);  //中心点
    layer.bounds = CGRectMake(100,100,80,80);
    [firstView.layer addSublayer:layer];

在这里插入图片描述

可以看出并没有在父视图添加新的图层,而是在view上改变了颜色,这和addSubView并不一样。可以看出layer是对View显示内容的绘制。

  • CAlayer视图结构类似于UIView的子View树形结构,可以在layer上添加子layer,类似于view添加view来实现一些特殊的表示。不同之处CALayer在添加的时候不会添加新视图,类似于修改原来的layer。
  • UIVIew的layer树形在系统内部,被系统维护三份copy
    • 第一份,逻辑树,代码可以在里面操作,例如通过代码更改layer的属性(比如frame\bounds)就在这一份进行操作
    • 第二份,动画树,这是一个中间层,系统在这一层更改属性,进行各种渲染操作
    • 第三份,显示树,这棵树的内容就是当前正被显示在屏幕上的内容

这三棵树的逻辑结构都是一样的,区别只是有各自的属性

UITableView

UITableView代理需要遵循的两个协议以及必须实现的方法

主要是通过2个协议:UITableViewDataSource和UITableViewDelegate

  • UITableView需要一个数据源代理(dataSource)来显示数据,UITableView会向数据源查询一共有多少行数据以及每一行显示生命数据。没有设置数据源的UITableView只是一个空壳。凡是遵循UITableViewDataSource协议的OC对象,都可以是UITableView的数据源
  • 我们也需要为UITableView设置代理对象(delegate),以便在UITableView触发某些事件时做出相应的处理。
  • 凡是遵循了UITableViewDelegate协议的OC对象,都可以是UITableView的代理对象,一般会让控制器充当充当UITableView的dataSource和delegate,我们可以手动实现协议中的某些方法来完成UITableView的实现。

@protocol UITableViewDataSource的方法

//返回组数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

//返回每组里的行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 

//cell的实现
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

// section头的title(例如,通讯录不同姓名标识)
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

// section尾段的title 
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section

// section索引的title集合(例如,通讯录索引,帮助快速找到姓名)
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
    
}

@protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>的方法

//点击cell事件
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
// 设置cell行高(因为参数是indexPath,所以可以设置不同section的行高,也能设置同一section不容row的行高)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
// section头部的height
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
// section尾部的height
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
// section头部的view
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
//  section尾部的view
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section

其中代理对象必须实现的方法是DataSource协议的方法

//每组的cell
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
//实现cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

几个主要的方法在TableView加载时的执行顺序

  • numberOfSectionsInTableView
  • numberOfRowsInSection
  • cellForRowAtIndexPath
  • heightForRowAtIndexPath

TbaleView的cell的复用

在滑动tableView时为了避免cell的重复的销毁创建而消耗性能就出现了cell的复用

简单来说:当创建了多个cell且屏幕显示不了所有的cell,系统会将已经创建不在显示的cell放入复用池中,当需要新建cell并且标识符与复用池中的标识符存在相同的情况,就会调用复用池中的cell,并且使用该cell的所有cell控件

cell的两种复用机制

自定义cell

cell复用会出现的问题

对于不同种类的自定义cell,有时复用会出现问题。如果自定义cell上的控件不同,会出现复用到控件不同的cell,这时就会出现界面的错乱。

解决方法:

  • 弃用重用机制 - 从indexpath每次获取新的cell
  • 对于不同种类的cell设置不同的标识符,通过不同的标识符去复用相应类型的cell
  • 在prepareForReuses中重置所有的subView的显示属性为nil。(当前已经被分配的cell如果被重用了,会调用cell的prepareForReuse通知cell)

在这里插入图片描述

在这里插入图片描述

tableViewCell的行高计算

动态计算-缓存高度

动态计算

实际开发中,使用最多的应该是动态计算cell高度。例如标题高度不固定,标签不固定,这样就需要更具model里的内容计算行高

在这里插入图片描述

使用的时候在tableView的代理设置

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
     WMSearchResultQAModel *model = self.dataArray[indexPath.row];
     return [WMSearchResultQAModel calutWholeCellHeightWithModel:model];
}

这样就可以达到每个cell根据内容展示不同高度的要求了。 这种方法很繁琐,但是也是最精确的,最可控的

缓存行高

当tableView滚动的时会不停的调用heightForAtIndexPath这个代理方法,当cell的高度需要自适应时,就意味着每次回调这个方法都要计算高度,而计算是非常消耗时间的,就会产生卡顿。

为了避免重复且无意义的计算cell高度,缓存高度就释放重要。

缓存高度机制

缓存高度需要一个容器来保存高度数值,可以是model ,一个可变数组,一个可变字典,以达到每当回调 heightForRowAtIndexPath 这个方法时,我们先去这个缓存里去取,如果有,就直接拿出来,如果没有,就计算高度,并且缓存起来。

以model为例

在model里声明个cellheight属性,用于保存Model对应的cell高度,然后在heightForRowAtIndexPath 方法中,如果当前model的cellHeight为0,说明这个cell没有缓存过高度,则计算Cell的高度,并把这个高度记录在model的cellHeight。如果当前model的cellHeight不为0,则直接使用。


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  WMSearchResultQAModel *model = self.dataArray[indexPath.row];
  if (model.cellHeight > 0) {
      // 有缓存的高度,取出缓存高度
      return model.cellHeight;
  }
  // 没有缓存时,计算高度并缓存起来
  CGFloat cellHeight; = [WMSearchResultQAModel calutWholeCellHeightWithModel:model];
  // 缓存给model
  model.cellHeight = cellHeight;
  return cellHeight;
}
手动计算高度的两个方法
  • sizeToFit
  • boundingRectWithSize

sizeToFit

    UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(10,100, 350, 0)];
    label.numberOfLines = 0;
    label.text =@"当前视图的边界和边界大小的变化123123213213213123123123123123213213123213213213123123213";
    NSLog(@"the label bounds : %@",NSStringFromCGRect(label.frame));
    [label sizeToFit];
    NSLog(@"%f",label.frame.size.height);
    [self.view addSubview:label];

我们不设置高度,设置label.numberOfLines = 0;和[label sizeToFit];可以实现label的最多展开,并可获得相应的高度。

注意事项

  • 调整大小:sizeToFit 调整视图的大小,以适应内容。
  • 不改变位置:sizeToFit 不会更改视图的位置。
  • 确保内容已设置:调用 sizeToFit 之前,应设置好视图的内容。

doundingRectWithSize

返回文本会在所占据的矩形空间

CGRect rect=[(NSString *)obj boundingRectWithSize:CGSizeMake(1000, FONTHEIGHT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16]} context:nil].size.width;

里面的参数如下:

  • obj 是指要计算显示的字符串
  • boundingRectWithSize 表示计算的宽高限制
  • 计算高度时,需要宽度固定:CGSizeMake(1000, CGFLOAT_MAX)
    这里的1000也可以用已经确定的控件的宽度替代self.label.width
    计算结果表示在宽度最多为1000高度不限时,显示完全字符串需要的高度
    计算宽度时,需要高度固定:CGSizeMake(CGFLOAT_MAX, 200)
    同理200也可以用已知高度替换:self.label.height
    计算结果表示在高度不超过200时,将给定的字符串现实完全需要的宽度
  • options是文本绘制的附加选项
  • NSStringDrawingUsesLineFragmentOrigin 是默认基线
  • attributes字典格式,限定字符串显示的样式,一般限制字体较多,比如:@{NSFontAttributeName:[UIFont systemFontOfSize:16]}
    context包括一些信息,例如如何调整字间距以及缩放。最终,该对象包含的信息将用于文本绘制。一般写nil。
    UILabel * labelSecond = [[UILabel alloc] init];
    labelSecond.numberOfLines = 0;
    labelSecond.text =@"当前视图的边界和边界大小的变化123123213213213123123123123123213213123213213213123123213";
    labelSecond.font = [UIFont systemFontOfSize:16];
	//用我们预设的width来算label应该显示的size   
    CGRect rectTest = [labelSecond.text boundingRectWithSize:CGSizeMake(350, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16]} context:nil];
    
    //从刚才算的size中取出heigth
    //加1是怕四舍五入完之后少了一点导致显示的label少了一行
    CGFloat titleHeight = ceilf(rectTest.size.height) + 1;
    
    //用算出来的结果显示label
    labelSecond.frame = CGRectMake(10,200, 350, titleHeight);
    //将label作为子视图添加到父视图
    [self.view addSubview:labelSecond];
自适应行高-缓存高度

在 iOS8 之后,系统结合autolayout提供了动态结算行高的方法 UITableViewAutomaticDimension,做好约束,我们都不用去实现 heightForRowAtIndexPath 这个代理方法了。

实现步骤
1,tableView设置

// 预设行高
self.tableView.estimatedRowHeight = xxx;
// 自动计算行高模式 
self.tableView.rowHeight = UITableViewAutomaticDimension;

2,在自定义cell,masonry布局

- (void)layoutSubviews {
    [super layoutSubviews];
    [self.headImgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.offset(kSpace15);
        make.size.mas_equalTo(CGSizeMake(50.f, 50.f));
        // 在自动计算行高模式下 要加上的 
        make.bottom.equalTo(self.contentView.mas_bottom).offset(-kSpace15);
    }];
    [self.nickNameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.headImgView.mas_right).offset(12.f);
        make.top.offset(17.f);
    }];
    [self.jobWorkLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.nickNameLabel.mas_right).offset(8.f);
        make.right.lessThanOrEqualTo(self.contentView.mas_right).offset(-kSpace15);
        make.top.offset(21.f);
    }];
    [self.hospitalLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.headImgView.mas_right).offset(12.f);
        make.top.equalTo(self.jobWorkLabel.mas_bottom).offset(6.f);
    }];
    [self.line mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.bottom.offset(0);
        make.height.mas_equalTo(0.5f);
    }];
}
  • 所有子控件都要依赖self.contentView作为约束父控件
  • 关键控件要做buttom约束,确定好控件的上下边界,根据控件的动态内容将cell纵向撑开。

3,最关键的一步: [cell layoutIfNeeded]

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    WMDoctorEvaluateDescribeInputCell *cell = [tableView dequeueReusableCellWithIdentifier:[WMDoctorEvaluateDescribeInputCell reuseIdentifier] forIndexPath:indexPath];
    kWeakSelf
    cell.describeInputBlock = ^(NSString * _Nonnull describeText) {
            weakSelf.inputDescribeText = describeText;
        };
    //关键的一步,解决不正常显示问题
    [cell layoutIfNeeded];
    return cell;
}

缓存高度机制

首先获取cell实际显示的高度

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{
  NSString *key = [NSString stringWithFormat:@"%ld",    (long)indexPath.row];
  [self.heightDict setObject:@(cell.height) forKey:key];
  NSLOG(@"第%@行的计算的最终高度是%f",key,cell.height);
}

didEndDisplayingCell当cell已经被正真的显示到屏幕上时会调用这个方法,此时的高度是cell的正真高度。根据indexPath.row作为key,将高度缓存进字典。

然后在 heightForRowAtIndexPath 方法里判断,如果字典里有值,则使用缓存高度,否则自动计算:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *key = [NSString stringWithFormat:@"%ld",indexPath.row];
    if (self.heightDict[key] != nil) {
       NSNumber *value = _heightDict[key];
       return value.floatValue;
    }
    return UITableViewAutomaticDimension;
}

ViewController的生命周期

ViewController相关函数以及执行顺序

当一个视图被创建,并且在屏幕上显示的时候

1.alloc 创建对象,分配空间
2. init; 初始化对象,初始化数据
3. loadview 在UIViewController对象的view被访问且为空的时候调用
4. viewDidLoad 控制器载入完成,可以进行自定义数据,以及动态创建其他控件
5. viewWillAppear 视图出现在屏幕之前,马上这个视图就会被展现在屏幕上了
6. viewWillLayoutSubviews 该方法在通知控制器将要布局 view 的子控件时调用
7. viewDidLayoutSubviews 该方法在通知控制器已经布局 view 的子控件时调用
8. viewDidAppear 视图已在屏幕上渲染完成

当一个视图被移除屏幕并且销毁的时候,代码执行的顺序

1,viewWillDisappear 视图将被从屏幕上移除之前执行
2,viewDidDisappear 视图已经被从屏幕上移除,用户看不见这个视图了
3,dealloc 视图被销毁,释放在init和viewDidLoad中创建的对象

离屏渲染

图片渲染和显示的流程

在这里插入图片描述

  • 在Application阶段,CPU会创建我们的视图,计算视图的一些数据,进行编解码,绘制纹理等操作然后交给GPU
  • GPU先通过顶点着色器去确定图像在硬件上的上的具体显示位置,然后通过片源着色器计算每个像素点的颜色值,最后通过光栅化找到像素点的位置,并把颜色显示上去。最终转化为一个个屏幕像素。
  • 然后把渲染后的数据放到帧缓存区(FrameBuffer),然后视图控制器就会读取数据交给显示器显示
掉帧

通过屏幕扫描的方式,会通过CRT电子枪从上到下逐行扫描,这个扫描的过程就是读取帧缓存区里的数据,当它扫描完的时候,它就会显示一帧的画面, 当显示完一帧画面后,CRT电子枪又回到原来的位置继续重新扫描显示下一帧。当一个垂直同步信号过来的时候,如果说CPUGPU还没有完成渲染的结果去做提交,也就是没有把数据放到FrameBuffer里面,这种情况,未过来提交过来这一帧的画面就会被丢弃,然后等待下一次垂直同步信号过来,再来显示新的画面,这个过程被称为掉帧

离屏渲染

当视图比较复杂的时候,GPU无法扫描视图的全部内容并把渲染数据反在FrameBuffer中,无法显示画面的全部内容,就需要开辟一块二外的内存缓存区,把剩下的渲染数据放入其中,再合并到FrameBuffer中,最后进行视图的显示。

导致离屏渲染的操作
  • 添加光栅化
  • 添加遮罩
  • 添加阴影
  • 抗锯齿
  • 设置背景颜色和圆角
  • 不透明

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1995296.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

封装加载(raect18+antd)

该组件主要是anted的组件中自带的loading属性&#xff0c; 1、封装loading组件 import React from react;function WithLoading(WrappedComponent: React.ComponentType<any>) {return (props: any) > {const [isLoading, setIsLoading] React.useState(true);Reac…

基于JAVA的高考智能排考场系统设计与实现,源码、部署+讲解

绪 论 随着教育规模的不断扩大和技术的进步&#xff0c;传统的考试管理方式面临着诸多挑战&#xff0c;如考试安排的复杂性、作弊现象的频发以及考试过程中的监督和管理等问题。因此&#xff0c;针对这些挑战&#xff0c;智能排考系统应运而生。 智能排考系统利用先进的技术…

接口基础知识5:详解request headers(一篇讲完常见字段)

课程大纲 一、请求头的定义 HTTP请求头部&#xff08;HTTP Request Headers&#xff09;&#xff1a;HTTP协议中的一部分&#xff0c;用于在客户端和服务器之间传递附加信息。这些头部字段提供了关于请求、客户端环境、或请求的上下文的信息。 请求头是键值对的形式&#xff…

day04-套餐管理

完成套餐管理模块所有业务功能&#xff0c;包括&#xff1a; 新增套餐套餐分页查询删除套餐修改套餐起售停售套餐 要求&#xff1a; 根据产品原型进行需求分析&#xff0c;分析出业务规则设计接口梳理表之间的关系&#xff08;分类表、菜品表、套餐表、口味表、套餐菜品关系…

element plus el-select修改后缀图标

使用 element plus 提供的api 默认为&#xff1a; 修改后为&#xff1a; 方法&#xff1a; <el-select v-model"value" placeholder"Select" size"large" style"width: 120px;":teleported"false" :suffix-icon"…

图数据库Neo4j的调研

图数据库Neo4j的调研 一、neo4j基础概述 概述 neo4j作为当下最热门的图数据库之一&#xff0c;他的底层实现是java语言&#xff0c;所以安装的时候必须有jre环境。并且neo4j是根据计算机中图论理论来实现的。 neo4j图数据库主要有以下组成元素&#xff1a;&#xff08;具体…

Kibana,Docker Remote Api,Kubernetes Api Server我未授权访问漏洞(附带修复方法)

一.Kibana Kibana是⼀个开源的分析与可视化平台&#xff0c;设计出来⽤于和Elasticsearch⼀起使⽤的。你可以⽤kibana搜索、查看存放在Elasticsearch中的数据。Kibana与Elasticsearch的交互⽅式是以各种不同的图表、表格、地图等直观地展示数据&#xff0c;从⽽达到⾼级的数据分…

【数据链路层】ARP协议

文章目录 以太网以太网帧对的格式 MAC地址对比MAC地址和IP地址 MTU和MSSARP协议ARP协议的工作原理ARP欺骗 以太网 ”以太网" 不是一种具体的网络, 而是一种技术标准; 既包含了数据链路层的内容, 也包含了一些物理层的内容. 例如: 规定了网络拓扑结构, 访问控制方式, 传输…

数学思维曼哈顿距离

前言&#xff1a;刚刚看到这个题的时候模拟了一下&#xff0c;感觉就是一个曼哈顿距离的问题&#xff0c;我们计算当前位置和中心的曼哈顿距离&#xff0c;然后比较x 或 y 到中心距离的大小&#xff0c;如果有一个小于等于&#xff0c;那么就是ok的 #define _CRT_SECURE_NO_WAR…

正点原子imx6ull-mini-Linux驱动之Linux IIO 驱动实验

工业场合里面也有大量的模拟量和数字量之间的转换&#xff0c;也就是我们常说的 ADC 和 DAC。 而且随着手机、物联网、工业物联网和可穿戴设备的爆发&#xff0c;传感器的需求只持续增强。比如手 机或者手环里面的加速度计、光传感器、陀螺仪、气压计、磁力计等&#xff0c;这些…

【数据结构】关于栈你必须知道的内部原理!!!

前言&#xff1a; &#x1f31f;&#x1f31f;Hello家人们&#xff0c;小编这期将带来关于栈的相关知识&#xff0c;以及代码的实现&#xff0c;希望能够帮到屏幕前的你。 &#x1f4da;️上期双链表博客在这里哟&#xff1a;http://t.csdnimg.cn/xgjK1&#xff1b; &#x1f4…

预测云计算的未来

云计算的未来是否依旧未知&#xff1f; 直到最近&#xff0c;云计算还是软件编程界之外很少有人熟悉的一个概念。如今&#xff0c;云计算已成为一切的基础&#xff0c;从点播电视服务和在线游戏门户网站到电子邮件和社交媒体&#xff0c;这四大现代世界的基石。云计算将继续存在…

Electron 使用Electron-build 进行打包

看完下面两篇就可以完成&#xff01; 基于vue3vite的web项目改为Electron桌面应用&#xff08;一&#xff09;_vue3转electron-CSDN博客 将web项目打包成electron桌面端教程&#xff08;二&#xff09;vue3vitets_vue3 打包桌面端-CSDN博客 打包报错 1. 首先确定依赖包 npm …

合金钢旋转花键:高强度与高耐磨性的选择

旋转花键‌是一种利用装在花键外筒内的滚珠&#xff0c;‌在精密研磨的滚动沟槽中作平滑滚动&#xff0c;‌同时传递力矩的直线运动系统。需要在振动冲击负荷作用过大、‌定位精度要求高的地方&#xff0c;‌以及需要高速运动性能的地方发挥重要作用。 旋转花键的性能跟材质有直…

龙迅#LT86102SXE适用于HDMI转两路HDMI应用方案,分辨率高达4K60HZ,提供技术支持!

1.功能 ⚫HDMI1.4和DVI 1.0规范兼容 ⚫支持3D视频格式和4Kx2K扩展分辨率格式高达3.4Gbps数据速率和4Kx2K 60Hz YCbCr 4&#xff1a;2&#xff1a;0格式 ⚫自适应均衡和失重&#xff0c;以补偿长电缆损耗 ⚫ODTs和校准 ⚫集成HDCP中继器引擎符合HDCP 1.4规范 ⚫完全硬件控制或可…

CSS文本两端对齐

背景 如果我们要写了列表或表单类的样式&#xff0c;名称长短不一&#xff0c;但是想要两端对齐&#xff0c;如下面这样的&#xff1a; 你是怎么写的&#xff1f; 是这样的吗&#xff0c;在HTML里调整加空格&#xff1a; <ul><li>用户名</li><li>账 …

探索算法系列 - 前缀和算法

目录 一维前缀和&#xff08;原题链接&#xff09; 二维前缀和&#xff08;原题链接&#xff09; 寻找数组的中心下标&#xff08;原题链接&#xff09; 除自身以外数组的乘积&#xff08;原题链接&#xff09; 和为 K 的子数组&#xff08;原题链接&#xff09; 和可被 …

电脑开机后出现bootmgr is missing原因及解决方法

最近有网友问我为什么我电脑开机后出现bootmgr is missing&#xff0c;这个提示意思是:意思是启动管理器丢失&#xff0c;说明bootmgr损坏或者丢失&#xff0c;系统无法读取到这个必要的启动信息导致无法启动。原因有很多&#xff0c;比如我们采用的是uefi引导&#xff0c;而第…

【数学建模】简单的优化模型-6 血管分支

背景&#xff1a;机体提供能量维持血液在血管中的流动&#xff0c;给血管壁以营养&#xff1b;克服血液流动的阻力&#xff0c;能量消耗与血管的几何形状有关。在长期进化中动物血管的几何形状已经在能量消耗最小原则下达到最优化。 问题&#xff1a;在能量消耗最小原则下&…

学习!胖东来秋季陈列欣赏

生鲜区 丰满、新鲜、有量感&#xff1b;色彩搭配更显艺术美&#xff01; 每个石榴专门被泡沫网套半包裹&#xff0c;避免果体受伤的同时&#xff0c;方便顾客挑选。 非季节性商品&#xff0c;以精而美的陈列形式呈现。 蔬菜区的商品分层立体陈列&#xff0c;顾客既拿既走&…