[iPhone] - 시작하세요! 아이폰 3 프로그래밍 - Part 7. 탭바와 피커

iPhone/[위키북스]시작하세요! 아이폰3 프로그래밍 2010. 7. 12. 22:06

* 델리게이트와 데이터소스
- 피커는 여러 가지 작업을 델리게이에게 위임한다. 그 중에서도 가장 중요한 것은 각 행과 해당 행에 속한 컴포넌트 중에서 실제로 무엇을 그릴지를 결정하는 일이다. 피커는 델리게이트에게 문자열 또는 주어진 컴ㅁ포넌트의 특정 위치에 내용을 그리기 위한 뷰를 요청한다.

- 데이터소스는 피커에게 몇 개의 컴포턴트와 몇 개의 목록이 각각의 컴포넌트를 구성하고 있는지 알려준다. 데이터소스는 델리케이트와 유사한 방식으로 동작하지만, 메서드가 미리 정해진 시간에 호출된다는 점이 다르다.

* 탭바 아이콘
- 아이콘은 24 * 24 픽셀 크기여야 하고, .png 포맷으로 저장되어야 한다. 또 아이콘 파일은 투명 배경을 가지고 있어야 한다. 일반적으로 중간크기의 회색 아이콘이 탭바에서 가장 잘 어울린다.

* Tab Bar Controller
+ Tab Bar Item Attributes
-- Tab Bar Item
---- Badge = 이 옵션은 메일 애플리케이션에서 읽지 않은 메일이 몇 개인지를 나타낼 때 아이콘 위에 빨간색 숫자를 보여주는 것처럼 탭자에 빨간색 아이콘을 보여주기 위해 사용된다.
---- Identifier = 이것은 Favorites와 Search와 같은 일반적인 아이콘을 탭바에서 사용할 수 있도록 만들어 준다.

-- Bar Item
---- Title = 제목
---- Image = 사용할 이미지 파일

* 작업 순서
1. 탭을 클릭하고 속성 인스펙터를 사용하여 뷰 컨트롤러와 연결시킨 탭의 nib파일 이름을 입력
2. 아이텐터티 인스펙터를 열고 탭과 연결된 뷰 컨트롤러의 하위클래스를 변경
3. 탭바 아이템을 수정하기 위해 뷰 컨트롤러 대신에 탭을 한번 더 클릭하고 탭바 아이템의 텍스트와 아이콘을 설정

* Picker View
-- 날짜 피커와는 조금 다른점은 일반적인 피커는 자신이 어떤 데이터를 가지고 있는지를 알려주지 않는다. 데이터를 직접 보관하지 않기 때문이다. 대신 델리게이트와 데이터소스가 그 역할을 담당한다. 우리는 대신에 직접 피커에게 어떤 행이 선택되었는지 물어보고, PickerData 배열에 대응하는 데이터를 선택해야 한다.
-- viewDidLoad에서 우리는 피커에 데이터를 공급할 수 있도록, 여러 객체를 담을 수 있는 배열을 생성했다. 일반적으로 데이터는 프로젝트 폴더의 Resources폴더에 있는 프로퍼티 리스트 파일과 같은 소스들로부터 전달된다.

피커 구현에 필요한 새로운 메서드
* UIPickerViewDataSource에서 나온 공통으로 필요한 메서드

- (NSInteger) numberOfComponentsInPickerView:(UIPickerView *) pickerView
{
    return 1;
}

--- 피커는 하나 이상의 회전판 또는 컴포넌트를 가질 수 있기 때문에, 이 방법을 사용해서 피커가 얼마나 많은 컴포넌트를 표시해야 할지를 물어볼수 있다. UI 피커가 매개변수로 전달되었다는데 주목하자. 이 매개변수는 우리가 요청을 하는 피커 뷰를 가리키는 매개변수로서, 이를 통해 동일한 데이터소스가 여러 개의 피커를 관리 할 수 있게 된다.

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    return [pickerData count];
}

-- 피커에게 해당 컴포넌트에 몇개의 행이 있는지를 물어보는 메서드

*UIPickerViewDelegate에서 나온 공통으로 필요한 메서드
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger) row forComponent:(NSInteger)component
{
    return [pickerData objectAtIndex:row];
}

-- 이 메서드에서 피커는 특정 컴포넌트에서 특정 행에 대한 자료를 제공하도록 요청한다. 우리는 요청받은 컴포넌트와 행의 정보와 함께 피커에 대한 포인터를 제공하면 된다.

* 2개 이상의 회전판 피커 구현시 델리게이트와 데이터 소스 예제
// 몇개의 회전판을 구성할것인가?
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
 return 2;  // 몇개의 회전판을 구성할것인가 ... 2라면 2개의 회전판이 존재하는 피커
}
 
// 어떤 회전판에 어떤 데이터소스를 사용할것인가?
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
   if(component == 0)
      return [self.breadTypes count];
   else
      return [self.fillingTypes count];
}
// 선택된 회전판에서 데이터 알아내기
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
   if(component == 0)
      return [self.breadTypes objectAtIndex:row];
   else
      return [self.filiingTypes objectAtIndex:row];
}

* 번들(Bundle)이란?
- 특별한 구조를 따르는 컨텐츠를 가진 좀 특별한 폴더의 일종. 애플리케이션과 프레임워크도 모두 번들이고, 이들을 호출하면 우리의 애플리케이션을 나타내는 번들 객체를 리턴하게 된다. NSBundle의 주된 용도는 프로젝트에 추가한 Resources폴더에서 리소스를 획득하는 것이다. 애플리케이션을 빌드할 때 이 파일들이 여러분의 애플리케이션의 번들로 복사된다.

* Dictionary로 file에서 데이터 가져오기
-(void)viewDidLoad
{
  NSBundle *bundle = [NSBundle  mainBundle];     //애플리케이션의 메인 번들에서 참조를 획득
  NSString *plistPath = [bundle pathForResource:@"statedictionary" OfType:@"plist"];
  NSDictionary *dictionary = [[NSDictionary alloc] initWithContensOfFile:plistPath];
  self.stateZips = dictionary;
  [dictionary release];
 
  NSArray *components = [self.stateZips allKeys];    
  NSArray *sorted = [components sortedArrayUsingSelector:@selector(compare:)];
  self.states = sorted;
 
  NSString *selectState = [self.states objectAtIndex:0];
  NSArray *array = [stateZips objectForKey:selectedState];
  slef.zips = array;
}

* 피커의 선택이 변결될 때마다 메서드가 게속 호출된다.
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
  if(component == kStateComponent)
  {
    NSString *selectedState = [self.states objectAtIndex:row];
    NSArray *array = [statZips objectForKey:selectedState];
    self.zips = array;
    [picker selectRow:0 inComponent:kStateComponent animated:YES];
    [picker reloadComponent:kZipComponent];
  }
}
: