(一二四)tableView的多组数据展示和手动排序

最近在写一个轻量级的网络游戏,遇到了技能优先顺序手动排序的需求,我就想到了iOS自带的tableView编辑功能,对其进行了初步探索,最后做出的效果如下图所示:

点击左边可以删除,拖住右边可以手动排序,要实现这个功能,分以下步骤。

①用plist存储这些数据,可以看到数据分两个职业,每个职业4个技能,因此建立如下的plist结构:

②因为每个职业除了技能还有名称这个属性,因此应该用职业模型保存一个职业的所有数据,再用一个数组保存所有职业模型,职业模型的定义如下:

#import <Foundation/Foundation.h>

@interface Vocation : NSObject

@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSMutableArray *skills;

+ (instancetype)vocationWithDict:(NSDictionary *)dict;

@end

需要注意的是这里没有利用系统实现KVC,因为如果采用系统自带的,在把plist中的NSArray传给NSMutableArray时,因为NSMutableArray没有初始化 ,所以就变成了不可变的数组,这样为后面的顺序调整带来了致命的问题,因此我们手动实现KVC,用NSArray初始化一个NSMutableArray。

#import "Vocation.h"

@implementation Vocation

+ (instancetype)vocationWithDict:(NSDictionary *)dict{

    Vocation *vc = [[Vocation alloc] init];
    vc.title = dict[@"title"];
    vc.skills = [NSMutableArray arrayWithArray:dict[@"skills"]];
    return vc;

}

@end

③使用一个TableViewController,并且实现下面的代码:

#import "TableViewController.h"
#import "Vocation.h"

@interface TableViewController ()

@property (nonatomic, strong) NSArray *vocations;

@end

@implementation TableViewController

- (void)viewDidAppear:(BOOL)animated{

    [super viewDidAppear:animated];
    self.editing = YES;

}

- (BOOL)prefersStatusBarHidden{

    return YES;

}

- (NSArray *)vocations{

    if (_vocations == nil) {

        NSString *path = [[NSBundle mainBundle] pathForResource:@"skillList.plist" ofType:nil];
        NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
        NSMutableArray *vocations = [NSMutableArray array];
        for (NSDictionary *dict in dictArray) {
            Vocation *vc = [Vocation vocationWithDict:dict];
            [vocations addObject:vc];
        }
        _vocations = vocations;

    }

    return _vocations;

}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return self.vocations.count;
}

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

    Vocation *vc = self.vocations[section];
    return vc.skills.count;

}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

    Vocation *vc = self.vocations[section];
    return vc.title;

}

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

    static NSString  *ID = @"vocation";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }

    // 在这里设置cell数据
    Vocation *vc = self.vocations[indexPath.section];
    cell.textLabel.text = vc.skills[indexPath.row];

    return cell;

}

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{

    if (sourceIndexPath.section != destinationIndexPath.section) {
        [self.tableView reloadData];
        return;
    }

    Vocation *vc = self.vocations[sourceIndexPath.section];
    [vc.skills exchangeObjectAtIndex:sourceIndexPath.row withObjectAtIndex:destinationIndexPath.row];

}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{

    if (editingStyle == UITableViewCellEditingStyleDelete) {
        Vocation *vc = self.vocations[indexPath.section];
        [vc.skills removeObjectAtIndex:indexPath.row];
    }

    [self.tableView reloadData];

}

- (IBAction)editClick:(id)sender {

    UIBarButtonItem *btn = sender;
    if ([btn.title isEqualToString:@"调整"]) {
        btn.title = @"确定";
        self.editing = YES;
    }else{
        btn.title = @"调整";
        self.editing = NO;
        [self.tableView reloadData];
    }

}

@end

在这其中,editClick:对应了NavigationBar上的按钮,用于切换编辑和非编辑状态。

通过tableViewController的editing方法控制是否进入编辑状态。

要实现拖动排序,需要实现下面的方法,否则不能拖动,在这个方法中可以获取到起始和终止位置。

需要注意的是移动只是单纯的视觉效果,实际的数据源变化需要自己调整,否则在重新加载数据后又会回到原来的顺序,可通过数组的exchangeObjectAtIndexPath::方法调整。

