iOS:练习题中如何用技术去实现一个连线题
一、介绍
本人做的app涉及的是教育行业,所以关于练习题的开发肯定是家常便饭。例如,选择题、填空题、连线题、判断题等,每一种题型都需要技术去实现,没啥多大难度,这里呢,就给出实现连线题的核心代码吧。过了年后,好久没写笔记了,今天就简单开始吧~~~
二、思想
采用上下文在画图的方法,首先确定起点和终点的坐标,然后通过两点画一条直线。
三、代码
(1)常量定义
lianXianHeader.h
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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)显示连线
![](/assets/blank.gif)
![](/assets/blank.gif)
// // 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
iOS:练习题中如何用技术去实现一个连线题相关推荐
- iOS开发中如何用Swif重写cell的frame方法
设置cell的内边距的时候会用到重写setframe的方法,OC里边很简单,但是在Swift中稍微有点麻烦,我在写的时候内存陷入了死循环,现在总结下后来正确的写法,希望能帮到你,说白了其实很简单 ...
- 在Qt中如何用纯代码写一个本地视频播放器
一.首先用纯代码写本地视频播放器需要用到以下类 #include <QWidget> #include <QHBoxLayout> //水平布局 #include <QV ...
- LISP 圆孔标记_在AUTOCAD中如何用lisp语言新建一个标注样式
标注样式要先建立字体样式.62616964757a686964616fe78988e69d8331333337616533 如果箭头没有块的话,要建立块. ;;;主程序标注样式 (defun Text ...
- iOS开发中多线程的那些事
iOS开发深入之后还是要接触多线程和runloop的,写篇博客讲解.记录下iOS开发中的多线程技术. 线程.进程 什么是线程.进程 有的人说进程就像是人的脑袋,线程就是脑袋上的头发~~.其实这么比 ...
- 在MacOS和iOS系统中使用OpenCV
在MacOS和iOS系统中使用OpenCV 前言 OpenCV 是一个开源的跨平台计算机视觉库,实现了图像处理和计算机视觉方面的很多通用算法. 最近试着在 MacOS 和 iOS 上使用 OpenCV ...
- iOS 14中人工智能的进步
探索Core ML,Create ML,ML Compute,Vision,Natural Language和PencilKit框架中的最新功能. 阿努帕姆·楚(Anupam Chugh) 2020年 ...
- iOS编程中throttle那些事
不知道大家对throttle这个单词是否看着眼熟,还是说对这个计算机基础概念有很清晰的了解了.今天就来聊聊和throttle相关的一些技术场景. 定义 我经常有一种感觉,对于英语这门语言的语感,会影响 ...
- 大疆技术总监:如何用六年成为一个全能的机器人工程师
origin: http://www.elecfans.com/app/api/focus/index/id/438628?from=singlemessage&isappinstalled= ...
- 大疆技术总监:如何用六年成为一个全能的机器人工程师(转载)
智能机器人会成为未来世界的灾难吗?对机器人或人工智能的研究会帮助我们更好的了解人类自己吗?人工智能将会怎样影响我们的生活?诸如此类的问题及文章早已屡见不鲜.但机器人控制如何入门?如何成为一个合格的 ...
- iOS progressive Web App (PWA) 技术
随着 iOS 11.3 的发布,iOS + PWA 的时代终于来了!本文对 iOS 中 PWA 的能力进行了分析,并将其与 iOS 上的 Native App.Android 上的 PWA 进行了深度 ...
最新文章
- java方法的调用怎么跳出_JAVA 的一个方法调用另一个方法时,怎么把那个方法里的数据调用出来...
- Mpg123源代码详解
- 均方误差越大越好_超详细 | 如何写好计量经济学实证分析论文?
- SAP CRM fiori application delete if only one note header
- vim 常用快捷键总结
- jedis StreamEntryID参数解释
- 实例讲解如何利用jQuery设置图片居中放大或者缩小
- 从Windows复制文件到Linux显示乱码问题
- jQuery easyUI Pagination控件自定义div分页(不用datagrid)
- GridView实现CheckBox全选
- RDPWrap远程桌面的一次脱坑
- 深度学习——目前可用的3D人体数据集
- 直播线上实时翻译和流式字幕技术实践与应用
- u12无线网卡linux驱动装不上,腾达(U12)USB无线网卡Linux驱动安装笔记
- c++知识点汇总--数组
- VScode C/C++ 环境配置教程 (GCC)
- 嵌入式服务器appweb交叉编译指南
- 【2021年第三届全国高校计算机能力挑战赛】大数据应用赛
- Techwiz OLED:透明显示
- 征途2经典版服务器双线哪个稳定,征途,别毁了自己和曾经的经典