본문 바로가기
개발(Development)/iOS(아이폰)

[한글 번역_05] Start Developing iOS Apps (Swift) - Building the UI > Work with View Controllers

by 카레유 2015. 10. 30.
안녕하세요 카레유입니다.

Apple에서 제공해주는 Swift iOS 앱 개발 가이드를 한글 번역해보았습니다.

영어실력도, 개발실력도, 심지어 한국어 실력도 미흡합니다.

부족한 부분이 많지만, 많은 도움 되시길 바라겠습니다.

아직 작성 중인 내용으로 시간을 갖고 개선해 나갈 생각입니다.

감사합니다.






Work with View Controllers

이번 레슨에서는 FoodTracker앱의 meal scene에 대한 UI작업을 좀더 진행해보겠습니다. 기존 UI엘리먼트를 재배치하고, UI에 사진을 추가하기 위해 Image Picker를 이용한 작업을 진행하겠습니다. 이번 레슨을 마치고 나면 아래와 같은 모습의 앱을 완성하게 됩니다.

image

Learning Objectives

At the end of the lesson, you’ll be able to:

  • "ViewController"의 라이프 사이클에 대해 이해하고, 콜백함수들(viewDidLoad, viewWillAppear, viewDidAppear)이 언제 호출되는지 알게 됩니다.

  • ViewController사이에서 데이터를 주고 받을 수 있습니다.

  • ViewController를 제거할 수 있습니다.

  • gesture recognizer"를 이용해서 별도로 정의한 이벤트를 발생시킬 수 있습니다.

  • "UIVeiw/UIControl" 클래스 계층구조에 기반하여 객체의 동작을 예측해볼 수 있습니다.

  • "asset catalog"를 이용해 image assets을 프로젝트에 추가할 수 있습니다.

Understand the View Controller Lifecycle

지금 우리의 FoodTracker앱은 하나의 ViewController에 의해 관리되는 하나의 scene만을 갖고 있습니다. 하지만 좀더 복잡한 앱을 만들려면 더 많은 scene이 필요합니다. 또한 화면에 나타났다 사라졌다하는 다양한 view들을 로딩하고 언로딩하는 작업도 해야합니다.

"UIViewController"클래스(혹은 서브클래스)의 객체는 "뷰 계층구조"를 관리하기 위한 메서드들을 갖고 있습니다. iOS는 ViewController의 상태 변화에 따라 자동으로 이 메서드들을 호출(callback)합니다. ViewController 서브클래스를 만들면, UIViewController클래스의 정의된 메서드들을 상속받게 되고, 각 메서드에 원하는 동작을 작성할 수 있습니다. 따라서 이 메서드들이 언제 호출되는지를 이해하는 것은 매우 중요합니다. 그래야만 적절한 타이밍에 어떤 view를 노출하고, 제거할지를 관리할 수 있기 때문입니다. 이번 레슨에서는 이에 대해 다루게 될 것입니다. 

image

"UIViewController"의 메서드들은 아래와 같이 호출됩니다.

  • viewDidLoad()—ViewController의 컨텐트뷰(view계층구조의 가장 상위단계에 있는 content view)가 스토리보드로 부터 생성되어 로드되면 호출됩니다. 이 메서드에서는 각종 초기화 작업을 하기에 최적화 되어 있습니다. 하지만 앱의 제한된 리소스로 인해 view가 정상적으로 로드되지 않을수도 있으며, 이 경우에 이 메서드는 다시 호출될 수 있습니다.(단 한번만 호출된다고 보장할 수 없습니다)

  • viewWillAppear()—view 가 화면에 노출되기 전에 해야할 작업을 하기에 적합합니다. view는 다른 view와의 관계에 따라 보이기도 하고 안 보이기도 하기 때문에, 이 메서드는 컨텐트뷰(content view)가 스크린에 나타나기 직전에 호출 됩니다.

  • viewDidAppear()—Intended for any operations that you want to occur as soon as the view becomes visible, such as fetching data or showing an animation. Because a view’s visibility may be toggled or obscured by other views, this method is always called immediately after the content view appears onscreen.  view가 화면에 나타나자 마자 수행할 작업을 작성하기에 적합합니다. 주로 데이터를 가져오거나 애니메이션을 보여주는 작업등을 합니다. view들은 다른 view와의 관계에 의해 보이거나 안보이거나 하기 때문에, 이 메서드 또한 컨텐트가 스크린에 나타난 후에 호출됩니다.

