본문 바로가기
모바일앱/iOS

원피스 현상금 랭킹앱 만들기(6) - 뷰컨트롤러 간 데이터 전달하기

by GeekCode 2021. 11. 8.
반응형

데이터 넘기기

 

이제 해야할 것은 뷰컨트롤러간의 데이터를 넘겨주는 것을 설정하는 것이다.

우리가 만들어야 하는 것은 셀을 클릭했을 때, 전환된 화면에 그림과 이름, 현상금이 크게 보이도록 하는 것이다. 

그런데 이게 각 셀을 눌렀을 때, 각각 다른 데이터가 넘어갈 수 있게 코드를 짜야한다.

 

스토리보드에 UI 배치

먼저 Storyboard에서 꾸밀 것들을 먼저 배치해준다.

 

이미지, 이름을 넣을 Label, 현상금을 넣을 Label을 넣어준다.

모두 배치하고 

이제는 너무 익숙한 오토레이아웃을 설정해주자

이미지를 View에 연결하며 Top을 먼저 지정해주자. 100정도로 지정해주자. 

또 View에 드래그하면서 X축에서 가운데에 위치하도록 설정

그리고 사이즈도 지정해주자. 사이즈는 이미지뷰 자체를 약간 옆에 끌어당기면 생긴다.

Aspect Ratio 선택

해당 그림의 원래 비율을 선택해주면 좋다. 이 그림은 7:10 비율로 제작되었기 때문에 7:10으로 수정

아직 가로길이가 정해져있지 않아서 View를 기준으로 Leading(좌측공간)을 설정하자. 50정도로 수정

그다음 Label을 원하는 곳에 배치해주자.

폰트크기는 30으로 지정, Style은 Bold로 수정

예시로 Luffy라는 이름을 입력했다.

 

이번엔 Luffy 라벨을 imageView에 드래그하면서 

Vertical Spacing과 X축방향으로 센터를 지정해준다. 

 

다음, 현상금 라벨을 따로 만들지않아도 방금 만든 이름 라벨을 복사해도 좋다.

색을 LightGrey로 설정, 현상금 입력

마지막으로 이름 라벨과 똑같이 현상금 라벨을 이름 라벨에 드래그하면서

Vertical Spacing과 X축방향으로 센터를 지정해준다.  이름은 이미지뷰에, 현상금은 이름에 연결을 한 것이다.

어느정도 배치가 끝났다.  

DetailView와 Outlet을 연결

이제 DetailView와 Outlet을 연결해야한다.  

차례로 선택해서 Assistant Editor 를 연다.

 

BountyViewController에서 만든 버튼들과 똑같기 때문에 복사해오자

DetailViewController에 복붙 

똑같은 내용이기 때문에 문제가 없다.

 

매치되는 

 

연결을 마치면 아래처럼 동그라미가 채워진다.

정보 가져오기

그다음 해야할 일은 정보들을 

1. 이미지 2. 이름 3.현상금 정보를 받아오는 것이다. 

 

BountyViewController를 보면 

1. 이미지는 nameList를 통해 가져왔다.

2. 이름은 nameList를 통해 가져왔다.

3. 현상금은 bountyList를 통해 가져왔다.

그래서 DetailViewController에 이름과 현상금 정보만 가져오면 된다는 것을 알게됐다.

이름과 현상금 정보를 옵셔널로 변수지정해준다.

이렇게만 하고 빌드해보면

이미지는 비어있고 아직 스토리보드에 만들어 놓은 화면만 뜨는 것을 볼수 있다. 

데이터가 넘어오는 과정

데이터가 넘어오는 과정을 생각해보자

 

DetailView로 넘어올 때,  변수로 지정한 name과 bounty에 데이터가 꽂혀있으면

위쪽에 위치한 Outlet 으로 지정된 UI컴포넌트들에 해당하는 데이터를 넣어줄수가 있다. 

 

