繁体   English   中英

iOS表格视图以及来自NSDictionary的数据

[英]iOS table view with data from an NSDictionary

我是iOS编程的新手,我需要一些建议。 我想创建一个带有部分的表视图以了解其工作原理。 我有一些来自模型类user对象。 我使用字典在表格视图中填充数据。 表格视图位于我的故事板中的“视图控制器”中。 该代码有效,但是我不知道这是否是处理表中数据的好方法。 像我一样这样做是语义上的错误吗?

请看一下我的代码并给我一些建议。

我的用户对象( User.h ):

@interface User : NSObject

@property (nonatomic, strong) NSString *email;
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSString *city;

@end

虚拟函数,用于将用户填充到数组中(在助手类中):

- (NSMutableArray *) createUser
{
    NSMutableArray *userArray = [[NSMutableArray alloc] init];

    User *user1 = [[User alloc] init];
    user1.firstName = @"Donald";
    user1.lastName = @"Duck";
    user1.email = @"donald_duck@disney.com";
    user1.city = @"Entenhausen";

    User *user2 = [[User alloc] init];
    user2.firstName = @"Micky";
    user2.lastName = @"Maus";
    user2.email = @"micky@disney.com";
    user2.city = @"Entenhausen";

    User *user3 = [[User alloc] init];
    user3.firstName = @"Daisy";
    user3.lastName = @"Duck";
    user3.email = @"daisy_duck@disney.com";
    user3.city = @"Frankfurt";

    User *user4 = [[User alloc] init];
    user4.firstName = @"Goofy";
    user4.lastName = @"Goof";
    user4.email = @"goofy@disney.com";
    user4.city = @"Berlin";

    User *user5 = [[User alloc] init];
    user5.firstName = @"Some";
    user5.lastName = @"Body";
    user5.email = @"somebody@disney.com";
    user5.city = @"Somewhere";

    User *user6 = [[User alloc] init];
    user6.firstName = @"Dagobert";
    user6.lastName = @"Duck";
    user6.email = @"dagobert@disney.com";
    user6.city = @"Mainz";

    [userArray addObject:user1];
    [userArray addObject:user2];
    [userArray addObject:user3];
    [userArray addObject:user4];
    [userArray addObject:user5];
    [userArray addObject:user6];

    return userArray;

}

创建字典对象的函数(在帮助器类中):

- (NSMutableDictionary *) createDictionaryFromArray: (NSMutableArray *) allData
{
    NSArray *arrayKeys = [[NSArray alloc] initWithObjects:@"Entenhausen", @"Frankfurt", @"Berlin", @"Mainz", nil];

    NSMutableDictionary *collection = [[NSMutableDictionary alloc] init];

    for (int i=0; i < arrayKeys.count; i++) {
        NSString *key = [arrayKeys objectAtIndex:i];
        NSMutableArray *allValues = [[NSMutableArray alloc] init];

        for (User *usr in allData) {

            if([usr.city isEqualToString:key]) {
                [allValues addObject:usr];
            }
        }

        [collection setObject:allValues forKey:key];
    }

    return collection;
}

我的表视图控制器类( TableViewController.h ):

#import <UIKit/UIKit.h>
#import "HelperClass.h"

@interface TableViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> {
    HelperClass             *helper;
    NSMutableArray          *users;
    NSArray                 *allKeys;
    NSDictionary            *dictionaryUsers;
}

TableViewController.m

#import "TableViewController.h"