이 외에도 위의 다이어그램에서 볼 수 있는 것처럼 view가 사라지는 것과 관련된 추가 메서드들도 존재합니다.

FoodTracker앱에서도 적절한 타이밍에 view를 로드하고 노출하기 위해 위의 메서드들을 이용할 것입니다. 사실 우리는 이미 ViewController파일의 viewDidLoad()메서드에 약간의 코드를 작성한 적이 있습니다.

  1. override func viewDidLoad() {
  2. super.viewDidLoad()
  3. // Handle the text field’s user input through delegate callbacks.
  4. nameTextField.delegate = self
  5. }

ViewController가 view와 data model사이의 커뮤니케이션 역할을 하는 설계 방식을 MVC(Model-View-Controller) 패턴이라고 합니다. MVC패턴에서 model은 앱의 data를 관리합니다. view는 사용자 인터페이스를 노출하고 컨텐츠들을 구성하여 보여줍니다. 그리고 controller는 이런 view들을 관리하지요. controller는 사용자의 액션에 반응하여 data model로 부터 데이터를 받아 구성한 컨텐츠로 view 를 만들어내기 때문에, model과 view사이에서 커뮤니케이션 역할을 하는 일종의 게이트웨이라고 할 수 있습니다. MVC는 iOS앱을 설계하는 핵심적인 패턴이며, 사실 FoodTracker앱도 이미 MVC패턴에 따라 만드는 중입니다.

앱 설계에 MVC패턴이 사용된다는 사실을 기억하고, 이제 우리 앱의 UI를 한단계 끌어올려봅시다. 이번 레슨에서 meal 화면(scene)의 최종 레이아웃을 만들어 볼 예정입니다.

Add a Meal Photo

meal scene의 최종 UI를 만들기 위한 다음 단계는 특정 음식의 사진을 보여주는 것입니다. 이를 위해 UIImageView의 객체인 image view를 이용해 보겠습니다.

To add an image view to your scene

  1. 스토리보드에 Main.stroyboard를 열어주세요

  2. utility area에서 Object library를 열어주세요(메뉴바에서 View > Utilities > Show Object Library 를 선택해도 됩니다)

    image
  3. Object Library의 검색창(filter field)에서 "Image View"  객체를 찾아보세요

  4. Image View를 드래그해서 stack view 내부의 버튼 밑에 배치하세요

    image
  5. Image View를 선택한 상태에서, utility area의 Size inspector를 열어주세요

    inspector selector bar에서 다섯번째 버튼을 누르면 됩니다. Size inspector를 통해 스토리보드에서 선택한 객체의 크기와 위치를 조절할 수 있습니다.

    image
  6. "Intrinsic Size" Field의 값을 "Placeholder"로 설정해주세요

  7. Width와 Height항목을 모두 320으로 입력하고 엔터키를 누르세요

    An empty image view doesn’t have an intrinsic content size. You’re giving your image view a placeholder size so you can specify the appropriate constraints in your interface. image view는 현재 비어있기때문에 내부 콘텐츠 사이즈(intrinsic content size)를 갖고 있지 않습니다. image view에 Placeholder 사이즈를 설정함으로써, 인터페이스 상에서 표현될 적절한 컨스트레인트(constraint)를 설정할 수 있습니다.

    image
  8. canvas의 우측하단에서 Pin메뉴를 열어주세요

    image
  9. "Aspect Ratio"항목을 체크해주세요

    Pin메뉴의 항목들이 아래 화면과 같으면 됩니다.

    image
  10. "Add 1 Constraints" 버튼을 클릭해주세요

    image

    이렇게 작업함으로써 Image View는 1:1의 비율을 갖게 되었습니다. 즉 언제나 정사각형 사이즈로 보이게 됩니다.

  11. ImageView를 선택한 상태에서, Attributes inspector를 열어주세요

    utilities 영역의 inspector selector bar의 네번째 버튼을 누르면 열 수 있습니다. Attributes inspector를 통해 스토리보드에 있는 객체의 속성을 설정할 수 있습니다.

  12. Attributes inspector에서 Mode 필드의 값을 "Aspect Fill" 로 설정해주세요

    이 옵션을 선택하면 비율이 다른 이미지가 찌그러지는 걸 방지할 수 있습니다.

  13. Attributes inspector 에서 "Interaction" 필드에서 "User Interaction Enabled" 항목을 체크해주세요

    나중에 사용자가 Image View 와 상호작용(interaction)할 때, 이 기능을 사용하게 될 것입니다.(*역자 : imageView는 기본적으로 사용자의 입력에 반응할 수 없습니다. 사용자가 이미지를 탭하거나 하는 액션을 가할 때 이벤트를 발생시키기 위해서는 별도의 작업이 필요합니다)

