저는 프로그래밍에 익숙하지 않습니다. 나는 C++의 거친 지식 기반을 가지고 있지만 objective-c는 완전히 새로운 것이다.TableViewController 연락처가 표시되지 않습니다.
사용자가 연락처 목록에서 전자 메일받는 사람을 추가 할 것인지 묻는 응용 프로그램에서 간단한 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, @"[email protected]", 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;
}
미안! 어떤 코드 섹션이 문제와 가장 관련이 있는지 확실하지 않습니다.
* 많은 코드가 문제 해결을 위해 다소 압도적 인 경우이 문제에 대한 도움을 크게 주시면 감사하겠습니다. 오류나 문제가 나타나면 TableViewController가로드됩니다. 사용자에게 몇 번만 연락처에 대한 액세스를 허용하고 이후로는하지 않았습니다. 프롬프트가 표시 되더라도 시뮬레이터의 연락처로 이동하지 않았습니다. iOS 시뮬레이터에 연락처를 추가했습니다.
나는 어떤 도움에 진심으로 감사드립니다!
감사합니다! 좋아, 그래서 방금 0으로 계산했다. 어떻게 해결할 수 있을까요? 다음은 NSLog를 추가 한 코드입니다. - (void) viewDidLoad { [super viewDidLoad]; // 주소록 개체 만들기 _addressBook = ABAddressBookCreateWithOptions (NULL, NULL); self.menuArray = [[NSMutableArray alloc] initWithCapacity : 0]; [self checkAddressBookAccess]; [self.tableView reloadData]; NSLog (@ "배열의 항목 수 : % lu", [_menuArray count]); } – FundamentalClue