본문 바로가기

iOS 앱 개발자 프로젝트/iOS 입문

[iOS] Connecting the Dots, Connecting the VCs...

VC 통신  연습을 다시, 기초부터 다시 점을 찍어 봅니다. 

 

Connecting the Dots... 

 

 

남의 코드를 타이핑하는 코더처럼 말고, 

고민하고 스스로 코딩해 보는 것에 초점을 맞추었습니다. 

 

이전에는 segue를 사용해 화면을 전환 후 closure를 사용하여 데이터를 전달했다면,

(secondVC -> firstVC 데이터를 전달할 땐 segue(performSegue)를 사용할 수 없으므로!!)

 

이번에는 performSegue 로 데이터를 전달해 보았습니다.

 

그리고 화면 내에서 FistVC 와 scondVC의 핵심 역할도 서로 바꿔 보았습니다.

다시말해, firstVC -> SecondVC 데이터 전달! 왜냐? 가능하고,, 더 간단하니까.. *Ꙩꙻ₀Ꙩꙻ)!

 

.. (확실하게 알려주는 롤드사마..)

 

  • A, B 2개의 화면이 있고, A → B 로 이동하는 플로우를 가지고 있음
  • A 화면에는 +  스테퍼능이 있음 (이전에는 B 화면에 스테퍼 기능이 있었음)
  • A 화면에서 증가시키면 B 화면의 숫자가 반영!

 

 

#1. 머릿 속으로 필요한 UI를 생각하며 시뮬레이션 해본다.

 

A 화면의 스테퍼 버튼이 화면 전환 역할까지 수행할 순 없을까? 

아, 그러면 tap할 수 있는 최대 횟수가 1이 된다. (그 다음 스텝을 시뮬레이션 해보는 연습, 꼭 !!) 

플러스 스테퍼를 두두두.. 누르려면 다음 화면 전환 버튼은 따로 만들어야만 한다. 

 

 

 

#2. 두 화면과 VC를 만들어 클래스 이름을 설정하고, 필요한 버튼과 레이블을 넣는다.

 

SecondViewController를 위한 새로운 ViewController 파일을 추가하고, 

(VC를 새로 추가할 땐 기억해 기호 2번, Cocoa Touch Class..)

기호 1번과 기호 2번, 상황에 맞게 선택할 것!

 

 

클래스 이름도 각각 FirstViewController, SecondViewController 로 설정.

(코드 내에서 이름을 수정할 땐 떠올려 우클릭, Refactor ..)

 

FirstVC의 + 스테퍼 버튼 이름은 tapToPlus으로,

SecondVC로 연결시키는 버튼의 이름은 goToNext으로,

SecondVC에는 숫자 0 레이블을 넣었다. constrain 조건도 충분하게 설정!

segue 연결 전 대기 중인 VCs

 

화면 -> 화면 segue 연결 (버튼 -> 화면 X)

 

inspector -> storyboard segue -> identifier

 

 

main에서 segue를 연결했으니, 이제 VC에서 코드 설계 시작! 

 

 

 

#3. FirstVC 에서 코드 작성

 

#3-1) go to next 버튼을 tap했을 때 호출되는 액션 메서드 설정

 

main에서 @IBActionUIButton sender로 지정하고 끌어와 연결하고,

performSegue 메소드 사용하여 아래와 같이 string 타입으로 내가 정했던 식별자를 넣어 주었다.

 

우선 여기까지만 하면 go to next 버튼을 tap했을 때 다음 화면으로 이동한다.

따라서 연결되는 어떤 이슈가 없이 화면을 전환하기만 한다면 여기까지만 하면 된다.

@IBAction에서 UIButton을 sender로 지정하고 performsegue 메소드로 연결 완성

 

 

#3-2) 버튼을 tap 할 때마다 1씩 증가함을 저장할 변수 count 세팅

 

현재는 빈 그릇이니 숫자 0을 넣어 int 타입으로 초기화했다.

var count = 0

 

 