현재까지 작업한 화면은 아래와 같습니다.

image

Display a Default Photo

사용자가 image view를 선택할 수 있다는 것을 인지할 수 있게 하기 위해 디폴트 이미지(placeholder image)를 추가하도록 하겠습니다.

image

아 레슨의 맨 마지막에서 다운 받을 수 있는 파일의 "Images/" 폴더에서 있는 사진파일을 이용하실 수 있습니다. 물론 다른 사진을 이용해도 상관 없습니다.

To add an image to your project

  1. project navigator에서 "Assets.xcassets"를 선택해서 asset catalog를 열어주세요.

    asset catalog는 앱에서 사용할 이미지들을 정렬하여 저장하고 있는 곳입니다.

  2. 화면 좌하단에 있는 (+) 버튼을 누르고, 팝업 메뉴에서 "New Image Set"을 눌러주세요

    image
  3. 왼쪽 화면에서 "image" set의 이름을 더블클릭하여 "defaultPhoto"로 수정하세요

  4. 컴퓨터의 파인더를 이용해서 추가하고 싶은 사진을 고르세요

  5. 그 사진을 드래그해서 image set의 "2x" 슬롯에 넣으세요

    image

    "2x"는 iPhone6 시뮬레이터에 최적화된 디스플레이 해상도를 의미합니다.

디폴트 이미지(default placeholder image)를 프로젝트에 추가했으므로, 이제 Image View에 노출 시키는 작업을 해보겠습니다.

To display a default image in the image view

  1. 스토리보드를 여세요

  2. 스토리보드 상에서 Image View를 선택하세요

  3. Image View가 선택된 상태에서, utility area에 있는 Attributes inspector를 열어주세요

  4. Attributes inspector 에서 "Image" 필드의 값을 "defaultPhoto" 로 설정해주세요

Checkpoint: 앱을 실행시켜보세요. default image가 image view에 보입니다

image

Connect the Image View to Code

이제 runtime중에 image view에 들어갈 image를 변경하는 기능을 구현해보겠습니다. 코드 상에서 이러한 이미지 변경을 수행할 수 있습니다. 먼저 Image View를 ViewController.swift파일의 코드로 연결해야합니다.

To connect the image view to the ViewController.swift code

  1. 툴바의 오른쪽에서 Assistant editor를 열어주세요.

    image
  2. 공간이 좁아서 잘 안 보이면 툴바에서 project navigator와 utility area를 숨겨주세요

    image

    물론 캔버스 좌측 하단에서 outline view를 숨기셔도 됩니다.

  3. 스토리보드에서 Image View를 선택해주세요

  4. control을 누른상태에서 Image View를 드래그 해서 오른쪽 Assistant editor에 표시된 ViewController.swfit 파일에 선언된 outlet들 바로 아래로 연결해주세요

    image
  5. 다이얼로그가 나타나면, Name필드에 "photoImageView"라고 입력해주세요

    나머지 옵션들은 아래화면처럼 그대로 두세요

    image
  6. Connect를 클릭하세요

    ViewController.swift 소스코드에는 Image View에 대한 포인터를 저장하는 코드가 생성되며, 스토리보드에는 이 연결(connection)이 자동으로 설정됩니다.

    1. @IBOutlet weak var photoImageView: UIImageView!

이제 코드를 통해 image view에 접근하여 이미지를 변경할 수 있습니다. 그런데 이미지는 언제 바뀔까요? 사용자가 image view영역을 탭하여 이미지를 변경하는 식의 방법이 제공되어야 합니다. 즉, 이미지 뷰에 "탭(Tap)" 이벤트가 발생했을 때 이미지를 변경할 수 있는 액션 메서드(action method)를 정의해야합니다.

아직 언급하진 않았지만, 단순 view(Label, Image View)와 control(Text Field, Button)은 미묘한 차이가 있습니다. control은 특정 사용자 액션에 반응하게끔 설계된 스페셜한 view입니다. 단순 view가 단순히 컨텐츠만 보여주는데 반해, control은 컨텐츠를 수정/변경하는데 사용됩니다. control은 UIControl​의 객체이며, UIControl은 UIView의 서브클래스입니다. 사실 이미 view(label, image view)와 control(text field, button)을 모두 사용하여 작업해왔습니다. 여러분은 이미 view와 control을 잘 사용해오고 있었다는 의미입니다.

Create a Gesture Recognizer

Image View는 control이 아닙니다. 따라서 button 처럼 사용자의 입력에 반응하도록 설계되어있는 객체가 아닙니다. 따라서 사용자가 Image View를 탭했을 때 실행할 액션 메서드를 만들 수 없습니다(Control-drag를 통해 연결 시 나타나는 다이얼로그 상의 connection filed항목에서 "Action"을 선택할 수 없습니다)

하지만 다행스럽게도, 단순 view 또한 control처럼 작동하게 할 수 있는 아주 쉬운 방법이 있습니다. 바로 "Gesture Recognizer" 객체를 view에 추가하는 것입니다. Gesture Recognizer 객체를 view에 추가하면 Image view와 같은 view도 control(button 등) 처럼 사용자의 액션에 반응할 수 있게 됩니다. gesture recoginzer가 적용된 view에 터치가 발생하면, Gesture recognizer는 이 제스쳐가 무엇인지를(tap인지, swipe인지, pinch인지, rotation인지 등) 분석하며,  우리가 정의해둔 제스쳐 타입의 터치로 판명되면, 그에 맞는 액션메서드를 실행시킵니다. 여기서는 Tap이라는 제스쳐가 발생하면, Image View를 변경 시킬 수 있도록 액션메서드를 구현하겠습니다.

먼저 UITapGestureRecognizer 객체인 tap gesture recognizer를 image view에 삽입하여, 사용자가 Image View를 탭했을 때를 인식할 수 있도록 작업해 보겠습니다. 이 작업은 스토리보드에서 쉽게 할 수 있습니다.

To add a tap gesture recognizer to your image view

  1. Object library를 열어주세요(메뉴바에서 Veiw > Utilities > Show Object Library를 선택해도 됩니다)

  2. Object library의 검색창에서 "Tap Gesture Recognizer"를 찾아보세요

  3. "Tap Gesture Recognizer"를 드래그해서 scene의 ​Image View에 삽입해 주세요

    image

    아래 화면처럼 Tap Gesture Recognizer가 scene dock영역에 나타납니다.

    image

Connect the Gesture Recognizer to Code

이제 Image View에 추가한 Tap Gesture Recognizer를 소스 코드의 액션메서드로 연결해보겠습니다.

To connect the gesture recognizer to the ViewController.swift code

  1. scene dock에 있는 gesture recognizer를 control을 누른채 드래그하여, ViewController.swift 소스 상의 "// MARK: Actions" 주석 밑으로 연결하세요.

    image
  2. 다이얼로그 나타나면 Connection 필드의 값을 Action으로 설정합니다.

  3. Name필드의 값은 "selectImageFromPhotoLibrary"로 지정합니다.

  4. Type필드 값은 UITapGestureRecognizer를 선택하세요

    나머지 옵션은 모두 아래 화면처럼 그대로 두세요

    image
  5. Connect를 클릭하세요 

    ViewController.swift 파일에 액션을 정의하기 위한 엑션메서드 코드가 생성됩니다.

    1. @IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) {
    2. }

Create an Image Picker to Respond to User Taps

사용자가 ImageView를 탭하면 어떤 일이 발생해야할까요? 아마도 사진 보관함에서 사진을 선택하거나, 새로운 사진을 찍을 수 있어야 할 것 같습니다. 갑자기 머리가 복잡해지네요. 하지만 정말 다행스럽게도 이 모든 기능을 내장하고 있는 UIImagePickerController라는 클래스가 있습니다. ImagePickerController는 저장된 사진을 불러오거나, 새로운 사진을 찍어 앱에서 사용할 수 있는 UI를 제공합니다. text field의 delegate를 사용했던 것과 마찬가지로, ImagePickerController로 작업을 하기 위해서는 ImagePickerControllerDelegate가 필요합니다. 물론 ImagePickerControllerDelegate가 되어 작업을 위임 받아줄 객체는 ViewController입니다. 

먼저 ViewController는 UIImagePickerControllerDelegate 프로토콜을 채택(adopt)해야합니다. 또한 ViewController는 Image Picker Controller 의 UI를 노출해야하기 때문에 UINavigationControllerDelegate 프로토콜도 채택하여 네비게이션 기능도 구현해야 합니다.(*역자 : 현재 화면에서 다른 화면으로 이동했다가, 다시 돌아오는 것과 같은 기능을 네비게이션이라고 합니다)

To adopt the UIImagePickerControllerDelegate and UINavigationControllerDelegate protocols

  1. 아래 화면과 같이 툴바를 통해 Standard editor로 돌아가세요

    image

    툴바에서 Navigator와 Utility 영역도 보이게 해주세요

  2. project navigator에서 ViewController.swift 파일을 선택해주세요

  3. 현재 ViewController.swift파일의 클래스 선언부는 아래와 같습니다.

    1. class ViewController: UIViewController, UITextFieldDelegate {
  4. UITextFieldDelegate 옆에 콤마(,)를 찍고, UIImagePickerControllerDelegate을 추가하세요

    1. class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate {
  5. 또 다시 콤마(,)를 찍고, UINavigationControllerDelegate도 선언해주세요

    1. class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

이제 아까 선언해둔 selectImageFromPhotoLibrary 액션메서드로 돌아가서 구현부를 완성시켜 보겠습니다.

To implement the selectImageFromPhotoLibrary(_:) action method

  1. ViewController.swift파일에서 selectImageFromPhotoLibrary(_:)메서드를 찾으세요

    아직 구현부를 작성하지 않은 상태입니다.

    1. @IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) {
    2. }
  2. 괄호( { } ) 사이의 메서드 구현부에 아래의 코드를 작성하세요

    1. // Hide the keyboard.
    2. nameTextField.resignFirstResponder()

    text field에 텍스트를 입력하던 중에(키보드가 올라온 상황) image view를 탭했을 때에는 키보드를 내려주는 작업이 필요하기 때문에 작성한 코드입니다. (text filed는 first responder 를 보유하게 되면 키보드가 올라옵니다. first responder 를 반납하면 키보드가 내려가게 됩니다)

  3. A아래 코드를 작성해서 Image Picker Controller를 생성해주세요(참고로 ImagePickerController 또한 ViewController의 서브클래스입니다. 따라서 사용자가 사진보관함에서 사진을 선택할 수 있는 view를 제공합니다. 새로운 view에 진입했다가, 이전 view로 돌아오는 작업이 필요하기 때문에 네비게이션 기능을 구현해야합니다.)

    1. // UIImagePickerController is a view controller that lets a user pick media from their photo library.
    2. let imagePickerController = UIImagePickerController()
  4. 아래의 코드도 추가해주세요

    1. // Only allow photos to be picked, not taken.
    2. imagePickerController.sourceType = .PhotoLibrary

    This line of code sets the image picker controller’s source, or the place where it gets its images. The .PhotoLibrary option uses Simulator’s camera roll. 이 코드는 image picker controller의 소스(사진을 어디서 가져올지)를 설정합니다. ".PhotoLibrary" 옵션은 시뮬레이터의 카메라롤을 이용하겠다는 의미입니다.

    imagePickerController.sourceType의 타입은 UIImagePickerControllerSouceType으로 enumeration입니다. enumeration은 값(value)은 타입이 이미 알려져 있다면, 어디서나 축약형으로 사용이 가능합니다. 따라서 UIImagePickerControllerSourceType.PhotoLibrary 대신 .PhotoLibrary 형식으로 축약형만 사용해도 enumeration의 값을 사용할 수 있습니다.

  5. 아래의 코드를 추가해서 image picker controller의 delegate를 ViewController로 선언해주세요. 즉, ViewController가 ImagePickerControllerDelegate 역할을 수행하게 되며,사용자가 image를 골랐을 때 ViewController에게 메시지가 전달됩니다

    1. // Make sure ViewController is notified when the user picks an image.
    2. imagePickerController.delegate = self
  6. 바로 아래에 다음의 코드도 추가해주세요

    1. presentViewController(imagePickerController, animated: true, completion: nil)

    presentedViewController(_:animated:completion:) 는 ViewController 내부에서 호출되는 메서드입니다. 명시적으로 선언되어 있지 않지만, 이 메서드는 self 객체(ViewController) 상에서 실행됩니다. 이 메서드는 ViewController상에 imageViewController로 정의된 view controller를 나타나게 만듭니다.(현재 화면에 imageViewController화면을 띄운다는 의미) animated 파라미터에 true를 넣으면, imageViewController가 나타날 때 애니메이션이 적용됩니다. completion은 completion handler를 참조하는 파라미터로, 이 메서드가 종료되면 수행할 코드를 의미합니다. 지금은 메서드가 종료되고 수행해야 할 일이 없으므로, completion handler가 없다는 의미로 nil을 넣으면 됩니다.

완성된 selectImageFromPhotoLibrary(_:)메서드는 아래와 같습니다.

  1. @IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) {
  2. // Hide the keyboard.
  3. nameTextField.resignFirstResponder()
  4. // UIImagePickerController is a view controller that lets a user pick media from their photo library.
  5. let imagePickerController = UIImagePickerController()
  6. // Only allow photos to be picked, not taken.
  7. imagePickerController.sourceType = .PhotoLibrary
  8. // Make sure ViewController is notified when the user picks an image.
  9. imagePickerController.delegate = self
  10. presentViewController(imagePickerController, animated: true, completion: nil)
  11. }

