iOS:练习题中如何用技术去实现一个连线题

一、介绍

本人做的app涉及的是教育行业,所以关于练习题的开发肯定是家常便饭。例如,选择题、填空题、连线题、判断题等,每一种题型都需要技术去实现,没啥多大难度,这里呢,就给出实现连线题的核心代码吧。过了年后,好久没写笔记了,今天就简单开始吧~~~

 

二、思想

采用上下文在画图的方法,首先确定起点和终点的坐标,然后通过两点画一条直线。

 

三、代码

(1)常量定义

lianXianHeader.h

//
//  LianXianHeader.h
//  LianxianDemo
//
//  Created by 夏远全 on 2018/2/9.
//  Copyright © 2018年 beijing. All rights reserved.
//

#ifndef LianXianHeader_h
#define LianXianHeader_hstatic CGFloat const BWidth   = 60;  //按钮的宽度
static CGFloat const BHeight  = 40;  //按钮的高度
static CGFloat const margin   = 40;  //按钮与屏幕的左边距、右边距
static CGFloat const Lpadding = 20;  //左边按钮上下间距
static CGFloat const Rpadding = 40;  //右边按钮上下间距static NSString* const kBeginPositionNotification = @"kBeginPositionNotification";
static NSString* const kEndPositionNotification   = @"kEndPositionNotification";
static NSString* const kClearAllLineNotification  = @"kClearAllLineNotification";
static NSString* const kFreshDrawLineNotification = @"kFreshDrawLineNotification";#endif /* LianXianHeader_h */
View Code

 

(2)连线模型

lianXianModel.h

//
//  LianXianModel.h
//  LianxianDemo
//
//  Created by 夏远全 on 2018/2/8.
//  Copyright © 2018年 beijing. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>@interface LianXianModel : NSObject
@property (nonatomic, strong) NSArray  *questions;
@property (nonatomic, strong) NSArray  *options;
@property (nonatomic, strong) NSArray  *relationships;
@end
View Code

lianXianModel.m

//
//  LianXianModel.m
//  LianxianDemo
//
//  Created by 夏远全 on 2018/2/8.
//  Copyright © 2018年 beijing. All rights reserved.
//

#import "LianXianModel.h"@implementation LianXianModel@end
View Code

 

(3)绘制连线

lianXianDrawView.h

//
//  LianxianDrawView.h
//  Ubbsz
//
//  Created by 夏远全 on 2018/2/9.
//  Copyright © 2018年 beijing. All rights reserved.
//
//

#import <UIKit/UIKit.h>@interface LianxianDrawView : UIView@end
View Code

lianXianDrawView.m

