(一二四)tableView的多組數據展現和手動排序

最近在寫一個輕量級的網絡遊戲,遇到了技能優先順序手動排序的需求,我就想到了iOS自帶的tableView編輯功能,對其進行了初步探索,最後作出的效果以下圖所示:數組

點擊左邊能夠刪除,拖住右邊能夠手動排序,要實現這個功能,分如下步驟。網絡

①用plist存儲這些數據,能夠看到數據分兩個職業,每一個職業4個技能,所以創建以下的plist結構:atom

②由於每一個職業除了技能還有名稱這個屬性,所以應該用職業模型保存一個職業的全部數據,再用一個數組保存全部職業模型,職業模型的定義以下:spa

#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方法控制是否進入編輯狀態。code

要實現拖動排序,須要實現下面的方法,不然不能拖動,在這個方法中能夠獲取到起始和終止位置。排序

須要注意的是移動只是單純的視覺效果,實際的數據源變化須要本身調整,不然在從新加載數據後又會回到原來的順序,可經過數組的exchangeObjectAtIndexPath::方法調整
遊戲

爲了不組間移動,這裏進行了判斷,發現非法移動直接重置數據。
rem

- (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];
    
}
相關文章
相關標籤/搜索