我是编程新手。我有一个粗略的c ++知识库,但Objective-c对我来说是全新的。
我正在尝试在应用中实现一个简单的UITableViewController,系统会提示用户从其联系人列表中添加电子邮件收件人。 TableViewController加载但不加载TableViewCell数据。我一直在搜索iOS开发人员库,我觉得这些信息非常像千篇一律。我找到了他们的示例代码并将其复制/粘贴到我的ViewController文件中。我做了必要的更改以符合我的文件,删除了一些不必要的电话,并按照我在这个网站上找到的远程处理我的问题的每个答案......无济于事!这是我到目前为止所做的:
·H
@interface RecipientsViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource>
的.m
#import "RecipientsViewController.h"
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
enum TableRowSelected
{
kUIDisplayPickerRow = 0,
kUICreateNewContactRow,
kUIDisplayContactRow,
kUIEditUnknownContactRow
};
// Height for the Edit Unknown Contact row
#define kUIEditUnknownContactRowHeight 81.0
@interface RecipientsViewController () < ABPeoplePickerNavigationControllerDelegate,ABPersonViewControllerDelegate,
ABNewPersonViewControllerDelegate, ABUnknownPersonViewControllerDelegate>
@property (nonatomic, assign) ABAddressBookRef addressBook;
@property (nonatomic, strong) NSMutableArray *menuArray;
@end
@implementation RecipientsViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
self.title = @"Recipients";
}
return self;
}
#pragma mark Load views
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
// Create an address book object
_addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
self.menuArray = [[NSMutableArray alloc] initWithCapacity:0];
[self checkAddressBookAccess];
[self.tableView reloadData];
}
#pragma mark -
#pragma mark Address Book Access
// Check the authorization status of our application for Address Book
-(void)checkAddressBookAccess
{
switch (ABAddressBookGetAuthorizationStatus())
{
// Update our UI if the user has granted access to their Contacts
case kABAuthorizationStatusAuthorized:
[self accessGrantedForAddressBook];
break;
// Prompt the user for access to Contacts if there is no definitive answer
case kABAuthorizationStatusNotDetermined :
[self requestAddressBookAccess];
break;
// Display a message if the user has denied or restricted access to Contacts
case kABAuthorizationStatusDenied:
case kABAuthorizationStatusRestricted:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Privacy Warning"
message:@"Permission was not granted for Contacts."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
break;
default:
break;
}
}
// Prompt the user for access to their Address Book data
-(void)requestAddressBookAccess
{
RecipientsViewController * __weak weakSelf = self;
ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error)
{
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf accessGrantedForAddressBook];
});
}
});
}
// This method is called when the user has granted access to their address book data.
-(void)accessGrantedForAddressBook
{
// Load data from the plist file
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Menu" ofType:@"plist"];
self.menuArray = [NSMutableArray arrayWithContentsOfFile:plistPath];
[self.tableView reloadData];
}
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return [self.menuArray count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *aCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (aCell == nil)
{
// Make the Display Picker and Create New Contact rows look like buttons
if (indexPath.section < 2)
{
aCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
aCell.textLabel.textAlignment = NSTextAlignmentCenter;
}
else
{
aCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
aCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
aCell.detailTextLabel.numberOfLines = 0;
// Display descriptions for the Edit Unknown Contact and Display and Edit Contact rows
aCell.detailTextLabel.text = [[self.menuArray objectAtIndex:indexPath.section] valueForKey:@"description"];
}
}
// Configure the cell...
return aCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section)
{
case kUIDisplayPickerRow:
[self showPeoplePickerController];
break;
case kUICreateNewContactRow:
[self showNewPersonViewController];
break;
case kUIDisplayContactRow:
[self showPersonViewController];
break;
case kUIEditUnknownContactRow:
[self showUnknownPersonViewController];
break;
default:
[self showPeoplePickerController];
break;
}
}
#pragma mark TableViewDelegate method
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Change the height if Edit Unknown Contact is the row selected
return (indexPath.section==kUIEditUnknownContactRow) ? kUIEditUnknownContactRowHeight : tableView.rowHeight;
}
#pragma mark Show all contacts
// Called when users tap "Display Picker" in the application. Displays a list of contacts and allows users to select a contact from that list.
// The application only shows the phone, email, and birthdate information of the selected contact.
-(void)showPeoplePickerController
{
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
// Display only a person's phone, email, and birthdate
NSArray *displayedItems = [NSArray arrayWithObjects:[NSNumber numberWithInt:kABPersonPhoneProperty],
[NSNumber numberWithInt:kABPersonEmailProperty],
[NSNumber numberWithInt:kABPersonBirthdayProperty], nil];
picker.displayedProperties = displayedItems;
// Show the picker
[self presentViewController:picker animated:YES completion:nil];
}
#pragma mark Display and edit a person
// Called when users tap "Display and Edit Contact" in the application. Searches for a contact named "Appleseed" in
// in the address book. Displays and allows editing of all information associated with that contact if
// the search is successful. Shows an alert, otherwise.
-(void)showPersonViewController
{
// Search for the person named "Appleseed" in the address book
NSArray *people = (NSArray *)CFBridgingRelease(ABAddressBookCopyPeopleWithName(self.addressBook, CFSTR("Appleseed")));
// Display "Appleseed" information if found in the address book
if ((people != nil) && [people count])
{
ABRecordRef person = (__bridge ABRecordRef)[people objectAtIndex:0];
ABPersonViewController *picker = [[ABPersonViewController alloc] init];
picker.personViewDelegate = self;
picker.displayedPerson = person;
// Allow users to edit the person’s information
picker.allowsEditing = YES;
[self.navigationController pushViewController:picker animated:YES];
}
else
{
// Show an alert if "Appleseed" is not in Contacts
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"Could not find Appleseed in the Contacts application"
delegate:nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alert show];
}
}
#pragma mark Create a new person
// Called when users tap "Create New Contact" in the application. Allows users to create a new contact.
-(void)showNewPersonViewController
{
ABNewPersonViewController *picker = [[ABNewPersonViewController alloc] init];
picker.newPersonViewDelegate = self;
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:picker];
[self presentViewController:navigation animated:YES completion:nil];
}
#pragma mark Add data to an existing person
// Called when users tap "Edit Unknown Contact" in the application.
-(void)showUnknownPersonViewController
{
ABRecordRef aContact = ABPersonCreate();
CFErrorRef anError = NULL;
ABMultiValueRef email = ABMultiValueCreateMutable(kABMultiStringPropertyType);
bool didAdd = ABMultiValueAddValueAndLabel(email, @"John-Appleseed@mac.com", kABOtherLabel, NULL);
if (didAdd == YES)
{
ABRecordSetValue(aContact, kABPersonEmailProperty, email, &anError);
if (anError == NULL)
{
ABUnknownPersonViewController *picker = [[ABUnknownPersonViewController alloc] init];
picker.unknownPersonViewDelegate = self;
picker.displayedPerson = aContact;
picker.allowsAddingToAddressBook = YES;
picker.allowsActions = YES;
picker.alternateName = @"John Appleseed";
picker.title = @"John Appleseed";
picker.message = @"Company, Inc";
[self.navigationController pushViewController:picker animated:YES];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"Could not create unknown user"
delegate:nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alert show];
}
}
CFRelease(email);
CFRelease(aContact);
}
#pragma mark ABPeoplePickerNavigationControllerDelegate methods
// Displays the information of a selected person
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
return YES;
}
// Does not allow users to perform default actions such as dialing a phone number, when they select a person property.
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
return NO;
}
// Dismisses the people picker and shows the application when users tap Cancel.
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker;
{
[self dismissViewControllerAnimated:YES completion:NULL];
}
#pragma mark ABPersonViewControllerDelegate methods
// Does not allow users to perform default actions such as dialing a phone number, when they select a contact property.
- (BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person
property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue
{
return NO;
}
#pragma mark ABNewPersonViewControllerDelegate methods
// Dismisses the new-person view controller.
- (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person
{
[self loadView];
}
#pragma mark ABUnknownPersonViewControllerDelegate methods
// Dismisses the picker when users are done creating a contact or adding the displayed person properties to an existing contact.
- (void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownPersonView didResolveToPerson:(ABRecordRef)person
{
[self.navigationController popViewControllerAnimated:YES];
}
// Does not allow users to perform default actions such as emailing a contact, when they select a contact property.
- (BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
return NO;
}
SORRY !!!不确定代码的哪些部分与问题最相关。
* 鉴于这么多代码对我来说有点压倒性的问题,我会非常感谢对此的一些帮助。我没有出现任何错误或问题,TableViewController加载。它只是提示用户允许访问联系人几次,而且从那时起就没有。即使提示确实显示,它也从未将我带到模拟器上的联系人。我在iOS模拟器中添加了联系人。
我真诚地感谢任何帮助!
答案 0 :(得分:0)
我还没有完成你的所有代码,但是我所描述的问题主要发生在我的数组为空时,尝试将数组内容的NSLog放在你要添加objets的地方,以便查看如果它的计数大于0。
答案 1 :(得分:0)
您使用的是哪个版本的iOS?这将决定它是否会显示,如果它是iOS 7,那么你需要获得查看地址簿的权限,这就是他们添加的新内容。