//
//  LianxianDrawView.m
//  Ubbsz
//
//  Created by 夏远全 on 2018/2/9.
//  Copyright © 2018年 beijing. All rights reserved.
//
#import "LianxianDrawView.h"
#import "LianXianHeader.h"@interface LianxianDrawView()
{NSMutableArray *pointArray; //存储当前的一对坐标,起始点和终止点NSMutableArray *lineArray;  //存储全部的连线,每一条连线就是一对坐标NSString       *startPointString; //当前起点NSString       *endPointString;   //当前起点
    CGFloat        lineWidth;
}@end@implementation LianxianDrawView//对进行重写,以便在视图初始化的时候创建并设置自定义的Context
- (id)initWithFrame:(CGRect)frame
{if (self = [super initWithFrame:frame]) {[self setupDefaultValue];[self regesterNotification];}return self;
}//初始值
- (void)setupDefaultValue{pointArray=[[NSMutableArray alloc]init];lineArray=[[NSMutableArray alloc]init];lineWidth = 2.0f;self.backgroundColor = [UIColor colorWithRed:238/255.0 green:243/255.0  blue:248/255.0  alpha:1];
}//注册通知
- (void)regesterNotification{[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toucheBegin:) name:kBeginPositionNotification object:nil];[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toucheEnd:) name:kEndPositionNotification object:nil];[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clearLine:) name:kClearAllLineNotification object:nil];[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(freshNeedsDisplay:) name:kFreshDrawLineNotification object:nil];
}//对drawRect进行重写
- (void)drawRect:(CGRect)rect
{//获取当前上下文,CGContextRef context=UIGraphicsGetCurrentContext();CGContextBeginPath(context);CGContextSetLineWidth(context, lineWidth);//线条拐角样式,设置为平滑
    CGContextSetLineJoin(context,kCGLineJoinRound);//线条开始样式,设置为平滑
    CGContextSetLineCap(context, kCGLineCapRound);//查看lineArray数组里是否有线条,有就将之前画的重绘,没有只画当前线条if ([lineArray count] > 0) {for (int i=0; i < [lineArray count]; i++) {NSArray * array=[NSArray arrayWithArray:[lineArray objectAtIndex:i]];if ([array count] > 0 && [array count]%2 == 0) {CGContextBeginPath(context);CGPoint myStartPoint = CGPointFromString(array.firstObject);CGContextMoveToPoint(context, myStartPoint.x, myStartPoint.y);CGPoint myEndPoint = CGPointFromString(array.lastObject);CGContextAddLineToPoint(context, myEndPoint.x,myEndPoint.y);CGContextSetStrokeColorWithColor(context,[[UIColor grayColor] CGColor]);CGContextSetLineWidth(context, lineWidth);CGContextStrokePath(context);}}}
}//接收起点按钮点击通知事件
- (void)toucheBegin:(NSNotification *)notification{CGRect beginFrame = [notification.object CGRectValue];CGPoint startPoint = CGPointMake(CGRectGetMaxX(beginFrame), CGRectGetMidY(beginFrame));startPointString = NSStringFromCGPoint(startPoint);if (pointArray.count==0) {[pointArray addObject:startPointString];}else{[pointArray replaceObjectAtIndex:0 withObject:startPointString];}
}//接收终点按钮点击通知事件
- (void)toucheEnd:(NSNotification *)notification{CGRect endFrame = [notification.object CGRectValue];CGPoint endPoint = CGPointMake(CGRectGetMinX(endFrame), CGRectGetMidY(endFrame));endPointString = NSStringFromCGPoint(endPoint);if (pointArray.count==2) {[pointArray replaceObjectAtIndex:1 withObject:endPointString];}else{[pointArray addObject:endPointString];}[self clearSomeHistoryLineView];[self addLA];[self setNeedsDisplay];
}//接收清除按钮点击通知事件
- (void)clearLine:(NSNotification *)notification{[self clearAllLineView];
}//接收重新绘制通知事件
- (void)freshNeedsDisplay:(NSNotification *)notification{NSArray *relationslineArray = notification.object;lineArray = [NSMutableArray arrayWithArray:relationslineArray];[self setNeedsDisplay];
}//添加连线
-(void)addLA{NSArray *array = [NSArray arrayWithArray:pointArray];[lineArray addObject:array];[pointArray removeAllObjects];
}//清除所有的连线
- (void)clearAllLineView
{[pointArray removeAllObjects];[lineArray removeAllObjects];[self setNeedsDisplay];
}//移除历史交叉重复的连线
- (void)clearSomeHistoryLineView{NSMutableArray *arrayM = [NSMutableArray array];for (int i=0; i < [lineArray count]; i++) {NSArray *array = [NSArray arrayWithArray:[lineArray objectAtIndex:i]];if ([array count] > 0) {NSString *hisBePointString = array.firstObject;NSString *hisEnPointString = array.lastObject;if ([startPointString isEqualToString:hisBePointString] || [endPointString isEqualToString:hisEnPointString]) {[arrayM addObject:array];}}}[lineArray removeObjectsInArray:arrayM];
}//移除通知
-(void)dealloc{[[NSNotificationCenter defaultCenter] removeObserver:self];
}@end
View Code

 

(4)计算尺寸

LianXianFrameUitity.h

//
//  LianXianSizeUitity.h
//  LianxianDemo
//
//  Created by 夏远全 on 2018/2/9.
//  Copyright © 2018年 beijing. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "LianXianModel.h"@interface LianXianFrameUitity : NSObject+ (CGRect)calculateSizeWithModel:(LianXianModel *)lianxianModel;@end
View Code