为了避免组间移动,这里进行了判断,发现非法移动直接重置数据。

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{

    if (sourceIndexPath.section != destinationIndexPath.section) {
        [self.tableView reloadData];
        return;
    }

    Vocation *vc = self.vocations[sourceIndexPath.section];
    [vc.skills exchangeObjectAtIndex:sourceIndexPath.row withObjectAtIndex:destinationIndexPath.row];

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-31 09:34:49

(一二四)tableView的多组数据展示和手动排序的相关文章

简单的TableView单组数据展示/多组数据展示

1 拖入TableView到UIView中,连线DataSource 2 3 1.实现数据源方法 4 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 5 { 6 return ; 7 } 8 9 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexP

IOS开发——UI进阶篇—UITableView,索引条,汽车数据展示案例

一.什么是UITableView 在iOS中,要实现展示列表数据,最常用的做法就是使用UITableViewUITableView继承自UIScrollView,因此支持垂直滚动,而且性能极佳 UITableView的两种样式UITableViewStylePlainUITableViewStyleGrouped 二.如何展示数据 UITableView需要一个数据源(dataSource)来显示数据 UITableView会向数据源查询一共有多少行数据以及每一行显示什么数据等 没有设置数据源的

iOS开发UI篇—无限轮播(新闻数据展示)

一.实现效果        二.实现步骤 1.前期准备 (1)导入数据转模型的第三方框架MJExtension (2)向项目中添加保存有“新闻”数据的plist文件 (3)导入用到的图片素材 2.步骤和代码 (1)新建一个数据模型 该模型的代码设计如下: YYnews.h文件 1 // 2 // YYnews.h 3 // 08-无限滚动(新闻数据展示) 4 // 5 6 #import <Foundation/Foundation.h> 7 8 @interface YYnews : NSO

数据可视化中数据展示效果,基于highcharts的图表数据展示

最近在公司里搞对外的大屏展示,效果需要比较酷炫. 因为只是单纯的数据展示+效果,而且时间比较紧(2天时间基于一个原先的3D地球模型,制作配套十来个页面),采用jquery+highcharts (效果1) (效果2) 上面就是效果图,直接上代码,文件引入这样的问题就不说了 1 render_chart: function (chartid, type) { 2 let chartOption = {}; 3 switch (type) { 4 case "areaspline" : 5

Exchange Server 2013就地电子数据展示

9.2 就地电子数据展示 如果您的组织遵循法定发现要求(与组织策略.合规性或诉讼相关),Microsoft Exchange Server 2013 和 ExchangeOnline 中的就地电子数据展示可以帮助您对邮箱内的相关内容执行发现搜索.Exchange 2013 和 Exchange Online 还提供联合搜索功能以及与 MicrosoftSharePoint 2013 和 Microsoft SharePoint Online 的集成.您可以使用 SharePoint 中的电子数据

jquery: json树组数据输出到表格Dom树的处理方法

项目背景 项目中需要把表格重排显示 处理方法 思路主要是用历遍Json数组把json数据一个个append到4个表格里,还要给每个单元格绑定个单击弹出自定义对话框,表格分了单双行,第一行最后还要改rowspan呵呵,程序还没优化运行正常先给客户展示先:) 1,表格数据->json数组 var keyArr = new Array(); var jsonArr = new Array(); $list.find("thead th").each(function () { keyA

无限轮播(新闻数据展示)

无限轮播(新闻数据展示) 一.实现效果        二.实现步骤 1.前期准备 (1)导入数据转模型的第三方框架MJExtension (2)向项目中添加保存有“新闻”数据的plist文件 (3)导入用到的图片素材 2.步骤和代码 (1)新建一个数据模型 该模型的代码设计如下: YYnews.h文件 5 6 #import <Foundation/Foundation.h> 7 8 @interface YYnews : NSObject 9 @property(nonatomic,copy

iOS 【Multithreading-多图下载数据展示案例(二级缓存)/模拟SDWebImage内部实现】

#import "ViewController.h" #import "WZYApp.h" @interface ViewController () // 数据模型数组 @property (nonatomic, strong) NSArray *apps; // 保存操作对象的字典 @property (nonatomic, strong) NSMutableDictionary *operations; // 内存缓存 @property (nonatomic,

易宝典——玩转O365中的EXO服务 之四十三 就地电子数据展示存在什么样的搜索限制和局限

企业发现管理员在操作电子数据展示和保留时,往往会遇到诸如"包括不可搜索的项目"等选项.这种不可搜索项目是由于Exchange Online不支持的文件类型或其它原因产生的.那么到底Exchange Online对其就地电子数据展示搜索存在哪些限制和局限性呢? 一.就地电子数据展示的搜索限制 就地电子数据显示的限制有助于维护Office 365服务的运行的状况和质量.一般作为Office 365的订阅者是无法修改这些限制,通过了解这些限制,可以在规划.运行电子数据展示搜索,以及排除故障时