이제 DetailView에 updateUI라는 메서드를 만들어준다.

 

ViewDidLoad는  이 ViewController가 실제로 메모리로 올라오는 시점의 바로 직전에 호출이 된다.

그래서 이 곳에 updateUI를 실행시켜주자.

updateUI()

이제 updateUI()를 완성시켜주자.  

아래 세가지를 세팅할 것이다. 

imgView의 image

nameLabel의 text

bountLabel의 text

name과 bounty의 정보들이 있을 때, 사용할 수 있도록 

옵셔널이니까 옵셔널 바인딩을 이용해서 실제로 데이터들이 있을때, 정보들을 세팅할 수 있다.

 

다시 정리,

1. UIoutlet를 스토리보드와 연결

2. 데이터에 필요한 property를 추가 했고 (변수 지정 name, bounty)

3. ViewController가 뜨기직전, 메모리에 올라왔을 때, updateUI를 실행한다.

4. 이 때, 2번의 데이터를 가지고 UIcomponent에 업데이트를 한다.

 

이제 마지막으로 필요한 것은 2번에 데이터가 들어오는 것만 남았다. 

이건 BountyViewController에서 보내주면 된다.

 

 

데이터 보내기

// UITableViewDataSource -> 1. 몇개가 필요하니 2. 어떻게 표현할거니

// UITableViewDelegate -> 어떻게 반응할거야? -> 어떻게 줄거니?

 

셀이 클릭됐을 때, 세그웨이를 수행하는 메소드가 호출이 됐다.

그런데 세그웨이를 수행할 때, 그 직전에 세그웨이 수행을 준비하는 메서드가 있다.

prepare for segue 함수이다. 

이것을 누르면 자동으로 override가 생성되는데 그 이유는

 

ViewController에 원래 있는 함수인데  상속을 받았다. 상속받은 클래스에서 다시 이걸 사용하려다 보니

Override를 사용하게 되는 것이다.

 

UIViewController를 ⌃키를 누르고 definition을 들어가보면 중간에 prepare함수가 이미 들어가 있는 것을 발견할 수 있다.

⌘ + F 로 prepare를 사용했는지 검색해봤다.

이렇게 이미 상속받기 전에 정의가 되어있기 때문에 override를 사용해야한다.  

 

다시 순서를 정리해보면 

// UITableViewDelegate에서 performSegue를 수행하는데 그 직전에 prepare가 실행이 된다.

그리고 그 데이터에 대한 힌트를  아래 코드가 실행될 때 알아야한다. 

여기서 Indexpath가 넘어오기 때문에 몇 번 셀이 클릭되는 지 알 수가 있다.

여기서 sender를 수정하는 것이다. 

indexpath는 크게 두가지가 있다. section과 row가 있다.  

우리는 지금 단일 섹션을 사용하기 때문에 row데이터를 사용하면된다. 몇번째 셀인지 row 사용

어떤 세그웨이를 말하는 건지 알려주고 -> showDetail

지칭하고 있는 destination 세그웨이를 지정해준다. 

여기에는 name과 bounty가 있다. 여기에 꽂아주는 것이다. 

여기에 몇번째 인지 추가해준다.

데이터를 꽂아주려는 데 이 정보가 몇번째인지 이미 sender를 통해 보냈다. 

sender는 any? 옵셔널인데 그걸 int로 다운캐스팅을 할 수 있다. 



이정보를 옵셔널바인딩 해서 있으면 nameList에서 몇번째인지

bountyList에서 몇번째인지 알 수 있다.

이제 perform segue웨이를 할때 prepare를 이용해서 정보를 보내면 

DetailView에서 메모리에 올라가고 수행이 되는데 

변수 지정된 것들에 세팅이 되는 것이다. 

updateUI메서드가 수행 될때, UI컴포넌트에 필요한 정보들까지 옵셔널로 데이터로 다 업데이트 시켰다.

이러면 드디어 끝!!

 

 

반응형