'Addressbook'에 해당되는 글 1건

  1. 2010.06.22 UItableView customizing with Addressbook (네번째 스터디)
아이폰어플개발정보2010. 6. 22. 09:47
UItableView customizing with Addressbook (네번째 스터디)
안녕하세요.. 금일은 전 시간에 진행했던 테이블뷰에 대해서 쪼금 더 심도 있게 진행을 하겠습니다.
제목을 봅시다... 네 테이블뷰의 커스텀마이징 입니다...

@ 학습목표
- UITableViewCell 을 이용하여 테이블뷰 꾸미기
- ABAddressbook 프레임 워크 이용하기

개요를 말씀드리자면 IB를 이용한 커스텀셀을 생성하는 방법과 코딩으로 하는 방법 2가지가 있습니다 우선 모두다 해보겠습니다.
추가적인 보너스로 테이블의 내용을 iPhone 내부의 주소록을 데이터를 이용하여 만들어 보겠습니다..
이름하여 인맥북!!!! ㅋㅋ 귀찮으시더라도 시뮬레이터의 주소록에 이미지를 추가해 놓습니다. 그래야 이미지가 나와요..

먼저 뷰콘트롤러 기반의 포르젝트를 생성합니다.. 저는 ownLinks 라고 명명.. 하겠습니다. 
IB를 로드 해서 UITableView 를 추가합니다. 그리고 UITableView를 선택해서 connection을 설정합니다. delegate, dataSouce는 File's Owns와 연결을 합시다.. 그리고 세이브 해주시고 소스 코드로 돌아갑니다.



먼저 IB를 사용 하지 않고 Cell 을 디자인 해보겠습니다.
addressbook을 사용하기 위해서는 AddressBook/AddressBookUi 라는 2가지 프레임워크를 이용합니다. 
먼저 AddressBook 프레임 워크 입니다.. 네 이건 주소록 데이터를 읽어오고 편집 추가 저장 등을 할 수 있는 메서드들을 제공합니다.
두번째 프레임 워크인 AddressBookUI 는 말그대로 UI와 데이터를 연결하는 Delegate 메서드를 정의 합니다(사용은 아직 안해봐서 정확한 표현인지는 모르겠습니다만...)

저는 주소록의 데이터를 제가 만든 커스텀마이징된 테이블뷰에 넣기 위해서  AddressBook 프레임 워크만을 사용하였습니다.

프레임워크 파일을 프로젝트에 추가 합니다.

                                       

먼저 viewController.h 파일에 사용할 프레임 워크를 인포트 하고 프로토콜들을 추가 합니다.

#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h> // 프레임워크 추가
//UITableViewCell 하위 뷰의 구분자 선
#define kNameValueTag 1
#define kNumberValueTag 2
#define kImageTag 3

@interface ownLinksViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, > {
}
@end

다음는 바디 코드 입니다. 나머지 부분은 생략을 하고 제일 중요한 프로토콜 구현 부부입니다.

#pragma mark -
#pragma mark Table View Data Source Methods

-(NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
        // 테이블 수는 연락처에 입력된 연락처 수
ABAddressBookRef addressBook = ABAddressBookCreate();
NSInteger size = (NSInteger)ABAddressBookGetPersonCount(addressBook);
CFRelease(addressBook);
return size;
}

//tag값에 선언된 상수를 입력하여 해당 서버 뷰들을 구분한다.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//cell 구분자 언언
static NSString *CellTableIdentifier = @"CellTableIdentifier ";
//cell 존재 검사
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier];
if (cell == nil) {
              //cell 선언
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:CellTableIdentifier] autorelease];
        
               //cell에 들어갈 이미지 설정 
     CGRect imageViewRect = CGRectMake(5, 5, 30, 30);
