2015-12-15 26 views
0

我想要的是使用属性形成一个现有的CNContact对象的子接触。 我从CNContactPickerViewController得到CNContact对象,并在tableview中显示所有属性。存储单元从桌面开关打开

tableviewcell嵌入了开关。我在导航项上有一个预览按钮,当按下按钮时,如果属性中的开关处于打开状态,则此属性应存储在新的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#创建的字典,与开关状态和在观看记录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#在表视图数据源代表加载开关的状态在indexpath和

- (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

是否所有的控件都存储在一个单元中?或者,你有多个单元用于每个“CNContact”对象,其中一些可能不在屏幕上? – Stonz2

+0

@ Stonz2对不起,我不确定你在问什么。我从CNContactViewPickerController获取CNContact对象。而对于联系人的属性(电话,电子邮件,网址..)我使用UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@“Cell”];并嵌入了开关 –

+0

你是说你需要获取多个单元格的内容/状态,其中一些可能不在屏幕上?或者,在一个非常大的单元中你需要的是所有的东西,其中一部分可能不在屏幕上? – Stonz2

回答

0

与其枚举表格视图中的所有单元格,不如在表格视图的单元格中存储开关的状态。我会想象这已经完成了,否则,仅仅通过滚动表视图,开关的状态将不可靠/一致。

例如,在您的cellForRowAtIndexPath:方法中,您必须告诉小区,交换机是否应显示为onoff。您可以通过将交换机的状态保存在实例级别的数组中来完成此操作。这是一种方法:

@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]]; 
} 
+0

谢谢你的回答,你说得对,我需要记录我的开关状态。因为我有几个单元格部分和每个部分的行取决于CNContact对象,我不能使用标签女巫可以传递一个整数。我的解决方案是使用NSIndexpath属性创建UISwitch的子类。转换开关时,应该更改NSIndexpath处的值。在数据源代理功能中,我将在索引路径中加载交换机的状态。我将更新一些代码.. –

+0

正确 - 上面的例子只适用于1节的表格。这只是为了了解哪个开关已切换并将其保存在单元对象以外的其他位置。 – Stonz2

+0

谢谢@ Stonz2,我是IOS新手,探索和学习新东西总是很棒的。 –