(一二四)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];}


转载于:https://www.cnblogs.com/aiwz/p/6154047.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/374610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ARC_xp_20160530

1、 申请内存的地方在哪里&#xff1f;忘了...(应该是用的 malloc) 2、 键盘上按下一个键&#xff0c;处理的函数为&#xff1a;(所在的模块 应该是“CEGUIIrrlichtRenderer.dll”) 003B465F CC INT3 003B4660 /$ 53 PUSH EBX 003B4661 |. 56 …

Hibernate映射集合性能问题

首先&#xff0c;这篇文章的灵感来自于Burt Beckwith在2011年1月27日于SpringOne 2GX上发表的有关高级GORM –性能&#xff0c;定制和监控的演讲 。 简而言之&#xff0c; Burt Beckwith讨论了使用映射集合和GORM中的Hibernate 2级缓存的潜在性能问题&#xff0c;以及避免此类性…

算法:1!+(1!+3!)+(1!+3!+5!) + ( 1! + 3! + 5! + 7! + 9!)+....+(1!+3!+5!+ ... + m!)...

-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{ //算法入口 [self func2:9]; } //计算阶乘 factor&#xff08;m&#xff09;&#xff1d; m&#xff01; -(int)factor:(int)m{ int factorNum0; if(m0|m1) return 1; e…

知道这 20 个正则表达式,能让你少写 1,000 行代码

CocoaChina05-13正则表达式&#xff0c;一个十分古老而又强大的文本处理工具&#xff0c;仅仅用一段非常简短的表达式语句&#xff0c;便能够快速实现一个非常复杂的业务逻辑。熟练地掌握正则表达式的话&#xff0c;能够使你的开发效率得到极大的提升。下面是技匠整理的&#x…

用Jackson进行Java JSON处理

JSON &#xff08;Javascript对象符号&#xff09;正成为一种非常流行的数据交换格式。 在使用诸如YUI&#xff0c;ExtJS&#xff0c;DOJO等Javascript框架开发Web应用程序时&#xff0c;我们可以使用XML或JSON在客户端和服务器之间交换数据。 通常&#xff0c;我们从服务器获得…

Android Togglebutton 默认背景被放大

1 . 最近在项目中自定义toggleButton 发现背景图放入后 &#xff0c;比美工给我的原图要大很大 2. 为什么&#xff1f; 3.比较ToggleButton 和TextView源码 发现, toggleButton 设置了minWidth 和minHeigh &#xff0c;导致我的背景小图被拉伸。 4.解决这种问题&#xff1a; 重…

MapReduce:简单介绍

MapReduce是Google流行的一种并行编程技术。 它用于处理大量数据。 仅通过将工作并行分配给多台机器&#xff0c;就可以在合理的时间内完成这种处理。 每台机器都处理一小部分数据。 MapReduce是一种编程模型&#xff0c;使开发人员可以专注于编写处理数据的代码&#xff0c;而…

python翻译词典实例

#!/usr/bin/python # -*- coding:utf-8 -*- #通过有道翻译来进行内容翻译 import urllib2 import urllib import json #---------翻译方法定义 start---------# def transfer( transferStr , lanSource auto ): data {type:lanSource,i:transferStr,doctype:json,xmlVersion:1…

元素分类--块级元素(特点:独占一行, 宽高边距可改)

什么是块级元素&#xff1f;在html中<div>、 <p>、<h1>、<form>、<ul> 和 <li>就是块级元素。设置display:block就是将元素显示为块级元素。如下代码就是将内联元素a转换为块状元素&#xff0c;从而使a元素具有块状元素特点。 a{display:b…

Java应用程序中的消息传递主体

消息传递是每个Java应用程序的关键方面&#xff0c;尤其是对于涉及企业应用程序集成&#xff08;EAI&#xff09;或关注点分离的应用程序&#xff0c;例如多层WEB应用程序。 消息传递可以分为两个主要类别&#xff0c;即同步和异步。 另一方面&#xff0c;使用同步消息传递时&…

站立会议05(第二次冲刺)

一、站立会议信息&#xff08;配站立会议照片&#xff09; 第五天我们继续开发&#xff0c;把注册验证信息完善一下&#xff0c;将开始网站公共主页的开发。 二、任务进度 第五天我们注册验证完成。 三、任务看板&#xff08;图&#xff09; 四、燃尽图&#xff08;图&#xff…

[SoapUI] DataSource, DataSourceLoop, DataSink

Script assertion in login: 转载于:https://www.cnblogs.com/MasterMonkInTemple/p/4748189.html

1154. 一年中的第几天

给你一个字符串 date &#xff0c;按 YYYY-MM-DD 格式表示一个 现行公元纪年法 日期。请你计算并返回该日期是当年的第几天。 通常情况下&#xff0c;我们认为 1 月 1 日是每年的第 1 天&#xff0c;1 月 2 日是每年的第 2 天&#xff0c;依此类推。每个月的天数与现行公元纪年…

将CAPTCHA添加到您的GWT应用程序

什么是验证码&#xff1f; 在一个充满恶意机器人的世界中&#xff0c;您该怎么做才能保护您宝贵的Web应用程序&#xff1f; 您真正应该做的基本事情之一就是向其中添加CAPTCHA功能。 如果您不熟悉&#xff08;听起来有些奇怪&#xff09;&#xff0c;则CAPTCHA是确保用户实际上…

SQL基础语句

数据库面试常见题 一、SQL语言包括数据定义语言、数据操作语言、数据控制语言和事务控制语言1&#xff1a;DDL(Data Definition Language)&#xff0c;是用于描述数据库中要存储的现实世界实体的语言。 CREATE TABLE - 创建新表 ALTER TABLE - 变更&#xff08;改变&#xff0…

YYModel Summary

YYModel Effect-> YYModel的作用Provide some data-model method—>提供一些数据模型的方法Convert json to any object, or convert any object to json.->对任何对象转换成JSON&#xff0c;和对任何JSON转换为对象Set object properties with a key-value dictionar…

iOS学习——ScrollView图片轮播和同类控件优先级问题

iOS学习——ScrollView的使用和同类控件优先级问题 1. 布置界面 ScrollView的使用非常简单&#xff0c;只有三步 1.1 添加一个scrollview 1.2 向scrollview添加内容 1.3 告诉scrollview中内容的实际大小 首先做第一步&#xff0c;布置界面。 拖拽一个scrollview就可以了 就…

Exchanger和无GC的Java

总览 Exchanger类在线程之间传递工作和回收使用的对象方面非常有效。 AFAIK&#xff0c;它也是最少使用的并发类之一。 但是&#xff0c;如果您不需要GC&#xff0c;则使用ArrayBlockingQueue进行日志记录会更简单。 交换器类 Exchanger类对于在两个线程之间来回传递数据很有…

构造函数的反射

1 import java.lang.reflect.Constructor;2 3 public class zzbds {4 public static void main(String[] args) {5 6 try{ 7 Class cStudent.class; //获得无参构造函数8 Constructor constructorc.getConstructor(new Class[]{…

字符串连接“+”int、char、string

String s1 "21" "8" "54";System.out.println(s1);String s2 "21" 8 "54";System.out.println(s2);String s3 "21" 8 "54";System.out.println(s3);21854 21854 21854