LianXianFrameUitity.m 

//
//  LianXianSizeUitity.m
//  LianxianDemo
//
//  Created by 夏远全 on 2018/2/9.
//  Copyright © 2018年 beijing. All rights reserved.
//

#import "LianXianFrameUitity.h"
#import "LianXianHeader.h"@implementation LianXianFrameUitity+ (CGRect)calculateSizeWithModel:(LianXianModel *)lianxianModel{NSUInteger questionsCount = lianxianModel.questions.count;NSUInteger optionsCount = lianxianModel.options.count;CGFloat LHeight = questionsCount * (BHeight+Lpadding) + Lpadding;CGFloat RHeight = optionsCount * (BHeight+Rpadding) + Rpadding;CGFloat kWidth  = [UIScreen mainScreen].bounds.size.width; //默认宽度为屏幕的宽return CGRectMake(0, 0, kWidth, MAX(LHeight, RHeight));
}@end
View Code

 

(5)创建组件

LianXianComponentsView.h

//
//  LianXianComponentsView.h
//  LianxianDemo
//
//  Created by 夏远全 on 2018/2/6.
//  Copyright © 2018年 beijing. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "LianXianModel.h"@interface LianXianComponentsView : UIView
@property (nonatomic, strong) LianXianModel *lianxianModel;
@end
View Code

LianXianComponentsView.m

//
//  LianXianComponentsView.m
//  LianxianDemo
//
//  Created by 夏远全 on 2018/2/6.
//  Copyright © 2018年 beijing. All rights reserved.
//

