IOS菜鸟的所感所思(十三)——数据的图形化

目标:用coreData方式录入数据,并且用数据去生成相应的矩形图,实现数据的图形化。

步聚:1.需要把数据写入到SQLite文件中,当然你要创建一个勾选coreData的项目。
2.创建一个coreData的文件添加实体和属性。
3.创建一个DBManager的类,专门负责数据的操作。
4.在一个界面WriteDataToViewVC中负责向相应的SQLite文件中插入数据。
5.在第二个视图控制器PutDataIntoCellVC中,利用继承UITableViewCell的视图显示每个对象中的数据。
6.在第三个视图控制器中ShowDataOfGraphicVC,画出相应数据的矩形图。
实现:
1.项目的创建,勾选coreData选项。在程序中当你操作了数据后可以打印输出路径(只需要在appdelegate中NSLOG即可)
2.建议删除原来有得ViewController和视图,新建一个继承UITableViewController的类WriteDataToViewVC。
视图的样子:


说明:这是该项目的整体布局图。
3.创建coreData的文件,并生成相应的类

 
4.WriteDataToView.m文件中:
a. UITextField的关联

@interface WriteDataToViewVC ()<UITextFieldDelegate>

//会用到coreData

@property (nonatomic, strong) AppDelegate *myAppDelegate;

//添加分数

@property (weak, nonatomic) IBOutlet UITextField *addChineseScore;

@property (weak, nonatomic) IBOutlet UITextField *addMathScore;

@property (weak, nonatomic) IBOutlet UITextField *addEnglishScore;

@property (weak, nonatomic) IBOutlet UITextField *addPhysicalScore;

@property (weak, nonatomic) IBOutlet UITextField *addChemistryScore;

//将这些文本框放在一个数组中,方便后面的实现代理方法。

@property (nonatomic, strong) NSArray *textFieldArray;


@end


b.点击提交按钮时:

//初始化对象

- (AppDelegate *)myAppDelegate{

    if (!_myAppDelegate) {

        _myAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

    }

    return _myAppDelegate;

}

//当用户点击提交时会调用的方法,实现数据的插入。

- (IBAction)addDataToSqlite:(UIButton *)sender {

    //这里使用字典而不是数组,因为在数据的插入时需要进行区别

    NSDictionary *scoreDic = [[NSDictionary alloc] initWithObjectsAndKeys:_addChineseScore.text,@"ChineseScore",_addMathScore.text,@"MathScore",_addEnglishScore.text,@"EnglishScore",_addPhysicalScore.text,@"PhysicalScore",_addChemistryScore.text,@"ChemistryScore", nil];

    //调用SubjectNameAndScore类中的插入方法

    [SubjectNameAndScore insertData:@"SubjectScore" scoreData:scoreDic managedObjectContext:self.myAppDelegate.managedObjectContext];

}


说明:这里会用到coreData的插入操作,所以需要创建一个SubjectNameAndScore的类,继承NSObject。这里SubjectNameAndScore.h中导入头文件

#import "SubjectScore.h"


代码实现:


//公有的方法,实现数据的插入操作

+ (void)insertData:(NSString *)EntityName scoreData:(NSDictionary *)scoreData managedObjectContext:(NSManagedObjectContext *)context{

    SubjectScore *subjectScore = (SubjectScore *)[NSEntityDescription insertNewObjectForEntityForName:EntityName inManagedObjectContext:context];

    //相应的属性进行初始化,这里就体现了用字典的好处。

    [subjectScore setChinese:[scoreData objectForKey:@"ChineseScore"]];

    [subjectScore setMath:[scoreData objectForKey:@"MathScore"]];

    [subjectScore setEnglish:[scoreData objectForKey:@"EnglishScore"]];

    [subjectScore setPhysical:[scoreData objectForKey:@"PhysicalScore"]];

    [subjectScore setChemistry:[scoreData objectForKey:@"ChemistryScore"]];

    

    NSError *error;

    //插入操作后进行保存

    BOOL isSaveSuccess = [context save:&error];

    if (!isSaveSuccess) {

        NSLog(@"Error:%@",error);

    }else{

        NSLog(@"Save successful!");

    }

}


说明:当我们点击文本框输入信息时,键盘并不会隐藏,所以我们需要对文本框进行处理。那么在


- (void)viewDidLoad {

    [super viewDidLoad];

    //将文本框放在一个数组中,并分别进行代理的实现

    _textFieldArray = [[NSArray alloc] initWithObjects:_addChineseScore,_addMathScore,_addEnglishScore,_addPhysicalScore,_addChemistryScore, nil];

    [_textFieldArray enumerateObjectsUsingBlock:^(UITextField *obj, NSUInteger idx, BOOL *stop) {

        obj.delegate = self;

    }];

}

//运用数组的循环让每个文本框实现代理的方法,当我们点击键盘的return时就会隐藏键盘

- (BOOL)textFieldShouldReturn:(UITextField *)textField{

    [_textFieldArray enumerateObjectsUsingBlock:^(UITextField *obj, NSUInteger idx, BOOL *stop) {

        [obj resignFirstResponder];

    }];

    return YES;

}

说明:记得导入有文件。


#import "WriteDataToViewVC.h"

#import "SubjectNameAndScore.h"

#import "SubjectScore.h"

#import "AppDelegate.h"



效果:


5.现在我们已经有了数据了,接下来需要的就是把数据在界面视图中显示出来,第一种方式就是表格的方式显示。

a.我们首先得获取到数据源,所以在这里会用到SubjectNameAndScore类中的查询方法。

- (void)viewDidLoad {

    [super viewDidLoad];

    //表格中的cell的空白化

    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

    _myAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

}

- (void)viewDidAppear:(BOOL)animated{

    [super viewDidAppear:animated];

    //数据的获取,调用的方法中返回的是一个数组的类型

    _getDataArray = [SubjectNameAndScore getDataFromEntity:@"SubjectScore" managedObjectContext:self.myAppDelegate.managedObjectContext];

    //这里是检查数据是否获取到了

    [_getDataArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        NSLog(@"%@",obj);

    }];

    //重新加载数据,刷新界面

    [self.tableView reloadData];

}

b.接下来就是数据的显示,这里我们需要自定义UITableViewCell,所以需要创建一个继承UITableViewCell的类PutDataCell


c.cell的定义,PutDataCell.m中

- (void)setInfoCell:(SubjectScore *)subjectScore{


    _chineseScore.text = subjectScore.chinese;

    _mathScore.text = subjectScore.math;

    _englishScore.text = subjectScore.english;

    _physicalScore.text = subjectScore.physical;

    _chemistryScore.text = subjectScore.chemistry;

    

}

d.cell的数据的初始化,PutDataIntoCell.m中

#pragma mark - Table view data source


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {


    // Return the number of sections.

    return 1;

}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {


    // Return the number of rows in the section.

    return [_getDataArray count];

}

//cell的高度设置

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

    return 200;

}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    

    static NSString *cellIdentifier = @"scoreCell";

    //cell属性的定义

    PutDataCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil) {

        cell = [[[NSBundle mainBundle] loadNibNamed:@"PutDataCell" owner:self options:nil] lastObject];

        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

        

    }

    //从本地数组中获取数据,并且进行数据的初始化

    SubjectScore *subjectScore = _getDataArray[indexPath.row];

    [cell setInfoCell:subjectScore];

    return cell;

}

说明:在这里当我们点击一行cell时,就会弹出另外一个视图。该视图负责数据的图形化。
所以我们这里的cell是可编辑的,

//当我们点击cell时,会将该行cell的对象传入到sender

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    SubjectScore *subjectScore = _getDataArray[indexPath.row];

    [self performSegueWithIdentifier:@"showDataInGraphic" sender:subjectScore];

}


在另一个方法中我们会将sender中数据传入另一个视图控制器中。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    if ([segue.identifier isEqualToString:@"showDataInGraphic"]) {

        ShowDataOfGraphicVC *showDataInGraVC = segue.destinationViewController;

        showDataInGraVC.subjectScore = sender;

    }

}

说明:这里的showDataInGraphic是我们在进行视图布局的时候show的identifier。ShowDataOfGraphicVC中会有SubjectScore的对象,用于接收相应的数据对象。

效果:


6.最后一个视图的创建。 继承UIViewController的类ShowDataOfGraphicVC。这块的代码是我看了这个博客后,才知道自己可以完成图形动画。请参考:点击打开链接

@interface ShowDataOfGraphicVC ()


@property (nonatomic, strong) CALayer *myLayer;

@property (nonatomic, strong) NSArray *scoreData;


@end



- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    [self setMyLayerProperty];


    

}

说明:视图加载时会调用方法。

- (void)setMyLayerProperty{

    //初始化两个数组,用于储存相对应的学科和分数

    NSArray *graData = [[NSArray alloc] initWithObjects:_subjectScore.chinese,_subjectScore.math,_subjectScore.english,_subjectScore.physical,_subjectScore.chemistry, nil];

    NSArray *subjectsName = [[NSArray alloc] initWithObjects:@"语文",@"数学",@"英语",@"物理",@"化学", nil];

    int j = 0;

    //将手机界面宽度分为5份,进行画图

    for (int i = 10; i < self.view.frame.size.width; i += self.view.frame.size.width / 5) {

        CALayer *myLayer = [CALayer layer];

        //设置myLayer的属性

        myLayer.bounds = CGRectMake(0, 100, 0, 20);

        myLayer.backgroundColor = [UIColor blueColor].CGColor;

        //设置图形的位置

        myLayer.position = CGPointMake(10 + i, (self.view.bounds.size.height + 80) *0.618);

        //在图形下面写上相应的学科名字

        [self writeTheSubjectNameOfPonitX:10 + i pointY:(self.view.bounds.size.height + 80) *0.65 ofSubjectName:subjectsName[j]];

        //设置图形的锚点和矩形圆角

        myLayer.anchorPoint = CGPointMake(0, 1);

        myLayer.cornerRadius = 5;

        //添加图层

        [self.view.layer addSublayer:myLayer];

        self.myLayer = myLayer;

        

        NSLog(@"%d",j);

        //调用方法进行画图

        [self setGraDataOfx:10 + i andTheHeight:graData[j]];

        j++;

    }


}

//该方法创建一个UILabel,并且初始化信息

- (void)writeTheSubjectNameOfPonitX:(NSInteger)x pointY:(NSInteger)y ofSubjectName:(NSString *)subName{

    UILabel *subjectName = [[UILabel alloc] initWithFrame:CGRectMake( x, y, 25, 15)];

    subjectName.text = subName;

    subjectName.font = [UIFont systemFontOfSize:12];

    

    [self.view addSubview:subjectName];

}

//该方法是根据学科的数据画出相应的矩形高度

- (void)setGraDataOfx:(NSInteger)x andTheHeight:(NSString *)subjectData{

    //创建一个动画对象,并设置其属性

    CABasicAnimation *animation = [CABasicAnimation animation];

    animation.keyPath = @"bounds";

    animation.duration = 2.0;

    NSInteger subjectNum = [subjectData integerValue];

    //矩形的宽度20,高度是subjectNum

    animation.toValue = [NSValue valueWithCGRect:CGRectMake(100, 10, 20, subjectNum)];

    //调用方法,在相应的矩形框上添加UILabel,内容为该学科的分数。

    [self writeTheSubjectNameOfPonitX:x pointY:(self.view.bounds.size.height + 80) *0.618 - subjectNum * 1.3 ofSubjectName:subjectData];

    //设置动画执行完毕后不删除动画以及保存动画的最新状态

    animation.removedOnCompletion = NO;

    animation.fillMode = kCAFillModeForwards;

    

    //打印输出图形执行前的位置

    NSString *strPosition = NSStringFromCGPoint(self.myLayer.position);

    NSLog(@"执行前的位置:%@",strPosition);

    //在图层上添加动画

    [self.myLayer addAnimation:animation forKey:nil];

}

效果:



这样就基本上完成了相应的工作,但不足的是,本来打算让上面的那个视图横屏显示,其余的视图是竖屏,但查了很多资料,最终还是没有弄出来。
下载完整代码,请点击:点击打开链接

















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值