@implementation TableViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    helper = [[HelperClass alloc] init];
    users = [[NSMutableArray alloc] init];
    users = [helper createUser];

    dictionaryUsers = [[NSMutableDictionary alloc] init];
    dictionaryUsers = [helper createDictionaryFromArray:users];
    allKeys = [NSArray array];
    allKeys = [dictionaryUsers allKeys];


}


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{    // Return the number of sections.
    return [allKeys count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    NSMutableArray *arrayValuesUsers = [[NSMutableArray alloc] init];
    arrayValuesUsers = [dictionaryUsers objectForKey:[allKeys objectAtIndex:section]];
    return [arrayValuesUsers count];
}

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

    return [allKeys objectAtIndex:section];

}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];

    User *user = [[User alloc] init];

    NSMutableArray *usersInSection = [dictionaryUsers objectForKey:[allKeys objectAtIndex:indexPath.section]];
    user = [usersInSection objectAtIndex:indexPath.row];

    cell.textLabel.text = [NSString stringWithFormat:@"%@, %@", user.lastName, user.firstName];
    cell.detailTextLabel.text = user.email;

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSMutableArray *usersInSection = [dictionaryUsers objectForKey:[allKeys objectAtIndex:indexPath.section]];
    User *usr = [usersInSection objectAtIndex:indexPath.row];

    NSLog(@"user: %@, %@", usr.lastName, usr.firstName);
}



@end

首先要赞成使用HelperClass来实现常规功能。 仅在执行此操作时,至少使其成为一个单例,这样您就不必总是调用:

helper = [[HelperClass alloc] init];

或者,如果仅具有createUser之类的功能,则这些方法应为类方法。

在查看您的代码时,我想到了以下两个一般提示:

您的代码中分配过多。 例如,在TableViewController中,您可以执行以下操作:

users = [[NSMutableArray alloc] init];
users = [helper createUser];

因此,首先分配一个新数组,createUser函数要做的第一件事是在内存中分配另一个数组,然后将其返回。 您第一次分配的内存空间永远不会使用。

说到tableView,请不要使用字典。 始终坚持使用数组。 字典没有顺序,并且在遍历字典时,每次可能会得到不同的结果。 数组是有序的,objectOfIndex:i将始终返回相同的对象。

因此,我对您的代码进行了调整,使其具有一个动态的tableView,将用户按城市分类到各个部分中,并按字母顺序对其进行分类。 (我想这就是您想要实现的目标)。 新代码并非完全干净。 您可以尝试在各处使用NSArray而不是NSMutableArray来节省一些内存。

您的User.h未被更改。

这是新的HelperClass.h

//  HelperClass.h


#import <Foundation/Foundation.h>

@interface HelperClass : NSObject


+ (HelperClass *)sharedHelperClass;
+ (NSMutableArray *) createUser;
+ (NSMutableArray *) getAllCitiesFromUserArray: (NSMutableArray *)userArray;
+ (NSMutableArray *)getUsersOfUsersArray: (NSMutableArray *)userArray fromCity: (NSString *)city;

@end

还有HelperClass.m

 //  HelperClass.m


#import "HelperClass.h"
#import "User.h"

@implementation HelperClass


+ (HelperClass *)sharedHelperClass
{

    //This returns always the same object of HelperClass
    static dispatch_once_t pred;
    static HelperClass *_sharedHelperClass = nil;
    dispatch_once(&pred, ^{ _sharedHelperClass = [[self alloc] init]; });
    return _sharedHelperClass;
}


- (id)init{
    self = [super init];
    if (!self) {
        return nil;
    }
    return self;
}


+ (NSMutableArray *) createUser
{
    NSMutableArray *userArray = [[NSMutableArray alloc] init];

    User *user1 = [[User alloc] init];
    user1.firstName = @"Donald";
    user1.lastName = @"Duck";
    user1.email = @"donald_duck@disney.com";
    user1.city = @"Entenhausen";

    User *user2 = [[User alloc] init];
    user2.firstName = @"Micky";
    user2.lastName = @"Maus";
    user2.email = @"micky@disney.com";
    user2.city = @"Entenhausen";

    User *user3 = [[User alloc] init];
    user3.firstName = @"Daisy";
    user3.lastName = @"Duck";
    user3.email = @"daisy_duck@disney.com";
    user3.city = @"Frankfurt";

    User *user4 = [[User alloc] init];
    user4.firstName = @"Goofy";
    user4.lastName = @"Goof";
    user4.email = @"goofy@disney.com";
    user4.city = @"Berlin";

    User *user5 = [[User alloc] init];
    user5.firstName = @"Some";
    user5.lastName = @"Body";
    user5.email = @"somebody@disney.com";
    user5.city = @"Somewhere";

    User *user6 = [[User alloc] init];
    user6.firstName = @"Dagobert";
    user6.lastName = @"Duck";
    user6.email = @"dagobert@disney.com";
    user6.city = @"Mainz";

    [userArray addObject:user1];
    [userArray addObject:user2];
    [userArray addObject:user3];
    [userArray addObject:user4];
    [userArray addObject:user5];
    [userArray addObject:user6];

    return userArray;

}