#import "LianXianComponentsView.h"
#import "LianxianDrawView.h"
#import "LianXianHeader.h"@interface LianXianComponentsView() {NSMutableArray *_leftBtns;NSMutableArray *_rightBtns;UIButton       *currentLeftBtn;CGFloat        borderWith;
}@end@implementation LianXianComponentsView//对进行重写,以便在视图初始化的时候创建并设置自定义的Context
- (id)initWithFrame:(CGRect)frame
{if (self = [super initWithFrame:frame]) {[self setupDefalutValue];}return self;
}//设置默认值
- (void)setupDefalutValue{self.backgroundColor = [UIColor clearColor];borderWith = 2.5;[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(restStatus:) name:kClearAllLineNotification object:nil];
}//接收模型
-(void)setLianxianModel:(LianXianModel *)lianxianModel{_lianxianModel = lianxianModel;[self setupLianXianUnit];if (lianxianModel && lianxianModel.relationships.count>0) {[self showLianXianResult];}else{[self listClickLeftButton];}
}//绘制连线选项
- (void)setupLianXianUnit{_leftBtns  = [[NSMutableArray array] init];_rightBtns = [[NSMutableArray array] init];CGFloat kWidth   = self.frame.size.width;CGFloat kHeight  = self.frame.size.height;CGFloat LY = (kHeight-(BHeight+Lpadding)*(self.lianxianModel.questions.count-1) - BHeight)/2;CGFloat RY = (kHeight-(BHeight+Rpadding)*(self.lianxianModel.options.count-1) - BHeight)/2;for (NSInteger i =0; i < self.lianxianModel.questions.count; i++) {UIButton *btn = [self createButtonWithFrame:CGRectMake(margin, LY+(BHeight+Lpadding)*i, BWidth, BHeight) title:[NSString stringWithFormat:@"%@",self.lianxianModel.questions[i]] tag:i];[self addSubview:btn];[_leftBtns addObject:btn];}for (NSInteger i =0; i< self.lianxianModel.options.count; i++) {UIButton *btn = [self createButtonWithFrame:CGRectMake(kWidth-margin-BWidth, RY+(BHeight+Rpadding)*i, BWidth, BHeight) title:[NSString stringWithFormat:@"%@",self.lianxianModel.options[i]] tag:i];[self addSubview:btn];[_rightBtns addObject:btn];}
}-(UIButton *)createButtonWithFrame:(CGRect)frame title:(NSString *)title tag:(NSInteger)tag{UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];btn.frame = frame;btn.layer.cornerRadius = 5.0;btn.layer.borderColor = [UIColor lightGrayColor].CGColor;btn.layer.borderWidth = borderWith;btn.layer.masksToBounds = YES;btn.tag = tag;[btn setBackgroundImage:[self imageWithColor:[UIColor whiteColor]] forState:UIControlStateNormal];[btn setBackgroundImage:[self imageWithColor:[UIColor colorWithRed:138/255.0 green:193/255.0 blue:211/255.0 alpha:1]] forState:UIControlStateHighlighted];[btn setBackgroundImage:[self imageWithColor:[UIColor colorWithRed:138/255.0 green:193/255.0 blue:211/255.0 alpha:1]] forState:UIControlStateSelected];[btn addTarget:self action:@selector(tapBtn:) forControlEvents:UIControlEventTouchUpInside];[btn setTitle:title forState:UIControlStateNormal];[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];return btn;
}- (UIImage *)imageWithColor:(UIColor *)color
{CGFloat imageW = 20;CGFloat imageH = 20;UIGraphicsBeginImageContextWithOptions(CGSizeMake(imageW, imageH), NO, 0.0);[color set];UIRectFill(CGRectMake(0, 0, imageW, imageH));UIImage *image = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();return image;
}-(void)tapBtn:(UIButton *)btn{//判断左边按钮是否处于选择状态,只有首先左边处于此状态下,右边的按钮点击才能进行连线操作(当前仅支持单向连线)if ([_rightBtns containsObject:btn]) {BOOL isLeftBtnSelected = NO;for (UIButton *leftBtn in _leftBtns) {if (leftBtn.selected) {isLeftBtnSelected = YES;break;}}if (!isLeftBtnSelected) {return;}}if ([_leftBtns containsObject:btn]) {//设置连线起点currentLeftBtn.selected = NO;currentLeftBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;btn.selected = YES;currentLeftBtn = btn;currentLeftBtn.layer.borderColor = [UIColor colorWithRed:32/255.0 green:199/255.0 blue:251/255.0 alpha:1].CGColor;//设置终点按钮可以选中状态for (UIButton *rightBtn in _rightBtns) {rightBtn.layer.borderColor = [UIColor colorWithRed:32/255.0 green:199/255.0 blue:251/255.0 alpha:1].CGColor;}//发送起点通知[[NSNotificationCenter defaultCenter] postNotificationName:kBeginPositionNotification object:[NSValue valueWithCGRect:btn.frame]];}if ([_rightBtns containsObject:btn]) {for (UIButton *leftBtn in _leftBtns) {if (leftBtn.selected) {//发送终点通知[[NSNotificationCenter defaultCenter] postNotificationName:kEndPositionNotification object:[NSValue valueWithCGRect:btn.frame]];//自动设置起始选择按钮
                [self listClickLeftButton];break;}}}
}//自动设置起始选择按钮
- (void)listClickLeftButton{if (!currentLeftBtn) {[self tapBtn:_leftBtns[0]];return;}NSUInteger tag = currentLeftBtn.tag;if (tag < _leftBtns.count-1) {  //自动下移[self tapBtn:_leftBtns[tag+1]];}else{[self tapBtn:_leftBtns[0]]; //重新开始
    }
}//绘制默认已经连线的选项,此处仅仅做成绩预览使用,不能再编辑
- (void)showLianXianResult{for (UIButton *leftBtn in _leftBtns) {leftBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;leftBtn.selected = leftBtn.userInteractionEnabled = NO;}for (UIButton *rightBtn in _rightBtns) {rightBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;rightBtn.selected = rightBtn.userInteractionEnabled = NO;}if (self.lianxianModel.relationships.count == 0) {return;}NSMutableArray *relationslineArray = [NSMutableArray array];for (NSString *result in self.lianxianModel.relationships) {NSString *question = [[result componentsSeparatedByString:@"-"] firstObject];NSString *option   = [[result componentsSeparatedByString:@"-"] lastObject];NSMutableArray *pointArray = [NSMutableArray array];for (UIButton *leftBtn in _leftBtns) {if ([leftBtn.currentTitle isEqualToString:question]) {CGPoint startPoint = CGPointMake(CGRectGetMaxX(leftBtn.frame), CGRectGetMidY(leftBtn.frame));NSString *startPointString = NSStringFromCGPoint(startPoint);[pointArray addObject:startPointString];break;}}for (UIButton *rightBtn in _rightBtns) {if ([rightBtn.currentTitle isEqualToString:option]) {CGPoint endPoint = CGPointMake(CGRectGetMinX(rightBtn.frame), CGRectGetMidY(rightBtn.frame));NSString *endPointString = NSStringFromCGPoint(endPoint);[pointArray addObject:endPointString];break;}}[relationslineArray addObject:pointArray];}if (relationslineArray.count > 0) {[[NSNotificationCenter defaultCenter] postNotificationName:kFreshDrawLineNotification object:relationslineArray];}
}//重置初始状态
- (void)restStatus:(NSNotification *)notification{for (UIButton *leftBtn in _leftBtns) {leftBtn.selected = NO;leftBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;[self tapBtn:_leftBtns[0]]; //重新开始
    }
}@end
View Code

 