imagePickerController가 화면에 나타난 후에는 제어권이 delegate로 넘어갑니다. 사용자가 사진을 선택할 수 있게 하기 위해서는 UIImagePickerControllerDelegate 에 정의된 두개의 delegate method를 구현해야 합니다.

  1. func imagePickerControllerDidCancel(picker: UIImagePickerController)
  2. func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])

첫 번째 메서드인 imagePickerControllerDidCancel(_:)메서드는 사용자가 image picker의 Cancel버튼을 눌렀을 때 호출됩니다. 이 메서드가 호출되면 나타났던 UIImagePickerController가 사라지게 할 수 있습니다. (선택적으로 cleanup 작업도 합니다) 

To implement the imagePickerControllerDidCancel(_:) method

  1. In ViewController.swift, right above the // MARK: Actions section, add the following: ViewController.swift 파일의 "// MARK: Actions"섹션 위에 아래의 주석을 추가하세요

    1. // MARK: UIImagePickerControllerDelegate

    이 주석을 통해 코드를 보기 쉽게 만들 수 있고, 이 섹션이 image picker delegate 메서드를 구현한 부분임을 알 수 있습니다.

  2. 주석 아래에 아래의 메서드를 선언해주세요

    1. func imagePickerControllerDidCancel(picker: UIImagePickerController) {
    2. }
  3. 메서드 구현부에 아래의 코드를 작성하세요

    1. // Dismiss the picker if the user canceled.
    2. dismissViewControllerAnimated(true, completion: nil)

    이 코드는 애니메이션을 주면서 image picker controller가 사라지게 만듭니다.