#3-3) segue가 연결 되었을 때 이어지는 "what to do" or "where" 등의 구체적인 미션을 제시한다.

 

"내가 지정한 그 vcSegue 면 말이야" [ if segue.identifier == "vcSegue" ] ← 해당 segue 확인 및 상위 조건 부여

 

"prepare(for:sender:)(Segue를 통해 화면 전환이 일어나기 전 호출되는 함수)를 재정의해서 화면 전환 좀 준비해줘."

[ override func prepare(for segue: UIStoryboardSegue, sender: Any?) ] ← prepare 메소드 호출

prepare(for:sender:) 메서드를 사용하면 segue를 통해 전달되는 데이터를 설정할 수 있다.

 

 

"segue, 너의 destination은 SecondViewController를 다운캐스팅 해서 가져올거야."

[ let secondVC = segue.destination as? SecondViewController ] ← SecondViewController 가져오기

 

여기서 다운캐스팅을 하는 이유는 segue의 대상 ViewController(SecondViewController)가 UIViewController 타입으로 반환되기 때문에  SecondViewController 타입으로 접근하려면 다운캐스팅이 불가피하다. 만약 다운캐스팅을 하지 않으면 SecondViewController의 속성이나 메서드에 접근할 수 없게된다.

다운캐스팅을 하기 전. 즉, as를 쓰기전의 destination

 

다운캐스팅을 하기 전. 즉, as를 쓰기전의 secondVC

 

as? 를 붙이고 다운캐스팅을 하니 SecondViewController로 바뀌었다. guard let 으로 옵셔널 바인딩을 하여 안정성 있는 코드로 구현할 수도 있다.

 

 

" 아래와 같이 guard let 구문으로 else { return } 부분이 실행되어 메서드가 조기 종료되는 방식으로 언래핑 할 수도 있다. secondVC의 변수(segue.destination as? SecondViewController)가 nil인 상태(캐스팅 실패)에서는 secondVC.result = count 코드가 실행되지 않는다. "

guard let 으로 옵셔널 바인딩을 해서 ?를 없애고 캐스팅 실패를 처리할 수 있다.

 

 

 

"SecondViewController에서 가져온 result 속성에다가 변화된 (plus를 누른만큼 증가된) count 값 할당해."

[ secondVC?.result = count ]  " = count " 를 설명하자면, count 변수의 값을 SecondViewController의 result 속성에 할당하는 것이다. 이곳 FirstVC에서 계산된 count 값을 다음 화면으로 전달한다.

 

 

#3-4)  tapToPlus 버튼을 tap했을 때 호출되는 액션 메서드 설정

 

버튼을 탭할 때마다 count 변수 값을 1씩 증가시키는 tapToPlus 함수를 IBAction으로 연결한다. 

 

 

 

#4. SecondVC 에서 코드 작성

 

 

#4-1) (앞 화면에서 탭을 하면 1씩 증가하는) 레이블을 numberLabel 이름의 Outlet 변수로 설정해 @IBOutlet으로 연결

   @IBOutlet weak var numberLabel: UILabel!

 

 

#4-2) FirstVC의 prepare(for:) 함수에 연결할 result 변수를 선언하고 int 값으로 초기화 

 var result = 0

 

 

#4-3) viewDidLoad() 메서드에서 numberLabel의 text를 result 변수 값으로 설정 

    override func viewDidLoad() {
        super.viewDidLoad()

        numberLabel.text = "\(result)"
    
    }

 

 

numberLabel.text = "(result)"는 UILabel의 text 프로퍼티를 업데이트하는 부분으로 viewDidLoad() 메서드 내에 위치해야 한다. 왜냐하면 viewDidLoad() 메서드는 ViewController의 메인 뷰가 로드된 후 호출되기 때문이다. 따라서 만약 이 코드가 viewDidLoad() 메서드 외부에 있다면, numberLabel이 아직 초기화되지 않았을 수 있어 오류가 발생한다.

 

 

 

thanks to my teacher..