(6)连线容器

LianXianContainerView.h

//
//  LianXianContainerView.h
//  LianxianDemo
//
//  Created by 夏远全 on 2018/2/8.
//  Copyright © 2018年 beijing. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "LianXianComponentsView.h"
#import "LianxianDrawView.h"@interface LianXianContainerView : UIView
@property (nonatomic, strong) LianXianComponentsView *componentsView;
@property (nonatomic, strong) LianxianDrawView *lianXianView;
@end
View Code

LianXianContainerView.m

//
//  LianXianContainerView.m
//  LianxianDemo
//
//  Created by 夏远全 on 2018/2/8.
//  Copyright © 2018年 beijing. All rights reserved.
//

#import "LianXianContainerView.h"
#import "LianXianComponentsView.h"
#import "LianxianDrawView.h"
#import "LianXianModel.h"@implementation LianXianContainerView- (id)initWithFrame:(CGRect)frame
{if (self = [super initWithFrame:frame]) {[self setup];}return self;
}- (void)setup{self.lianXianView = [[LianxianDrawView alloc]initWithFrame:self.bounds];self.componentsView = [[LianXianComponentsView alloc] initWithFrame:self.bounds];[self addSubview:self.lianXianView];[self addSubview:self.componentsView];
}@end
View Code

 

(7)显示连线

//
//  ViewController.m
//  LianxianDemo
//
//  Created by tianjing on 15/3/31.
//  Copyright © 2015年 tianjing. All rights reserved.
//

#import "ViewController.h"#import "LianXianContainerView.h"
#import "LianXianFrameUitity.h"
#import "LianXianModel.h"
#import "LianXianHeader.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];UIButton *clearBtn = [[UIButton alloc] initWithFrame:CGRectMake(50, 50, 100, 40)];clearBtn.backgroundColor = [UIColor greenColor];[clearBtn setTitle:@"重置" forState:UIControlStateNormal];[clearBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];[clearBtn addTarget:self action:@selector(clear:) forControlEvents:UIControlEventTouchUpInside];//创建模型LianXianModel *lianxianModel = [[LianXianModel alloc] init];lianxianModel.questions = @[@"",@"",@""]; /// 左边选项lianxianModel.options = @[@"",@"",@""];   /// 右边选项//lianxianModel.relationships = @[@"天-世",@"好-夏",@"人-锋"]; /// 连线关系,如果不为空,就只显示,不能编辑//clearBtn.hidden = (lianxianModel.relationships.count>0);//连线视图CGRect frame = [LianXianFrameUitity calculateSizeWithModel:lianxianModel];LianXianContainerView *containerView = [[LianXianContainerView alloc] initWithFrame:frame];containerView.center = self.view.center;containerView.componentsView.lianxianModel = lianxianModel;[self.view addSubview:containerView];[self.view addSubview:clearBtn];
}- (void)clear:(UIButton *)sender{[[NSNotificationCenter defaultCenter] postNotificationName:kClearAllLineNotification object:nil];
}@end
View Code

 