완성된 imagePickerControllerDidCancel(:) 메서드의 모습은 아래와 같습니다.

  1. func imagePickerControllerDidCancel(picker: UIImagePickerController) {
  2. // Dismiss the picker if the user canceled.
  3. dismissViewControllerAnimated(true, completion: nil)
  4. }

두 번째로 구현해야하는 UIImagePickerControllerDelegate의 메서드는 imagePickerController(:_didFinishPickingMediaWithInfo:)입니다. 이 메서드는 사용자가 사진을 선택할 때 호출됩니다. 이 메서드를 통해 사용자가 picker를 통해 선택한 이미지(들)을 통해 무언가를 해볼 수 있습니다. 우리 앱에서는 선택된 이미지를 imageView 에 노출할 것입니다.

To implement the imagePickerController(_:didFinishPickingMediaWithInfo:) method

  1. imagePickerControllerDidCancel(_:) 메서드 바로 밑에 아래의 메서드를 추가하세요

    1. func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    2. }
  2. 메서드 구현부에 아래와 같이 코드를 작성하세요

    1. // The info dictionary contains multiple representations of the image, and this uses the original.
    2. let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage

    "info" 딕셔너리(dictionary)는 picker에서 선택된 원본이미지와, 편집된 이미지(존재한다면)를 갖고 있습니다. 여기서는 간단하게 만들기 위해 원본이미지를 사용하겠습니다. 위의 코드에서는 이 원본이미지를 selectedImage라는 상수에 저장하고 있습니다.

  3. 아래 코드를 작성해서 outlet으로 선언된 image view에 선택된 이미지를 표시하세요

    1. // Set photoImageView to display the selected image.
    2. photoImageView.image = selectedImage
  4. 아래의 코드를 작성해서 image picker를 사라지게 해주세요

    1. // Dismiss the picker.
    2. dismissViewControllerAnimated(true, completion: nil)

완성한 imagePickerController(_:didFinishPickingMediaWithInfo:)메서드는 아래와 같습니다.  

  1. func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
  2. // The info dictionary contains multiple representations of the image, and this uses the original.
  3. let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
  4. // Set photoImageView to display the selected image.
  5. photoImageView.image = selectedImage
  6. // Dismiss the picker.
  7. dismissViewControllerAnimated(true, completion: nil)
  8. }

Checkpoint: Run your app. You should be able to click the image view to pull up an image picker. You’ll need to click OK on the alert that asks for permission to give the FoodTracker app access to Photos. Then, you can click the Cancel button to dismiss the picker, or open Camera Roll and click an image to select it and set it as the image in the image view. 앱을 실행시켜서 테스를 해보세요. image view를 클릭하면 image picker가 나타납니다. FoodTracker가 Photos에 접근하는 것을 허용하겠냐는 경고창이 뜨면 OK를 눌러주세요. image picker가 나타나면 Cancel 버튼을 눌러서 picker를 제거해보세요. 다시 image view를 누르고 picker를 띄워서 카메라롤을 열고, 이미지를 하나 선택해보세요. 그 사진이 image view의 이미지로 변경됩니다.

image

시뮬레이터의 사진보관함에는 음식 사진이 없습니다. FoodTracker앱을 테스트하기 위한 음식사진을 시뮬레이터에 넣을 수 있습니다. 샘플 이미지가 필요하다면 레슨의 맨 마지박 부분에서 받을 수 있는 프로젝트 파일의 Images/폴더에 있는 것을 사용하세요

To add images to Simulator

  1. 시뮬레이터가 꺼져있는 경우, 시뮬레이터에서 앱을 실행시키세요

  2. 컴퓨터의 파인더에서 옮기고 싶은 사진들을 선택하세요

  3. 그 이미지들을 시뮬레이터르 드래그 앤 드롭 하세요

    image

    시뮬레이터는 추가한 사진을 보여주기 위해 Photos앱을 실행시킵니다.

    image

Checkpoint: 다시 앱을 실행 시키고, image view를 탭해서 image picker가 나타나게 하세요. camera roll을 열고 방금전에 시뮬레이터에 추가한 사진을 선택하세요. 그 사진이 image view에 표시됩니다.

image


댓글