Reputation: 1490
I am a new iOS programming. I am creating a sample app which similar to contact
app. I wonder how that real application works. For example, Our tableview display names based on alphabet like name starts with A
will stays in A
section and B
will stays in B
section and so on. And when user input some names which not exist in section then, new section will be auto created. I wonder how can i achieve something like this.
This is how i created UITableView programmatically. Not using storyboard
private let cellId = "cellId"
private let array = ["Aname", "Bname", "Cname", "Dname"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
}
Here is how i custom display data
// Table View
extension ContactListController {
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let label = UILabel()
label.backgroundColor = .gray
label.text = "A"
return label
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
cell.textLabel?.text = array[indexPath.row]
return cell
}
}
For my desire output i would like to display name starts with A
should be in A
section and so on...
Thank for your explanation.
Upvotes: 2
Views: 148
Reputation: 285150
The easiest solution is the method Dictionary(grouping: by:)
Create an array for the sections (keys
), a dictionary for the names (people
) and make array
mutable
var keys = [String]()
var people = [String : [String]]()
private var array = ["Aname", "Bname", "Cname", "Dname"]
Add a method to group the data
func groupData()
{
people = Dictionary(grouping: array, by: {String($0.first!)})
keys = people.keys.sorted()
tableView.reloadData()
}
If you want to restrict the grouping to consider only capital letters write
people = Dictionary(grouping: array, by: {$0.range(of: "^[A-Z]", options: .regularExpression) != nil ? String($0.first!) : "Unknown"})
in viewDidLoad
call the method
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
groupData()
}
Instead of viewForHeaderInSection
implement titleForHeaderInSection
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return keys[section]
}
The other relevant table view datasource and delegate methods are
override func numberOfSections(in tableView: UITableView) -> Int {
return keys.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let letter = keys[section]
return people[letter]!.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
let letter = keys[indexPath.section]
let item = people[letter]![indexPath.row]
cell.textLabel!.text = item
return cell
}
To add a new item append the name to array
and call groupData
If you want a more sophisticated solution with animations when the sections and rows are inserted you have to write the logic yourself. The design array for the keys and dictionary for the names can be used as well as a custom struct including the letter index and an array for the rows.
Upvotes: 1
Reputation: 1
You should gouup data contact before show in table view,Each key will a section in tableview, i have sample code group data:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray *arrNameContact = @[@"Aname",@"Bname",@"Cname",@"Dname",@"Dname1",@"Aname1",@"Ename1",@"Bname1"];
NSMutableArray *arrKey = [self getArrayKeyFromArrayName:arrNameContact];
NSMutableDictionary *dict =@{}.mutableCopy;
for (NSString *key in arrKey) {
NSMutableArray *arrContactWithKey = [[NSMutableArray alloc]init];
for (NSString *name in arrNameContact) {
if ([name hasPrefix:key]) {
[arrContactWithKey addObject:name];
}
}
[dict setObject:arrContactWithKey forKey:key];
}
NSLog(@"%@",dict);
}
// Get All alphabet
- (NSMutableArray *) getArrayKeyFromArrayName:(NSArray *)arrName {
NSMutableArray *arrKey = @[].mutableCopy;
for (int i = 0; i < arrName.count; i++) {
NSString *strFirstCharacter = [arrName[i] substringToIndex:1];
if (arrKey.count == 0) {
[arrKey addObject:strFirstCharacter];
} else {
if (![self checkItemExistKey:strFirstCharacter inArray:arrKey]) {
[arrKey addObject:strFirstCharacter];
}
}
}
return arrKey;
}
- (BOOL) checkItemExistKey:(NSString *) key inArray:(NSArray *)arrKey {
for (NSString *keyCheck in arrKey) {
if ([keyCheck isEqualToString:key]) {
return TRUE;
}
}
return FALSE;
}
result after group data:
Printing description of dict:
{
A = (
Aname,
Aname1
);
B = (
Bname,
Bname1
);
C = (
Cname
);
D = (
Dname,
Dname1
);
E = (
Ename1
);
}
Good luck!
Upvotes: 0