四、效果

提示:

左边按钮每次只有一个处于可连状态,而且每一次连接完会循环自动下移。

右边所有按钮始终处于可连状态。

同一个按钮再一次连接新的连线后,之前旧的跟其相关的连线都会被取消。 

 

  

 

五、采坑

如果练习题的界面是放在cell中的,因为复用的问题,在发送起点和终点的通知时,要对通知做唯一标识处理。

如果不这么做,可能会出现的bug是:上一道做过的连线题的连线会出现在下一道还没有做过的连线题上。

 

转载于:https://www.cnblogs.com/XYQ-208910/p/8532379.html

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

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

相关文章

18 Context与组合的应用场景与使用问题

contextType 指定context类型为创建的上下文&#xff0c;此时不需要用Consumer组件包裹&#xff0c;使用this.context即可访问会向上找最近的上下文并取值最适合的场景&#xff1a;杂乱无章的组件都需要同一些数据&#xff1b;若单纯为了不层层传递属性&#xff0c;使用contex…

http --- 共享加密(对称加密)的几个概念

使用互联网进行数据传输时,可能会产生以下四个问题: 1. 窃听: A向B发送的消息,有可能在传输过程中被X窃听到 2. 假冒: A收到来自B的消息有可能是X冒充的 3. 篡改: A确实收到来自B的消息,但是该消息有可能被X篡改了 4. 事后否认:B确实收到了来自A的消息,但是A是恶意用户,当A像B…

213. House Robber II 首尾相同的偷窃问题

&#xff3b;抄题&#xff3d;&#xff1a; You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of…

原型链

