IOS项目练习 之 "找驾校"

这是最近的一个作业练习,因为一直不知道这个博客写什么内容,就拿这个作业来展示一下,顺便分享一下我在这个项目中使用到的一些小技巧;

项目的源代码可以在我的gitHub上获得,项目地址为:https://github.com/vfanx/ZhaoJiaXiao

项目展示:

技术分享  技术分享

技术分享  技术分享

技术分享  技术分享

功能介绍:

1.练习模块:能即时判断答案正误,并且给出问题解析

2.考试模块:能通过设置模块设置考题数目,并且给出考试结果

3.错题模块:能够保存考试模块中的错题并且给出答案解析,错误答案以及正确答案

4.考试成绩:统计每次考试的时间和成绩

5.设置模块:即时的设置考试模块的考题数目

 

技巧分析:

1. 无论是那个模块都是基于数据库的数据,虽然取自与不同的表,但是数据之间还是由一定的相似性,所以我为定义了一个抽象基类的model;

所有的viewcontroller无论是否有tableview都拥有一个数据源,而且数据源的数据读取方式相似,所以我设计了一个遵守UITableViewDataSource协议的类来为所有viewcontroller提供数据,并且对其进行一定的抽象和提供一定数量的接口来保证其复用性;这里贴出datasource的代码,

 

技术分享
 1 #import <UIKit/UIKit.h>
 2 
 3 @class DataModel;
 4 typedef void(^ConfigureCell)(id item,id cell);
 5 
 6 
 7 @protocol DataSource <NSObject>
 8 
 9 @optional
10 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
11 
12 @end
13 
14 
15 @interface DataSource : NSObject<UITableViewDataSource>
16 
17 
18 @property (nonatomic,assign) BOOL tableCanEdit;
19 @property (nonatomic,weak) id<DataSource> delegate;
20 @property (nonatomic,strong) NSArray *indexArry;
21 @property (nonatomic,strong) NSMutableDictionary *itemDict;
22 
23 - (instancetype)initWithTableName:(NSString *)tableName indexArry:(NSArray *)arry configureBlock:(ConfigureCell)block;
24 
25 - (DataModel *)findDataModelWithIndex:(NSInteger)index;
26 - (DataModel *)findDataModelWithIndexPath:(NSIndexPath *)indexPath;
27 
28 
29 @end
DataSource.h
技术分享
 1 #import "DataSource.h"
 2 #import "DataModel.h"
 3 #import "DataModelBuilder.h"
 4 
 5 
 6 @interface DataSource ()
 7 
 8 @property (nonatomic,copy) NSString *tableName;
 9 @property (nonatomic,copy) ConfigureCell configureBlock;
10 
11 @end
12 
13 @implementation DataSource
14 
15 - (instancetype)initWithTableName:(NSString *)tableName indexArry:(NSArray *)arry configureBlock:(ConfigureCell)block
16 {
17     self = [super init];
18     if (self) {
19         _tableName = tableName;
20         _indexArry = arry;
21         _itemDict = [[NSMutableDictionary alloc] init];
22         _configureBlock = [block copy];
23         _tableCanEdit = NO;
24     }
25     
26     return self;
27 }
28 - (DataModel *)findDataModelWithIndex:(NSInteger)index
29 {
30     NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
31     DataModel *model = [_itemDict objectForKey:indexPath];
32     if (model == nil) {
33         model = [DataModelBuilder buildDataModelWithTableName:_tableName serialNumber:_indexArry[index]];
34     }
35     return model;
36 }
37 
38 - (DataModel *)findDataModelWithIndexPath:(NSIndexPath *)indexPath
39 {
40     DataModel *model = [_itemDict objectForKey:indexPath];
41     if (model == nil) {
42         model = [DataModelBuilder buildDataModelWithTableName:_tableName serialNumber:_indexArry[indexPath.row]];
43     }
44     return model;
45 }
46 
47 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
48 {
49     return _indexArry.count;
50 }
51 
52 
53 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
54 {
55     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:_tableName forIndexPath:indexPath];
56     cell.textLabel.font = [UIFont systemFontOfSize:13];
57     cell.textLabel.numberOfLines = 0;
58     DataModel *model = [self findDataModelWithIndexPath:indexPath];
59     _configureBlock(model,cell);
60     return cell;
61 }
62 
63 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
64 {
65     return _tableCanEdit;
66 }
67 
68 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
69 {
70     if (editingStyle == UITableViewCellEditingStyleDelete) {
71         [_delegate tableView:tableView commitEditingStyle:editingStyle forRowAtIndexPath:indexPath];
72     }
73 }
74 
75 
76 @end
DataSource.m

2.一个神奇的自定义控件:

由于要修改考题的数量,没有适合的控件,然后我就对UISegmentedControl进行了一个不友好的封装,定义一个UISegmentedControl,设置三个分段

分别为"-","(当前数目)","+",然后通过左右两边老控制中间标题的数字,具体代码如下;

技术分享
 1 #import <UIKit/UIKit.h>
 2 
 3 @interface NumberSegmentedControl : UISegmentedControl
 4 
 5 @property (assign,nonatomic) NSInteger numValue;
 6 @property (assign,nonatomic) BOOL isCongfigure;
 7 
 8 - (void)configureNumberSegmented;
 9 
10 @end
NumberSegmentedControl.h
技术分享
 1 #import "NumberSegmentedControl.h"
 2 
 3 @implementation NumberSegmentedControl
 4 
 5 - (void)configureNumberSegmented
 6 {
 7     if (_isCongfigure) {
 8         return;
 9     }
10     _numValue = [[NSUserDefaults standardUserDefaults] integerForKey:@"numValue"];
11     NSString *temp = [NSString stringWithFormat:@"%ld",(long)_numValue];
12     NSInteger count = self.numberOfSegments;
13     for (NSInteger i = 0; i < count; i ++) {
14         [self removeSegmentAtIndex:0 animated:NO];
15     }
16     [self insertSegmentWithTitle:@"-" atIndex:0 animated:NO];
17     [self insertSegmentWithTitle:temp atIndex:1 animated:NO];
18     [self insertSegmentWithTitle:@"+" atIndex:2 animated:NO];
19     [self addTarget:self action:@selector(segmentValueChange:) forControlEvents:UIControlEventValueChanged];
20     self.tintColor = [UIColor grayColor];
21     _isCongfigure = YES;
22     self.selectedSegmentIndex = 1;
23 }
24 
25 - (void)segmentValueChange:(id)sender
26 {
27     if (self.selectedSegmentIndex == 1) {
28         return;
29     }
30     if (self.selectedSegmentIndex == 0 && _numValue > 0) {
31         self.numValue = _numValue-1;
32     }else if (self.selectedSegmentIndex == 2)
33     {
34         self.numValue = _numValue+1;
35     }
36     NSString *tittle = [NSString stringWithFormat:@"%ld",(long)_numValue];
37     [self setTitle:tittle forSegmentAtIndex:1];
38     self.selectedSegmentIndex = 1;
39 }
40 
41 - (void)setNumValue:(NSInteger)numValue
42 {
43     _numValue = numValue;
44     [[NSUserDefaults standardUserDefaults] setInteger:numValue forKey:@"numValue"];
45 }
46 
47 
48 @end
NumberSegmentedControl.m

写在最后的话:

第一次写技术博客不知道写什么,如果有幸这篇博文被看到的话,希望你可以顺便去下载github下载我的代码试试,应该比这篇博文写得好;

写代码时间不长,代码风格还在形成当中,逻辑上可能也有些问题,如有错误,欢迎指正,谢谢阅读.

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。