UIImageView *personView = [[UIImageView alloc] initWithFrame:imageViewRect];
personView.tag = kImageTag;
[cell.contentView addSubview:personView];
[personView release];
        CGRect nameLabelRect = CGRectMake(35, 5, 65, 15);
        UILabel *nameLabel = [[UILabel alloc] initWithFrame:nameLabelRect];
        nameLabel.textAlignment = UITextAlignmentRight;
        nameLabel.text = @"Name:";
        nameLabel.font = [UIFont boldSystemFontOfSize:12];
        [cell.contentView addSubview: nameLabel];
        [nameLabel release];
        
        CGRect numberLabelRect = CGRectMake(35,25, 65, 15);
        UILabel *numberLabel = [[UILabel alloc] initWithFrame:numberLabelRect];
        numberLabel.textAlignment = UITextAlignmentRight;
  numberLabel.text = @"Number:";
        numberLabel.font = [UIFont boldSystemFontOfSize:12];
        [cell.contentView addSubview: numberLabel];
        [numberLabel release];
        
        CGRect nameValueRect = CGRectMake(110, 5, 200, 15);
        UILabel *nameValue = [[UILabel alloc] initWithFrame:nameValueRect];
        nameValue.tag = kNameValueTag;
        [cell.contentView addSubview:nameValue];
        [nameValue release];
        
        CGRect numberValueRect = CGRectMake(110, 25, 200, 15);
        UILabel *numberValue = [[UILabel alloc] initWithFrame:numberValueRect];
        numberValue.tag = kNumberValueTag;
        [cell.contentView addSubview:numberValue];
        [numberValue release];
        
}
//선택된 인덱스
 NSUInteger row = [indexPath row];  

//ABAdrressBookCreate()를 이용하여 현재 주소록 객체를 생성
ABAddressBookRef addressBook = ABAddressBookCreate();
//저장된 개인목록을 복사(Group 데이터는 ABAddressBookCopyArrayOfAllGroups를 이용
//개인 목록과 그룹 목록으로 구분되어 저장되어 있
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
//선택된 row 의 개인 정보 가져옴 
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, row);

//태그를 이용하여 라벨을 찾는다.
  UILabel *name = (UILabel *)[cell.contentView viewWithTag:kNameValueTag];
//개인정보 중 firstname 만 복사함 kABPersonFirstNameProperty 같은 각각의 인자가 정의 되어 있다.
name.text = (NSString *)ABRecordCopyValue(ref, kABPersonFirstNameProperty);

//전화번호부를 복사 여러개의 전호 번호가 존재하기 때문에 해당 데이터는 멀티 값을 가지는 배열로 저장되어 있다.
ABMutableMultiValueRef multi =  ABRecordCopyValue(ref, kABPersonPhoneProperty);
NSArray* phoneNumbers = (NSArray*)ABMultiValueCopyArrayOfAllValues(multi);
//전화 번호가 없는 경우 nil 값을 가진다.
if (phoneNumbers != nil) {
UILabel *number = (UILabel *)[cell.contentView viewWithTag:kNumberValueTag];
                //전화 번호는 배열로 저장되어 있기 때문에 원하는 정보가 위치한 index를 인자로 넘겨준다.
number.text = [phoneNumbers objectAtIndex:0];
}
//이미지를 가지는 검사 
if (ABPersonHasImageData(ref)) {
    // 이미지를 복사 하여 이미지 뷰에 입력
     // CFDataRef 데이터 형식으로 리턴된다. 형변환을 하여사
UIImage *personImage = [[UIImage alloc] initWithData:(NSData*)ABPersonCopyImageData(ref)];
UIImageView *imageView = (UIImageView *)[cell.contentView viewWithTag:kImageTag];
imageView.image = personImage;
[personImage release];
}
//프레임워크를 이용하여 생성된 객체(포인터아님)자원은 CFRelease를 이용하여 해제한다. 
CFRelease(multi);
CFRelease(ref);
//문제 발생
//ABAddressBookCreate, ABAddressBookCopyArrayOfAllPeople 를 이용하여 생성된 객체
//둘다 해제하게되면 메모리 크래쉬가 일어 난다. 둘중에 하나만 해제를 하여 사용
//원인을 추축하면 생성되는 시 같은 데이터를 참조하는게 아닐까 하는 추축이다... 구글링을 좀더 해서 원인을 
//파악해 야될것 같네요.
CFRelease(addressBook);
//주석처리..
// CFRelease(allPeople);

return cell;
}

이것을 실행하면 아래와 같이 나옵니다..




IB를 이용하는 방법은 이어 작성 하겠습니다.





 



출처 : http://blog.naver.com/PostView.nhn?blogId=coderider&logNo=50088797458
Posted by 오늘마감

댓글을 달아 주세요