<!DOCTYPE html><html><head lang"en"> <meta charset"UTF-8"> <title></title></head><body><script> /* 原型中的默认属性 原型链&#xff1a;当调用构造函数&#xff08;Fn()&a…

http --- 公开密钥加密(非对称加密)的几个概念

公开密钥加密: 公钥加密,私钥解密 公开密钥加密的处理流程: 1. A准备通过互联网向B发送数据 2. B生成公钥P和私钥S 3. B将P发送给A 4. A使用P进行加密,并将密文通过互联网发送给B 5. B使用S进行解密得到数据公钥加密的更具体的栗子: 1.B首先准备好公钥P和私钥S 2.B将公钥发布…

19、20 Context API

安装React Dev Tool Context对象.displayName 使用别名 不使用别名 React.createContext 创建指定的Context对象组件会找离自己最近的Provider&#xff0c;获取其value变量名都叫value的情况&#xff0c;就近取AContext变量名有所区分&#xff0c;两个value都可以获取可以…

01-spring配置详解

1 bean元素 <!--将User对象交给spring容器进行管理 --><!-- Bean元素:使用该元素描述需要spring容器管理的对象class属性:被管理对象的完整类名.name属性:给被管理的对象起个名字.获得对象时根据该名称获得对象. 可以重复.可以使用特殊字符.id属性: 与name属性一模一…

第八模块:算法设计模式、企业应用 第2章 企业应用工具学习

第八模块&#xff1a;算法&设计模式、企业应用 第2章 企业应用工具学习转载于:https://www.cnblogs.com/tqtl911/p/9131614.html

http --- 混合加密的具体过程

混合加密: 共享加密存在一个“共享密钥”无法安全告知服务端的问题.公开加密存在,加密、解密速度慢的问题.混合加密则同时使用了2种加密技术,具体过程如下: 1. B提前生成公钥P和私钥S,并将P发布到网上 2. A想(通过互联网)像B发送数据 3. A从互联网上获取B的公钥P,并使用P对共享…

Vite+Vue3页面空白、图标不显示问题解决

页面空白问题 由于项目部署在子文件夹下&#xff0c;因此需要配置vite.config.js const config {base: ./, }el-icon图标不显示、打包时mkdir无权限 在控制台Network看字体图标的请求&#xff0c;发现地址多了_assets&#xff0c;本以为需要重新配置publicDir&#xff0c;后…

在HTML打开已安装的App,未安装跳转到对应的下载链接

借鉴 HTML中判断手机是否安装某APP&#xff0c;跳转或下载该应用 function lookApp () {var ua navigator.userAgentvar isAndroid /(Android);?[\s/]([\d.])?/.test(ua)var isIpad /(iPad).*OS\s([\d_])/.test(ua)var isIpod /(iPod)(.*OS\s([\d_]))?/.test(ua)var is…

javascript --- 自定义数组的反序函数

想写一个自定义的_reverse函数,其作用是将传入的数组进行部分反序. 效果如下: 输入[1,2,3,4,5,6,7,8,9] 第一个将2~4个位置的数字反序 第二个将2~6个位置的数字反序. // js function _reverse(arr, s, e) {arr arr.join().slice(0,s) arr.join().slice(s,e).split().revers…

21 Fragment和短语法应用

React.Fragment jsx语法&#xff0c;相当于document.createDocumentFragment()创建文档碎片容器&#xff0c;优化渲染解决了没有根节点的问题<></>这种短语法也会声明React.Fragment但短语法不支持keyReact.Fragment只支持key属性&#xff0c;其余属性如事件等不支…

201521123004《软件工程》个人阅读作业1

task1Task2: 201521123004 林艺如 博客&#xff1a;https://www.cnblogs.com/dabaolyr/ 码云&#xff1a;https://gitee.com/dabao_lyr Task3&#xff1a;完成博客-阅读与思考 阅读参考材料&#xff0c;并回答下面几个问题&#xff1a; &#xff08;1&#xff09;回想一下你初入…

在sql当中为了让数据做缓存做with as的操作

今天看别人的代码&#xff0c;突然发现之前理解的sql的with as的用法有新的理解。 之前理解的with as只是想着做单表的union all 操作时才使用&#xff0c;今天发现在可以使用逗号做分割&#xff0c;做缓存不同的表数据。 下面的例子如下&#xff1a; WITH t1 AS (SELECT file_…

javascript --- 从数组中,找出比给定元素大一丁点的元素

目标如下: 从数组[1,3,2,4,5,6,7]中找到比第1个位置大一丁点的元素 function _findIndex(arr, j){let k -1;let key arr[j];for(let i j; i< arr.length; i) {if(arr[i] > key) {if( k ! -1){if(arr[i] < arr[k]) {k i;}} else {k i;}}}return k } let arr [1,…

22 React高阶组件

搭建服务端 yarn add express yarn add nodemon 在server目录下 npm init -y // 增加dev脚本"scripts": {"dev": "nodemon ./index.js"},引入 git HOC High Order Component 高阶组件&#xff0c;是组件的抽象HOC不是React提供的API&#xf…

PAT (Advanced Level) 1140~1143:1140模拟 1141模拟 1142暴力 1143 BST+LCA

1140 Look-and-say Sequence&#xff08;20 分&#xff09; 题意&#xff1a;观察序列D, D1, D111, D113, D11231, D112213111, ...&#xff0c;显然后一个串是对前一个串每一小段连续相同的字母及其个数的描述。例如&#xff0c;D112213111是对D11231的描述&#xff0c;原因是…

AngularJS:表达式

ylbtech-AngularJS&#xff1a;表达式1.返回顶部 1、AngularJS 表达式 AngularJS 使用 表达式 把数据绑定到 HTML。 AngularJS 表达式 AngularJS 表达式写在双大括号内&#xff1a;{{ expression }}。 AngularJS 表达式把数据绑定到 HTML&#xff0c;这与 ng-bind 指令有异曲同…

23 Refs的应用场景与选用思考

Refs含义 允许访问真实DOMReact数据流&#xff1a;通过props来实现父子组件的交互Refs允许强制修改子组件 // 1. 构造器离添加实例属性 this.ref React.createRef() // 2. 组件上绑定ref ref{this.ref} // 3. 使用&#xff1a;this.ref.currentinput class MyInput extends…