+ (NSMutableArray *) getAllCitiesFromUserArray: (NSMutableArray *)userArray{

    NSMutableArray *cityArray = [[NSMutableArray alloc] init];

    for (User *user in userArray) {
        if (![cityArray containsObject: user.city]){
            [cityArray addObject:user.city];
        }
    }

    //Sort the city array alphabetically (localizedCaseInsensitiveCompare even regards Umlaute)
    [cityArray sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

    return cityArray;
}

+ (NSMutableArray *)getUsersOfUsersArray: (NSMutableArray *)userArray fromCity: (NSString *)city{


    NSMutableArray *usersOfCityArray = [[NSMutableArray alloc] init];


    for (User *user in userArray) {
        if ([user.city isEqualToString:city]){
            [usersOfCityArray addObject:user];
        }
    }


    //Sort the array of custom objects by key lastName 
    NSSortDescriptor *sortDescriptor =
    [NSSortDescriptor sortDescriptorWithKey:@"lastName"
                                  ascending:YES
                                   selector:@selector(localizedCaseInsensitiveCompare:)];
    usersOfCityArray = [[usersOfCityArray sortedArrayUsingDescriptors:@[sortDescriptor]]mutableCopy];
    return usersOfCityArray;

}


@end

新的TableViewController.h

//  TableViewController.h


#import <UIKit/UIKit.h>

@interface TableViewController : UITableViewController

@end

还有新的TableViewController.m

//  TableViewController.m


#import "TableViewController.h"
#import "HelperClass.h"
#import "User.h"

@interface TableViewController ()

@property (nonatomic,strong) NSMutableArray *users;
@property (nonatomic,strong) NSMutableArray *sectionHeaders;


@end

@implementation TableViewController

- (void)viewDidLoad
{
    [super viewDidLoad];


    //This gets the Array of Users from the HelperClass class method
    //You could access the HelperClass Singleton with [HelperClass sharedHelperClass], but this is not needed in this case.

    self.users = [HelperClass createUser];
    self.sectionHeaders = [HelperClass getAllCitiesFromUserArray:self.users];



}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return [self.sectionHeaders count];
}

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

    //Get the current section city
    NSString *city = [self.sectionHeaders objectAtIndex:section];
    NSMutableArray *sectionUsers =[HelperClass getUsersOfUsersArray:self.users fromCity:city];

    return sectionUsers.count;
}

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

    return [self.sectionHeaders objectAtIndex:section];

}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }


    //Get the current section city
    NSString *city = [self.sectionHeaders objectAtIndex:indexPath.section];
    //Get users for the current city
    NSMutableArray *sectionUsers =[HelperClass getUsersOfUsersArray:self.users fromCity:city];
    //Get the user for the current cell
    User *user = [sectionUsers objectAtIndex:indexPath.row];

    cell.textLabel.text = [NSString stringWithFormat:@"%@, %@", user.lastName, user.firstName];
    cell.detailTextLabel.text = user.email;

    return cell;
}



#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //Get the current section city
    NSString *city = [self.sectionHeaders objectAtIndex:indexPath.section];
    //Get users for the current city
    NSMutableArray *sectionUsers =[HelperClass getUsersOfUsersArray:self.users fromCity:city];
    //Get the user for the current cell
    User *user = [sectionUsers objectAtIndex:indexPath.row];

    NSLog(@"user: %@, %@", user.lastName, user.firstName);

}


@end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM