我想要的是使用现有CNContact
对象的属性生成子联系人。
我从CNContact
获取了CNContactPickerViewController
对象,并在tableview中显示所有属性。
tableviewcell嵌入了switch。我在导航项目上有一个预览按钮,当按下按钮时,如果属性中的开关打开,则此属性应存储在新的CNMutableContact
中。
我的问题是:如果联系人的属性太多,我就无法保存屏幕外属性。有没有办法解决这个问题。
获得子联系的部分代码:
+(CNMutableContact*)newContactWithSelectedFieldInTableView:(UITableView*)tableView FromContact:(CNContact*)contact
{
CNMutableContact* aContact = [[CNMutableContact alloc]init];
//get all indexPath from tableview
NSMutableArray* indexPathArr = [[NSMutableArray alloc]init];
NSInteger nSections = [tableView numberOfSections];
for (int j=0; j<nSections; j++) {
NSInteger nRows = [tableView numberOfRowsInSection:j];
for (int i=0; i<nRows; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:j];
[indexPathArr addObject:indexPath];
}
}
//selected phone numbers
//go through indexPath
for (NSIndexPath* path in indexPathArr)
{
UITableViewCell* nameCell = [tableView cellForRowAtIndexPath:path];
UISwitch *mySwitch = (UISwitch *)nameCell.accessoryView;
switch (path.section)
{
case basicInfoSection://basic info section (name,company,department,title)
{
int row = 0;
if(path.row==row)
{
if(mySwitch.on)
{
aContact.givenName = contact.givenName;
aContact.middleName = contact.middleName;
aContact.familyName = contact.familyName;
}
}
if(![contact.organizationName isEqualToString:@""])
{row += 1;
if(path.row==row)//company row
{
//store company
if(mySwitch.on)
aContact.organizationName = contact.organizationName;
}
}
if(![contact.departmentName isEqualToString:@""])
{row += 1;
if(path.row==row)//department row
{
//store department
if(mySwitch.on)
aContact.departmentName = contact.departmentName;
}
}
if(![contact.jobTitle isEqualToString:@""])
{row += 1;
if(path.row==row)//jobTitle row
{
//store job Title
if(mySwitch.on)
aContact.jobTitle = contact.jobTitle;
}
}
}
break;
case phoneSection:
{
if(mySwitch.on)
{
aContact.phoneNumbers = [aContact.phoneNumbers arrayByAddingObject:contact.phoneNumbers[path.row]];
}
}
break;
我想出了一个解决方案,现在工作正常,下面列出了一些代码:
1#创建UISwitch的子类
#import <UIKit/UIKit.h>
@interface SwitchWithIndex : UISwitch
@property (strong ,nonatomic) NSIndexPath* indexPath;
@end
2#创建一个字典,用于记录带有switch状态的indexPath,并在视图中根据需求tableview布局为所有可能的indexPath加载,循环数据源(CNContact)。
for(NSInteger section=0; section<7; section++)
{
switch (section) {
{
//section 1 basic info(name, company, department, job title)
case basicInfoSection:
{int row =0;
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:row inSection:section];
[_switchStateAtIndex setObject:boolNumber forKey:indexPath];
if(![_contact.organizationName isEqualToString:@""])
{row += 1;
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:row inSection:section];
[_switchStateAtIndex setObject:boolNumber forKey:indexPath];
}
if(![_contact.departmentName isEqualToString:@""])
{row += 1;
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:row inSection:section];
[_switchStateAtIndex setObject:boolNumber forKey:indexPath];
}
if(![_contact.jobTitle isEqualToString:@""])
{row += 1;
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:row inSection:section];
[_switchStateAtIndex setObject:boolNumber forKey:indexPath];
}
}
break;
//section 2 phones
case phoneSection:
{
for(NSInteger row=0; row<[_contact.phoneNumbers count];row++)
{
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:row inSection:section];
[_switchStateAtIndex setObject:boolNumber forKey:indexPath];
}
}
break;
//more code ..
3#在表视图中,Datasource Delegate在indexpath和
加载switch的状态- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
SwitchWithIndex* mySwitch = [[SwitchWithIndex alloc] init];
[mySwitch addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
NSNumber* switchStateNumber =[_switchStateAtIndex objectForKey:indexPath];
BOOL switchState = [switchStateNumber boolValue];
mySwitch.on = switchState;
mySwitch.indexPath = [[NSIndexPath alloc]init];
mySwitch.indexPath = indexPath;
cell.accessoryView = mySwitch;
//more code
和以下代码检测开关状态的变化。
- (void) switchChanged:(id)sender {
SwitchWithIndex* mySwitch = sender;
NSIndexPath* indexPath = mySwitch.indexPath;
NSLog(@"%@",indexPath);
NSNumber* switchStateBool = [NSNumber numberWithBool:mySwitch.on ? YES : NO];
[_switchStateAtIndex setObject:switchStateBool forKey:indexPath];
NSLog( @"The switch is %@", mySwitch.on ? @"ON" : @"OFF" );
}
4#最后根据开关状态保存所选字段
+(CNMutableContact*)newContactFrom:(CNContact*)contact withSwitchState:(NSMutableDictionary*)switchState
{
CNMutableContact* aContact = [[CNMutableContact alloc]init];
for (NSIndexPath* indexPath in switchState.keyEnumerator)
{
NSNumber* boolNumber = [switchState objectForKey:indexPath];
BOOL switchOn = [boolNumber boolValue];
switch (indexPath.section) {
case basicInfoSection://basic info section (name,company,department,title)
{
int row = 0;
if(indexPath.row==row)
{
if(switchOn)
{
aContact.givenName = contact.givenName;
aContact.middleName = contact.middleName;
aContact.familyName = contact.familyName;
}
}
if(![contact.organizationName isEqualToString:@""])
{row += 1;
if(indexPath.row==row)//company row
{
//store company
if(switchOn)
aContact.organizationName = contact.organizationName;
}
}
//more code
可能还有其他解决方案来解决这个问题,上面就是我现在可以做的事情。
答案 0 :(得分:0)
您需要将交换机的状态存储在表视图单元格以外的其他位置,而不是枚举表视图中的所有单元格。我想这已经完成了,否则只需滚动表视图,开关的状态就不可靠/一致。
例如,在cellForRowAtIndexPath:
方法中,您必须告诉单元格切换是否应显示为on
或off
。您可以通过在实例级数组中保存开关的状态来完成此操作。这是一种方法:
@interface YourClass ()
{
// Create an instance-level array to store switch values.
NSMutableArray *switchValues;
}
...
- (void)viewDidLoad {
switchValues = [NSMutableArray new];
for(int i = 0; i < YOUR_TABLE_SIZE; i++)
[switchValues insertObject:[NSNumber numberWithBool:DEFAULT_SWITCH_STATE]];
// Alternatively, populate your array with another data object if all the
// switches do not have the same default starting state (on/off).
}
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
YourCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier" forIndexPath:indexPath];
...
// Add a target to the switch so we know when it toggles.
[cell.toggleSwitch addTarget:self action:@selector(switchSwitched:) forControlEvents:UIControlEventValueChanged];
cell.toggleSwitch.tag = indexPath.row;
// Set the state to the appropriate value.
cell.toggleSwitch.on = [[switchValues objectAtIndex:indexPath.row] boolValue];
return cell;
}
- (void)switchSwitched:(UISwitch *)switcher
{
// Toggle the switch's value in the instance array
[switchValues replaceObjectAtIndex:switcher.tag withObject:[NSNumber numberWithBool:switcher.on]];
}