勤之时 - 表示层(四)

因为某些事情,耽搁了好久。总算可以开始把这个内容给补全了。希望接下来的一周能把这个应用的开发过程描述完毕,并把源码公开给大家。

这一节讲任务设置的部分,左上角的按钮对应的功能。

功能描述如下:

【任务一览】 View Controller

  • 中上部为应用图标/名称/描述
  • 下面为任务一览的列表,列表内容为任务配色,名称以及任务时间
  • 左上角为【关闭】按钮
  • 右上角为【添加】按钮,点击跳转到任务添加页面,可以添加一个新的任务。

【任务设置】View Controller

  • 以TableView的形式展示所有任务设置的内容。
  • 左上角为【返回】按钮,点击返回【任务一览】页面
  • 右上角为【删除】按钮,点击删除该任务。【删除】按钮设置为红色,点击后会弹出警告框提示用户,且最后一个任务不得删除。

【任务设置详细】View Controllers

  • 如图所示,点击【任务设置】的每个cell会跳转到各自的设置页面,如果子设置还有子设置,则以navigation的形式弹出,如果不是,则已Present的形式弹出。

【添加任务】View Controller

  • 【添加任务】和【任务设置】本质上一样的,只不过修改了左右上方的按钮,并以Present的形式弹出。

MVC设计考虑:
在编写这个功能的时候,我个人会觉得非常的杂乱,因为它们是一系列类似但又有细微差别的View Controller,每一个单独写吧,总会有那么一部分的代码会重复,抽取一些公共内容吧,也总有一些别扭。 所以,如果大家有好的意见建议,请指教。
最终的考虑

  • Controller:
    • Base:考虑大部分的View Controller要么以有Nav+TableView的组合,要么以Present+PickView的组合,所以我单独写了两个基类,来添加控件以及控件的布局,具体的控件的内容配置,由子类自己实现。
    • Controllers:每一个配置一个View Controller
  • Model:
    • 【任务一览】需要获得所有的任务信息,所以可以通过ILDTaskDataCenter来获得所有任务的taskIds
    • 然后再由taskId来获得每个任务的ILDTaskModel
    • 在任务配置过程中,所有传递的Model都是该任务的ILDTaskModel,且可被修改,仅在最后保存,或者退出【任务设置】时,根据修改后的内容写入本地任务配置中。
  • View:
    • 对于Cell也做了一些整合,因为整个配置中只有这四种Cell形式。

详细编码:
ILDTaskConfigurationViewController 有两种风格,即【任务设置】和【添加任务】风格

1
2
3
4
typedef NS_ENUM(NSInteger, TaskConfigurationType) {
TaskConfigurationTypeAdd,
TaskConfigurationTypeModify
};

因此,对导航左右按钮的操作会有所不同,同时考虑到此时需要保存任务设置的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (void)clickBackBarButtonItem:(id)sender {
if (self.configurationType == TaskConfigurationTypeModify) {
if ([self.taskConfiguration.name isEqualToString:@""]) {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"警告" message:@"任务名称不能为空,请设置" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"知道" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
//
}];

[alertVC addAction:cancelAction];

[self presentViewController:alertVC animated:YES completion:nil];
} else {
[[ILDTaskDataCenter sharedInstance] updateTask:self.taskId taskConfiguration:self.taskConfiguration];
[super clickBackBarButtonItem:sender];
}
} else {
[self dismissViewControllerAnimated:YES completion:nil];
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
- (void)clickRightButtonItem:(id)sender {
if (self.configurationType == TaskConfigurationTypeAdd) {
[[ILDTaskDataCenter sharedInstance] addTask:self.taskConfiguration];
[self dismissViewControllerAnimated:YES completion:nil];
} else {
if ( [[[ILDTaskDataCenter sharedInstance] taskIds] count] <= 1) {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"通知" message:@"这是最后一个任务,无法被删除" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
//
}];

[alertVC addAction:cancelAction];

[self presentViewController:alertVC animated:YES completion:nil];
} else {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"警告" message:@"该操作会删除当前任务以及所有的和任务相关的统计记录,确认删除吗?" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
[[ILDTaskDataCenter sharedInstance] removeTask:self.taskId];
[self.navigationController popViewControllerAnimated:YES];
}];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
//
}];

[alertVC addAction:cancelAction];
[alertVC addAction:okAction];

[self presentViewController:alertVC animated:YES completion:nil];
}
}
}