과제 목표

  • Navigation Controller 를 이용하여 View안의 버튼과 Navigation Bar의 back Button을 통해 3개의 ViewController을 이동
  • 각 ViewController의 상단에 Title을 생성
  • 다음 ViewController로 뷰 중앙에 이동하기 버튼과 TextField가 존재
  • TextField에는 이전 ViewController의 이름 출력
  • 각각의 ViewController는 하나의 Singletone Class에 접근하여 View생성시에 이전 View 의 이름을 가져와 TextField에 출력해주고 Singletone Class의 Property에 자신의 이름을 넣어놓는다.
    • property는 하나만 사용
  • Navigation Controller 간의 이동은 1->2, 2->1는 Storyboard로 구현
  • 2->3, 3->2는 코드로 구현
    iOS 지원 버전은 8.0

1 단계. Singletone Class 만들기

SDK는 보통 싱글톤으로 만들기 때문에 Singletone Class를 만들어서 각 컨트롤러에서 공유할 수 있는 객체를 생성한다.

OBJECTIVE-C

// NEClass.h
#import <Foundation/Foundation.h>
@interface NEClass : NSObject
+ (instancetype) sharedInstance;
- (NSString *) getPreviousViewName;
- (void) setPreviousViewName:(NSString *)prevViewName;
@end

OBJECTIVE-C

// NEClass.m

#import "NEClass.h"

@interface NEClass()
@property(strong, nonatomic, getter=_getPreviousViewName, setter=_setPreviousViewName:) NSString * previousViewName;
// property를 헤더파일에서 선언안하고 구현부에서 하는 이유는 SDK니까
// 공개 안하고 쓰려고 하는 것.
// readonly를 써도 되지만, 수정이 잦아서 이렇게 보통 쓴다.
@end

@implementation NEClass

@synthesize previousViewName;

+ (instancetype) sharedInstance {
    static NEClass *obj = nil;
    
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        
        obj = [[super alloc] init];
        [obj _setPreviousViewName:@"nil"];
    });
    
    return obj;
}

- (NSString *) getPreviousViewName {
    return [self _getPreviousViewName];
}

- (void) setPreviousViewName:(NSString *)prevViewName {
    [self _setPreviousViewName:prevViewName];
}
@end

우선 클래스 메소드 안에 static 변수로 객체를 하나만 생성해서 그 객체를 계속 사용하게 한다.
보통은 헤더파일에서 property를 설정하는 데, SDK에서는 접근을 막으려고 구현파일 안에서 보통 선언한다고 한다. readonly 옵션을 주어서 헤더파일에 선언해도 되겠지만, 변경이 자주 되서 보통은 구현파일 안에서 선언해서 사용한다. 이번 경우에는 게터, 세터 둘다 사용하기 때문에 헤더에서 선언해서 사용해도 되지만, 이런 방식에 익숙해져야되서 이런식으로 한번 구현해봤다.

그럼 이제 사용법을 알아보자. 이 클래스의 목적은 뷰 이동시에 이전 뷰의 이름을 저장했다가 다음 뷰로 이동 시 이전 뷰의 이름을 표시해주고 현재 뷰의 이름을 저장하는 게 목적이다.

OBJECTIVE-C

- (void)viewWillAppear:(BOOL)animated {

    NEClass * ne = [NEClass sharedInstance];
    
    if( [[ne getPreviousViewName] isEqualToString:@"nil"]) {
        [ne setPreviousViewName:@"Zero ViewController"];
    }
    
    previousViewNameLabel.text = [ne getPreviousViewName];
    [ne setPreviousViewName:NSStringFromClass([self class])];
}

각 컨트롤러의 viewWillAppear에서 사용해주면 된다. viewDidLoad는 컨트롤러 생성 후 한번만 호출되기 때문에 맨 처음 이동한 직전 뷰의 이름 밖에 저장하지 못한다. sharedInstance로 static 객체를 얻어온다. 그 객체의 instance 메소드들을 이용해서 겟과 셋을 해주면 된다. 중간의 if문은 맨 처음의 FirstViewController에서는 이전 뷰가 없기 때문에 초기값을 세팅해주는 것이다.


2 단계. Navigation 구성하기

과제에서 주어진 것은 3개의 뷰를 만들어서 한번은 스토리보드로 이동을 구현하고, 한번은 코드로 구현하라는 것이었다. 내가 해봤던 뷰의 이동 구현 방법은 3가지 정도가 되어서 뷰를 하나 더 추가해서 3가지 구현 방법을 모두 사용해봤다. 우선 전체적인 뷰의 연결 모습은 이렇게 구성이 된다.
img

내가 생각하는 뷰의 이동 구현 방법은 다음과 같이 3개의 방법이 있다.

1. 버튼에 segue를 연결해서 코드 한 줄 없이 버튼 클릭 시에 자동으로 뷰의 이동이 이루어진다. 다음과 같은 연결 관계를 볼 수 있다.

img

2. 뷰에 segue를 연결한 후 버튼 클릭 액션 발생 시에 코드를 이용해서 연결해 주는 것이다. 다음과 같은 연결 관계를 볼 수 있고, segue의 Identifier를 지정해주면 다음과 같은 코드로 연결관계가 생성될 수 있다.

img

OBJECTIVE-C

- (IBAction)buttonTapped:(UIButton *)sender {
    [self performSegueWithIdentifier:@"SecondToThird" sender:self];
}

3. 마지막으로는 아래의 사진처럼 스토리보드 상에서는 어떠한 연결 관계도 없이 코드로만 뷰의 이동이 이루어진다. 코드에 대해서 조금 설명하자면, Storyboard에서 미리 정해놓은 Identifier로 ViewController 객체를 참조한다. 그리고 그 ViewController로 이동을 하면 되는 데, 일반 뷰의 경우에는 else 문에 있는 것처럼 present로 하면 되지만, Navigation일 경우에는 push를 해주어야 뷰 위의 Navigation바가 잘 나타난다. Navigation에서 단계를 타고 들어가는 것은 stack처럼 구현이 되어있다. 만약 Navigation Bar에서 백버튼을 눌러서 이전 뷰로 가는 액션을 직접 구현한다면 push의 반대인 pop을 써서 처리하면 된다.

img

OBJECTIVE-C

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];

UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"FourthView"];

if (self.navigationController) {
    [self.navigationController pushViewController:vc animated:YES];
} else {
    [self presentViewController:vc animated:YES completion:nil];
}

3단계. iOS 지원버전 8.0으로

SDK에서 iOS지원을 8버전부터 하기 때문에 아래와 같이 iOS Deployment Target 버전을 8.0으로 맞춰줘야 한다.

img

또한, storyboard도 9.0 이상 부터와 그 아래 버전이 다르기 때문에 storyboard 버전도 맞춰줘야 한다.

img