I want to replicate add contact like screen iPhone has. But I don't want to add contact in default phonebook instead I want to use the details in my app. Is it possible to open default add new contact screen and get all the data? If yes then how? A simple code snippet will be very helpful. Here is an image of add contact screen to better understand my question
You can try to add the contact to the address book, pull the data and then delete it from the address book. this is a fairly simple process.
I use this function to save all the person data to core data in my app. and then to delete the person from the addressBook.
+(void)savePersonDetails:(Person*)person{
ABAddressBookRef addressBook = ABAddressBookCreate();
ABRecordRef ref = ABAddressBookGetPersonWithRecordID(addressBook,[person.ID intValue]);
ABMutableMultiValueRef multiPhones = ABRecordCopyValue(ref, kABPersonPhoneProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multiPhones); i++) {
NSString *phoneNumber = (NSString*)ABMultiValueCopyValueAtIndex(multiPhones, i);
CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(multiPhones, i);
NSString *phoneNumberLabel =(NSString*) ABAddressBookCopyLocalizedLabel(locLabel);
CFRelease(locLabel);
Phone *phone =(Phone*)[NSEntityDescription insertNewObjectForEntityForName:#"Phone" inManagedObjectContext:person.managedObjectContext];
phone.number = phoneNumber;
phone.label = phoneNumberLabel;
phone.person = person;
[person addPhonesObject:phone];
[person release];
CFRelease(phoneNumber);
CFRelease(phoneNumberLabel);
}
CFRelease(multiPhones);
ABMutableMultiValueRef multiEmail = ABRecordCopyValue(ref, kABPersonEmailProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multiEmail); i++) {
NSString *mail = (NSString*)ABMultiValueCopyValueAtIndex(multiEmail, i);
CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(multiEmail, i);
NSString *mailLabel =(NSString*) ABAddressBookCopyLocalizedLabel(locLabel);
Mail *mailEntity =(Mail*)[NSEntityDescription insertNewObjectForEntityForName:#"Mail" inManagedObjectContext:person.managedObjectContext];
mailEntity.mail = mail;
mailEntity.label = mailLabel;
mailEntity.person = person;
[person addMailsObject:mailEntity];
CFRelease(locLabel);
[mail release];
[mailLabel release];
}
CFRelease(multiEmail);
ABMultiValueRef streets = ABRecordCopyValue(ref, kABPersonAddressProperty);
for (CFIndex j = 0; j<ABMultiValueGetCount(streets);j++){
CFDictionaryRef dict = ABMultiValueCopyValueAtIndex(streets, j);
CFStringRef typeTmp = ABMultiValueCopyLabelAtIndex(streets, j);
CFStringRef lbl = ABAddressBookCopyLocalizedLabel(typeTmp);
NSString *street = [(NSString *)CFDictionaryGetValue(dict, kABPersonAddressStreetKey) copy];
NSString *city = [(NSString *)CFDictionaryGetValue(dict, kABPersonAddressCityKey) copy];
NSString *state = [(NSString *)CFDictionaryGetValue(dict, kABPersonAddressStateKey) copy];
NSString *zip = [(NSString *)CFDictionaryGetValue(dict, kABPersonAddressZIPKey) copy];
NSString *country = [(NSString *)CFDictionaryGetValue(dict, kABPersonAddressCountryKey) copy];
Address *addressEntity =(Address*)[NSEntityDescription insertNewObjectForEntityForName:#"Address" inManagedObjectContext:person.managedObjectContext];
addressEntity.label = (NSString*)lbl;
addressEntity.street = street;
addressEntity.city = city;
addressEntity.state = state;
addressEntity.zip = zip;
addressEntity.country = country;
[street release];
[city release];
[state release];
[zip release];
[country release];
CFRelease(dict);
CFRelease(lbl);
CFRelease(typeTmp);
addressEntity.person = person;
[person addAddressesObject:addressEntity];
}
CFRelease(streets);
ABMutableMultiValueRef multiURL = ABRecordCopyValue(ref, kABPersonURLProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multiURL); i++) {
NSString *url = (NSString*)ABMultiValueCopyValueAtIndex(multiURL, i);
CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(multiPhones, i);
NSString *urlLabel =(NSString*) ABAddressBookCopyLocalizedLabel(locLabel);
Url *urlEntity =(Url*)[NSEntityDescription insertNewObjectForEntityForName:#"Url" inManagedObjectContext:person.managedObjectContext];
urlEntity.url = url;
urlEntity.label = urlLabel;
urlEntity.person = person;
[person addUrlsObject:urlEntity];
CFRelease(locLabel);
[urlLabel release];
[url release];
}
CFRelease(multiURL);
ABAddressBookRemoveRecord(addressBook, ref, nil);
ABAddressBookSave(addressBook, nil);
CFRelease(addressBook);
if (![person.managedObjectContext save:&error]) {
// Update to handle the error appropriately.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
exit(-1); // Fail
}
}
Related
I'm making an app in which i want to access the contact's first name and store them in to nsmutable array so that i can get the values of that array like array[0] up to array[i-1] and print them in table view.Here is my code:
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (addressBook != nil)
{
contacts_Image_List=[[NSMutableArray alloc]init];
NSLog(#"Succesful.");
NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSUInteger i = 0;
for (i = 0; i < [allContacts count]; i++)
{
Person *person = [[Person alloc] init];
ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
NSString *fullName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
person.firstName = firstName;
person.lastName = lastName;
person.fullName = fullName;
// person.userThumb[i]=firstName;
//[person.userThumb[i] addObject:#"firstName"];
//above line gives null
NSLog(#"%#",person.userThumb[i]);
my mutable array is in Person.h class.
On each iteration just do:
[person.yourMutableArray addObject:fullName]
Just ensure that your MutableArray has already been allocated, and that you only allocate it once.
I followed a tutorial I found online to create a tableview with sections and an index from an array of custom objects. This code works with the exception that when I select a row in the table I the index path for that section and not for the entire array. I can see why it doesn't work but I can't figure out how to address the fix, this is my cell for tableview code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"NameCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
int displayOrder = [defaults integerForKey:#"displayOrder"];
int sortOrder = [defaults integerForKey:#"sortOrder"];
NSString *alphabet = [listIndex objectAtIndex:[indexPath section]];
NSPredicate *sectionPredicate = [[NSPredicate alloc] init];
if (sortOrder == 1) {
//NSLog(#"fName is predicate at cell level");
sectionPredicate = [NSPredicate predicateWithFormat:#"fName beginswith[c] %#", alphabet];
} else {
//NSLog(#"lName is predicate at cell level");
sectionPredicate = [NSPredicate predicateWithFormat:#"lName beginswith[c] %#", alphabet];
}
NSArray *sectionContacts = [filteredList filteredArrayUsingPredicate:sectionPredicate];
if (isSearching) {
current = [filteredList objectAtIndex:indexPath.row];
} else{
current = [sectionContacts objectAtIndex:indexPath.row];
}
if (displayOrder == 1) {
NSString *fullName = [NSString stringWithFormat:#"%# %#",[current valueForKey:#"fName"],[current valueForKey:#"lName"]];
[cell.textLabel setText:fullName];
//NSLog(#"FirstNameFirst");
} else {
NSString *fullName = [NSString stringWithFormat:#"%# %#",[current valueForKey:#"lName"],[current valueForKey:#"fName"]];
[cell.textLabel setText:fullName];
//NSLog(#"LastNameFirst");
}
[cell.detailTextLabel setText:[current valueForKey:#"extension"]];
return cell; }
THen I call the segue with this code.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showContact"]) {
DetailViewController *dvc = [segue destinationViewController];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
NSDictionary *c = [filteredList objectAtIndex:path.row];
[dvc setCurrentContact:c];
[searchBar resignFirstResponder];
} }
The problem is that the objectAtIndex:path.row returns the index for that section but it isn't modified for the entire array, so if a name in the "B" section that is at index 4 of that section is tapped it returns the object at index 4 of the primary array. I have been scratching my head to figure out how to get the index for the full array and not for the one that is only local to that section.
I'll buy you a 6 pack of your favorite beverage if you can help!
Thanks!
You do it the same way that they do it in the first function, so change your prepareForSegue to this:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showContact"]) {
DetailViewController *dvc = [segue destinationViewController];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
NSDictionary *c;
NSString *alphabet = [listIndex objectAtIndex:[path section]];
NSPredicate *sectionPredicate = [[NSPredicate alloc] init];
if (sortOrder == 1) {
sectionPredicate = [NSPredicate predicateWithFormat:#"fName beginswith[c] %#", alphabet];
} else {
sectionPredicate = [NSPredicate predicateWithFormat:#"lName beginswith[c] %#", alphabet];
}
NSArray *sectionContacts = [filteredList filteredArrayUsingPredicate:sectionPredicate];
if (isSearching) {
c = [filteredList objectAtIndex:path.row];
} else{
c = [sectionContacts objectAtIndex:path.row];
}
[dvc setCurrentContact:c];
[searchBar resignFirstResponder];
}
}
Note that it would probably be best to pull the common code out and make a separate function instead of using it twice like this.
I am having problem in managing UITableView. I 'm posting a screenshot here to briefly explain the problem. Image 1 shows the default View when First Time view Appears. When I tap on yellow button(Yellow Button is in a custom table section header view) I open an UIAlertView with table in it like shown in the image 2. Then selecting any option I insert a custom cell with a button,textfield and another button. I have a mutable Array for each section so when I select an option I add that string into the corresponding section array and reloadtable.See image 3. Now when I enter values in UITextfields the values replaced by another cells. See the two images below for understanding the problem. image 4. Also when I delete a cell and insert a new the textfield is preloaded with previous value.
And here is the .m file implementation code for analyze the problem
#import "contactsViewController.h"
#import "textFieldCell.h"
#import "SBTableAlert.h"
#import "PhoneFieldCell.h"
#import "DHValidation.h"
#define kTextFieldTag 222
#define kTitleButtonTag 111
#define MAX_LENGTH 20
#define charecterLimit 13
#define PHONE_NUMBER #"0123456789+-"
#implementation contactsViewController
#synthesize currentTextField;
#synthesize choiceList;
#synthesize labelHeaders;
#synthesize selectedIndexPath;
#synthesize aTable;
#synthesize customText;
#synthesize currentSelectionType;
#synthesize phoneList;
#synthesize emailList;
#synthesize otherDetailsList;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
//Prepare array's for display in table header and in custom alert option table
[self prepareDataForTable];
[self initializeProperties];
//Set selected index to -1 by default
selectedIndex = -1;
}
//prepare array's for table
- (void) prepareDataForTable {
NSArray *temp = [[NSArray alloc] initWithObjects:#"work",#"home",#"mobile",#"custom",nil];
self.choiceList = temp;
[temp release];
NSArray *temp1 = [[NSArray alloc] initWithObjects:#"First Name",#"Last Name",nil];
self.labelHeaders = temp1;
[temp1 release];
}
- (void) initializeProperties {
//Initialize Mutable array's
NSMutableArray *temp = [[NSMutableArray alloc] initWithCapacity:0];
self.phoneList = temp;
[temp release];
NSMutableArray *temp1 = [[NSMutableArray alloc] initWithCapacity:0];
self.emailList = temp1;
[temp1 release];
NSMutableArray *temp2 = [[NSMutableArray alloc] initWithCapacity:0];
self.otherDetailsList = temp2;
[temp2 release];
}
#pragma mark -
- (IBAction) btnCancelTapped:(id) sender {
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction) btnDoneTapped:(id) sender {
[self.currentTextField resignFirstResponder];
//TODO: Fetch all the data from all the cells and notify the delegate.
NSMutableDictionary *allSectionsData = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
NSMutableDictionary *section1Dictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
NSMutableDictionary *phoneSectionDictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
NSMutableDictionary *emailSectionDictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
NSMutableDictionary *otherSectionDictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
//For Section 0
for (unsigned rowIndex = 0; rowIndex < 2; rowIndex++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:0];
UITableViewCell *cell = nil;
cell = (textFieldCell*)[aTable cellForRowAtIndexPath:indexPath];
UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];
//TextField validation
DHValidation *validation = [[DHValidation alloc] init];
NSString *str = [txtf.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *alertMessage = nil;
BOOL isvalid = NO;
if(![validation validateNotEmpty:str])
alertMessage = #"NameField should not be Empty";
else
isvalid = TRUE;
if(!isvalid){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:alertMessage delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
return ;
}
[validation release];
NSString *type = nil;
NSString *value = nil;
if(rowIndex == 0)
type = #"First Name";
else if(rowIndex == 1){
type = #"Last Name";
}
value = txtf.text;
if(!value){
//Do not insert that value in the dictinary
value = #"";
}else {
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,#"type",value,#"value",nil];
[section1Dictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
}
}
if([section1Dictionary count] > 0) {
[allSectionsData setObject:section1Dictionary forKey:#"PersonalDetailsSection"];
}
//For Section 1
for (unsigned rowIndex = 0; rowIndex < [phoneList count]; rowIndex++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:1];
UITableViewCell *cell = nil;
cell = (PhoneFieldCell*)[aTable cellForRowAtIndexPath:indexPath];
UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];
UIButton *btnTitle = (UIButton*)[cell viewWithTag:kTitleButtonTag];
NSString *type = nil;
NSString *value = nil;
type = [btnTitle currentTitle];
value = [txtf text];
if(!value || [[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:#""] ){
//Do not insert that value in the dictinary
continue;
}else {
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,#"type",value,#"value",nil];
[phoneSectionDictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
//[phoneSectionDictionary setObject:value forKey:type];
}
}
if([phoneSectionDictionary count] > 0) {
[allSectionsData setObject:phoneSectionDictionary forKey:#"PhoneSection"];
}
//For Section 2
for (unsigned rowIndex = 0; rowIndex < [emailList count]; rowIndex++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:2];
UITableViewCell *cell = nil;
cell = (PhoneFieldCell*)[aTable cellForRowAtIndexPath:indexPath];
UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];
UIButton *btnTitle = (UIButton*)[cell viewWithTag:kTitleButtonTag];
NSString *type = nil;
NSString *value = nil;
type = [btnTitle currentTitle];
value = [txtf text];
if(!value || [[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:#""] ){
//Do not insert that value in the dictinary
continue;
}else {
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,#"type",value,#"value",nil];
[emailSectionDictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
}
}
if([emailSectionDictionary count] > 0) {
[allSectionsData setObject:emailSectionDictionary forKey:#"EmailSection"];
}
//for Section 3
for (unsigned rowIndex = 0; rowIndex < [phoneList count]; rowIndex++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:3];
UITableViewCell *cell = nil;
cell = (PhoneFieldCell*)[aTable cellForRowAtIndexPath:indexPath];
UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];
UIButton *btnTitle = (UIButton*)[cell viewWithTag:kTitleButtonTag];
NSString *type = nil;
NSString *value = nil;
type = [btnTitle currentTitle];
value = [txtf text];
if(!value || [[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:#""] ){
//Do not insert that value in the dictinary
continue;
}else {
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,#"type",value,#"value",nil];
[otherSectionDictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
//[phoneSectionDictionary setObject:value forKey:type];
}
}
if([otherSectionDictionary count] > 0) {
[allSectionsData setObject:otherSectionDictionary forKey:#"OtherSection"];
}
}
#pragma mark -
#pragma mark UITableView Data Source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 4;
}
// Returns the number of rows in a given section.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger count = 0;
switch (section) {
case 0:
count = 2;
break;
case 1://Phone
count = [phoneList count];
break;
case 2://Email
count = [emailList count];
break;
case 3://Other
count = [otherDetailsList count];
break;
default:
count = 0;
break;
}
return count;
}
// Returns the cell for a given indexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"textFieldCustomCell";
static NSString *PhoneFieldCustomCellIdentifier = #"PhoneFieldCustomCell";
static NSString *EmailFieldCustomCellIdentifier = #"EmailFieldCustomCell";
static NSString *OtherDetailsCustomCellIdentifier = #"OtherDetailsCustomCell";
UITableViewCell *cell = nil;
switch (indexPath.section) {
case 0:{
cell = (textFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"textFieldCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[textFieldCell class]]){
cell = (textFieldCell *) currentObject;
break;
}
}
}
}
break;
case 1:{
cell = (PhoneFieldCell *)[tableView dequeueReusableCellWithIdentifier:PhoneFieldCustomCellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"PhoneFieldCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[PhoneFieldCell class]]){
cell = (PhoneFieldCell *) currentObject;
((PhoneFieldCell *)cell).enterText.delegate = self;
((PhoneFieldCell *)cell).enterText.text = nil;
break;
}
}
}
}
break;
case 2:{
cell = (EmailFieldCell *)[tableView dequeueReusableCellWithIdentifier:EmailFieldCustomCellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"EmailFieldCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[EmailFieldCell class]]){
cell = (EmailFieldCell *) currentObject;
((EmailFieldCell *)cell).enterText.delegate = self;
((EmailFieldCell *)cell).enterText.text = nil;
break;
}
}
}
}
break;
case 3:{
cell = (OtherDetailsCell *)[tableView dequeueReusableCellWithIdentifier:OtherDetailsCustomCellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"OtherDetailsCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[OtherDetailsCell class]]){
cell = (OtherDetailsCell *) currentObject;
((OtherDetailsCell *)cell).enterText.delegate = self;
((OtherDetailsCell *)cell).enterText.text = nil;
break;
}
}
}
}
break;
default:
break;
}
//Setup cell data
switch (indexPath.section) {
case 0:{
((textFieldCell*)cell).aTextField.delegate = self;
if(indexPath.row == 0){
((textFieldCell*)cell).aTextField.placeholder = #"Enter First Name";
}
if(indexPath.row == 1){
((textFieldCell*)cell).aTextField.placeholder = #"Enter Last Name";
}
((textFieldCell*)cell).aLabel.text = [self.labelHeaders objectAtIndex:indexPath.row];
}
break;
case 1:{
NSString *str = [phoneList objectAtIndex:indexPath.row];
[((PhoneFieldCell *)cell).changeBtn setTitle:str forState:UIControlStateNormal];
[((PhoneFieldCell *)cell).changeBtn addTarget:self action:#selector(changeButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
((PhoneFieldCell *)cell).btnDeleteCell.tag = indexPath.row;
[((PhoneFieldCell *)cell).btnDeleteCell addTarget:self action:#selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
break;
case 2:{
NSString *str = [emailList objectAtIndex:indexPath.row];
[((EmailFieldCell *)cell).changeBtn setTitle:str forState:UIControlStateNormal];
[((EmailFieldCell *)cell).changeBtn addTarget:self action:#selector(changeButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
((EmailFieldCell *)cell).btnDeleteCell.tag = indexPath.row;
[((EmailFieldCell *)cell).btnDeleteCell addTarget:self action:#selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
break;
case 3:{
NSString *str = [otherDetailsList objectAtIndex:indexPath.row];
[((OtherDetailsCell *)cell).changeBtn setTitle:str forState:UIControlStateNormal];
[((OtherDetailsCell *)cell).changeBtn addTarget:self action:#selector(changeButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
((OtherDetailsCell *)cell).btnDeleteCell.tag = indexPath.row;
[((OtherDetailsCell *)cell).btnDeleteCell addTarget:self action:#selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
break;
default:
break;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 30;
}
- (UIView*) tableView: (UITableView*) tableView viewForHeaderInSection: (NSInteger) section {
if (section == 0) {
return nil;
}
return [self headerViewForSection:section];
}
// Handle row selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
- (UIView*) headerViewForSection:(NSInteger)section {
CGRect lblTitleFrame = CGRectMake(15, 0, 200, 20);
CGRect btnFrame = CGRectMake(280.0, 0.0, 30.0, 30.0);
CGRect headerViewFrame = CGRectMake(0,0, 40, 30);
NSString *lblTitleText = nil;
switch (section) {
case 1://phone
lblTitleText = #"Phone";
break;
case 2://email
lblTitleText = #"Email";
break;
case 3://other details
lblTitleText = #"Other";
break;
default:
break;
}
//Create a header view with a label and a button
UIView *headerView = [[[UIView alloc] initWithFrame:headerViewFrame] autorelease];
UILabel *titleForTable = [[UILabel alloc]initWithFrame:lblTitleFrame];
titleForTable.text = lblTitleText;
titleForTable.backgroundColor = [UIColor clearColor];
titleForTable.textColor = [UIColor whiteColor];
titleForTable.shadowColor = [UIColor whiteColor];
[headerView addSubview:titleForTable];
[titleForTable release];
UIButton *phoneButton = [[UIButton alloc] initWithFrame:btnFrame];
phoneButton.alpha = 0.7;
phoneButton.tag = section;
[phoneButton setImage:[UIImage imageNamed:#"Yellow.png"] forState: UIControlStateNormal];
[phoneButton addTarget: self action: #selector(headerTapped:) forControlEvents: UIControlEventTouchUpInside];
[headerView addSubview: phoneButton];
[phoneButton release];
return headerView;
}
#pragma mark -
#pragma mark UITextField Delegate
- (void)textFieldDidBeginEditing:(UITextField *)textField {
self.currentTextField = textField;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
//textfield charecters range
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length >= MAX_LENGTH && range.length == 0){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"You reached maximum limit - 20"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
return NO; // return NO to not change text
}
else {
return YES;
}
}
#pragma mark -
- (void)deleteButtonTapped:(id)sender{
if([self.currentTextField isFirstResponder]) {
[self.currentTextField resignFirstResponder];
}
NSLog(#"Button Pressed");
UIButton *btnDelete = (UIButton*)sender;
id cell = [[btnDelete superview] superview];
if([cell isKindOfClass:[PhoneFieldCell class]]) {
cell = (PhoneFieldCell*)cell;
}
if([cell isKindOfClass:[EmailFieldCell class]]) {
cell = (EmailFieldCell*)cell;
}
if([cell isKindOfClass:[OtherDetailsCell class]]) {
cell = (OtherDetailsCell*)cell;
}
NSIndexPath *indexPath = [aTable indexPathForCell:cell];
NSLog(#"Section is %d and row is %d",indexPath.section,indexPath.row);
switch (indexPath.section) {
case 1:
[self.phoneList removeObjectAtIndex:[btnDelete tag]];
[aTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
break;
case 2:
[self.emailList removeObjectAtIndex:[btnDelete tag]];
[aTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
break;
case 3:
[self.otherDetailsList removeObjectAtIndex:[btnDelete tag]];
[aTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
break;
default:
break;
}
[aTable reloadData];
}
- (void)changeButtonTapped:(id)sender{
if([self.currentTextField isFirstResponder]) {
[self.currentTextField resignFirstResponder];
}
UIButton *btnDelete = (UIButton*)sender;
id cell = (PhoneFieldCell*)[[btnDelete superview] superview];
if([cell isKindOfClass:[PhoneFieldCell class]]) {
cell = (PhoneFieldCell*)cell;
}
if([cell isKindOfClass:[EmailFieldCell class]]) {
cell = (EmailFieldCell*)cell;
}
if([cell isKindOfClass:[OtherDetailsCell class]]) {
cell = (OtherDetailsCell*)cell;
}
self.selectedIndexPath = [aTable indexPathForCell:cell];
shouldModify = YES;
NSLog(#"Section is %d and row is %d",self.selectedIndexPath.section,self.selectedIndexPath.row);
SBTableAlert *alert = nil;
alert = [[[SBTableAlert alloc] initWithTitle:#"Options" cancelButtonTitle:#"Cancel" messageFormat:#"Select your option!"] autorelease];
[alert setType:SBTableAlertTypeSingleSelect];
[alert.view addButtonWithTitle:#"OK"];
[alert setDelegate:self];
[alert setDataSource:self];
[alert show];
}
- (void)headerTapped:(id)sender {
if([self.currentTextField isFirstResponder]) {
[self.currentTextField resignFirstResponder];
}
UIButton *tappedButton = (UIButton*)sender;
//set current selection according to section
switch ([tappedButton tag]) {
case 1://Phone
self.currentSelectionType = SELECTIONTYPE_PHONE;
break;
case 2://Email
self.currentSelectionType = SELECTIONTYPE_EMAIL;
break;
case 3://Other details
self.currentSelectionType = SELECTIONTYPE_OTHER;
break;
default:
break;
}
SBTableAlert *alert;
alert = [[[SBTableAlert alloc] initWithTitle:#"Options" cancelButtonTitle:#"Cancel" messageFormat:#"Select your option!"] autorelease];
[alert setType:SBTableAlertTypeSingleSelect];
[alert.view addButtonWithTitle:#"OK"];
[alert setDelegate:self];
[alert setDataSource:self];
[alert show];
}
#pragma mark - SBTableAlertDataSource
- (UITableViewCell *)tableAlert:(SBTableAlert *)tableAlert cellForRow:(NSInteger)row {
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil] autorelease];
[cell.textLabel setText:[self.choiceList objectAtIndex:row]];
if(row == selectedIndex)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else {
cell.accessoryType == UITableViewCellAccessoryNone;
}
return cell;
}
- (NSInteger)numberOfRowsInTableAlert:(SBTableAlert *)tableAlert {
if (tableAlert.type == SBTableAlertTypeSingleSelect)
return [self.choiceList count];
else
return 4;
}
#pragma mark - SBTableAlertDelegate
- (void)tableAlert:(SBTableAlert *)tableAlert didSelectRow:(NSInteger)row {
if (tableAlert.type == SBTableAlertTypeMultipleSelct) {
UITableViewCell *cell = [tableAlert.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0]];
if (cell.accessoryType == UITableViewCellAccessoryNone)
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
else
[cell setAccessoryType:UITableViewCellAccessoryNone];
[tableAlert.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] animated:YES];
}
else if (tableAlert.type == SBTableAlertTypeSingleSelect) {
selectedIndex = row;
[tableAlert.tableView reloadData];
[tableAlert.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] animated:YES];
}
}
- (void)tableAlert:(SBTableAlert *)tableAlert didDismissWithButtonIndex:(NSInteger)buttonIndex {
if(buttonIndex == 1){
if(selectedIndex == -1){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Select at least one choice" message:nil
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
}
else if(cellSelected == FALSE){
if(selectedIndex == 3){
UIAlertView *customAlert = [[UIAlertView alloc] initWithTitle:#"Enter Custom Message" message:#"\n\n"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok",nil];
customAlert.tag = 99;
CGAffineTransform myTransForm = CGAffineTransformMakeTranslation(0,0);
UITextField *temp = [[UITextField alloc] initWithFrame:CGRectMake(15, 50, 255, 30)];
self.customText = temp;
[temp release];
self.customText.backgroundColor = [UIColor whiteColor];
self.customText.placeholder = #"Enter Custom Text";
self.customText.clearButtonMode = UITextFieldViewModeWhileEditing;
self.customText.layer.cornerRadius = 5;
[customAlert addSubview:self.customText];
[customAlert setTransform:myTransForm];
[customAlert show];
[customAlert release];
}else {
UITableViewCell *cell = [tableAlert.tableView cellForRowAtIndexPath:[ NSIndexPath indexPathForRow:selectedIndex inSection:0]];
NSString *val = cell.textLabel.text;
if(!shouldModify) {
switch (self.currentSelectionType) {
case SELECTIONTYPE_PHONE:
[phoneList addObject:val];
break;
case SELECTIONTYPE_EMAIL:
[emailList addObject:val];
break;
case SELECTIONTYPE_OTHER:
[otherDetailsList addObject:val];
break;
default:
break;
}
}
else {
switch (self.selectedIndexPath.section) {
case 1:
[phoneList replaceObjectAtIndex:self.selectedIndexPath.row withObject:val];
break;
case 2:
[emailList replaceObjectAtIndex:self.selectedIndexPath.row withObject:val];
break;
case 3:
[otherDetailsList replaceObjectAtIndex:self.selectedIndexPath.row withObject:val];
break;
default:
break;
}
shouldModify = NO;
}
}
}
if(self.currentSelectionType != SELECTIONTYPE_UNKNOWN || self.selectedIndexPath.section > 0)
[aTable reloadData];
selectedIndex = -1;
[tableAlert release];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(alertView.tag == 99 && buttonIndex == 1){
NSString *val = [self.customText text];
if(!val || [[val stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:#""]){
//show error alert here and return from here
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Please fill a value for custom text"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[errorAlert show];
[errorAlert release];
return;
}
switch (self.currentSelectionType) {
case SELECTIONTYPE_PHONE:
[phoneList addObject:val];
[aTable reloadData];
break;
case SELECTIONTYPE_EMAIL:
[emailList addObject:val];
[aTable reloadData];
break;
case SELECTIONTYPE_OTHER:
[otherDetailsList addObject:val];
[aTable reloadData];
break;
default:
break;
}
}
}
#pragma mark -
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
self.currentTextField = nil;
self.choiceList = nil;
self.labelHeaders = nil;
self.selectedIndexPath = nil;
self.aTable = nil;
self.customText = nil;
self.phoneList = nil;
self.emailList = nil;
self.otherDetailsList = nil;
self.customText = nil;
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[phoneList release];
[emailList release];
[otherDetailsList release];
[customText release];
[customText release];
[aTable release];
[selectedIndexPath release];
[choiceList release];
[labelHeaders release];
[currentTextField release];
[super dealloc];
}
#end
here is your answer http://www.icodeblog.com/2011/01/04/elctextfieldcell-a-useful-tableviewcell-for-forms/
u can also manually do some customization according to your app need
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView reloadData];
}
I've been struggling with adding assets from the iPhone Photo Library to a AVMutableComposition and then export them. Here is what I got:
Finding the assets: (here I grab the AVURLAsset)
-(void) findAssets {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate just videos.
[group setAssetsFilter:[ALAssetsFilter allVideos]];
[group enumerateAssetsUsingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop){
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
NSURL *url = [representation url];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
// Do something interesting with the AV asset.
[thumbs addObject:alAsset];
[assets addObject:avAsset];
}else if(alAsset == nil){
[self createScroll];
}
}];
}
failureBlock: ^(NSError *error) {
// Typically you should handle an error more gracefully than this.
NSLog(#"No groups");
}];
[library release];
}
Here I add a asset to my composition (I use the first object in the array for testing only.
-(void) addToCompositionWithAsset:(AVURLAsset*)_asset{
NSError *editError = nil;
composition = [AVMutableComposition composition];
AVURLAsset* sourceAsset = [assets objectAtIndex:0];
Float64 inSeconds = 1.0;
Float64 outSeconds = 2.0;
// calculate time
CMTime inTime = CMTimeMakeWithSeconds(inSeconds, 600);
CMTime outTime = CMTimeMakeWithSeconds(outSeconds, 600);
CMTime duration = CMTimeSubtract(outTime, inTime);
CMTimeRange editRange = CMTimeRangeMake(inTime, duration);
[composition insertTimeRange:editRange ofAsset:sourceAsset atTime:composition.duration error:&editError];
if (!editError) {
CMTimeGetSeconds (composition.duration);
}
}
And finally I export the comp and here it crashes
-(void)exportComposition {
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
NSLog (#"can export: %#", exportSession.supportedFileTypes);
NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
NSString *exportPath = [documentsDirectoryPath stringByAppendingPathComponent:EXPORT_NAME];
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
exportSession.outputURL = exportURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;//#"com.apple.quicktime-movie";
[exportSession exportAsynchronouslyWithCompletionHandler:^{
NSLog (#"i is in your block, exportin. status is %d",
exportSession.status);
switch (exportSession.status) {
case AVAssetExportSessionStatusFailed:
case AVAssetExportSessionStatusCompleted: {
[self performSelectorOnMainThread:#selector (exportDone:)
withObject:nil
waitUntilDone:NO];
break;
}
};
}];
}
Does anyone have an idea of what it might be? It crashes on
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
And I tried different presets and outputFileTypes.
Thanks
* SOLVED *
I have to answer my own question now when I have solved. It's amazing that I've been struggling with this for a whole day and then I fix it right after posting a question :)
I changed and moved:
composition = [AVMutableComposition
composition];
to:
composition = [[AVMutableComposition
alloc] init];
I think I was too tired when I was working on this yesterday. Thanks guys!
I want to convert NSMutableArray to NSArray to it gives error following is code
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
tempPeoples=[[NSMutableArray alloc]init];
for(int i=0;i<nPeople;i++){
ABRecordRef i1=CFArrayGetValueAtIndex(allPeople, i);
[tempPeoples addObject:i1];
//[peoples addObject:i1];
}// end of the for loop
// Peoples is NSArray
// peoples=[[NSArray alloc] initWithArray: tempPeoples];
peoples=[NSArray arrayWithArray:tempPeoples];
Please help
I found the solution using following code
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *allPeople = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
tempPeoples= [NSMutableArray arrayWithCapacity:0];
for(int i=0;i<nPeople;i++){
ABRecordRef i1=CFArrayGetValueAtIndex(allPeople, i);
NSString* name = (NSString *)ABRecordCopyValue(i1,kABPersonFirstNameProperty);
[tempPeoples addObject:name];
// [peoples addObject:i1];
}// end of the for loop
peoples=[NSArray arrayWithArray:tempPeoples];