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

[한글 번역_03] Start Developing iOS Apps (Swift) - Building the UI > Build a Basic UI

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

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

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

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

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

감사합니다.




오늘 배울 내용은 UI를 만들어 보는 것입니다. 

실제로 작동하지는 않지만, 앱의 화면을 구성하는 법을 배우게 됩니다.

제 개인적인 생각이지만... 저는 실제 작동을 구현하는 것보다... 그림 그리는게 더 어렵더라구요 ㅠㅠ

하지만 Xcode는 저 같은 사람도 비교적 쉽게 UI를 구성할 수 있게 해줍니다!

자 그럼 시작해볼까요? 

별거 없습니다 ㅋㅋ


아래 Attributes 내용은 iOS에서 Swift로 개발시 참고가 필요한 내용으로 첨부합니다.


/*

// Attributes 내용 첨부 시작


Attribute


Swift에는 선언(Declaration)과 타입(Type)에 추가적인 정보를 제공하기 위해 사용되는 두 종류의 Attributes가 있는데,

클래스나 메서드를 선언할 때 붙이는 Declaration Attribute, 변수의 타입 등에 붙이는 Type Attribute가 바로 그것입니다.

아래와 같이 "@" 표시를 하고, Attribute의 이름과 인자를 뒤에 붙여서 Attribute를 표기하면 됩니다.

@ attribute name
@ attribute name (attribute arguement)

일부 Declaration Attribute의 경우, 해당 선언(declaration)에 추가적인 정보를 제공하기 위해 Attribute에 인자(argument)를 추가합니다. "@Attribute이름(인자)" 형식으로 사용하면 됩니다.

Declaration Attributes

Declaration Attribute 에는 여러 종류가 있으며, 오직 declaration에만 적용할 수 있습니다(*예외 : noreturn의 경우엔 선언(Declaration)과 타입(Type)에 모두 사용 가능) 

@UApplicationMain

"@UIApplicationMain" attribute를 클래스 선언에 적용하면, 이 클래스가 "application delegate"라는 것을 의미하게 됩니다. 이는 UIApplicationMain함수에 delegate클래스의 이름을 넣어 호출하는 것과 동일한 역할을 수행합니다. 

따라서 "@UIApplicationMain" attribute를 사용하지 않는 경우에는 UIApplicationMain함수를 호출하는 main함수가 포함된 main.swift파일이 제공되어야 합니다. 예를 들어 UIApplication의 커스텀 서브클래스를 정의하여 principal class로 사용하는 경우, UIApplicationMain 함수가 호출되어야 합니다.  

iOS프로젝트를 만들면 템플릿으로 생성되는 ApplicationDelegate 클래스에 이 Attribute가 적용되어 있습니다. 



Declaration Attributes Used by Interface Builder

Declaration Attribute 중에는 Interface Builder와 Xcode코드 사이의 싱크를 맞추기 위해 사용되는 "Interface Builder Attribute"라는 것이 있습니다. @IBAction, @IBDesignable, @IBInspectable, @IBOutlet이 바로 Interface Builder Attribute입니다.

@IBOutlet과 @IBInspectable은 클래스의 프로퍼티 선언에 적용되는 attribute이고, @IBAction은 클래스의 메소드 선언에 적용되는 attribute이며, @IBDesingable은 클래스 선언에 사용되는 attribute입니다.

// Attributes 내용 첨부 끝

*/

Build a Basic UI

이번 레슨에서는 FoodTracker앱을 만들기 위해 간단한 UI(User Interface)를 제작해보고, 시뮬레이션을 통해 테스트도 진행해 볼 예정입니다. 이 과정을 통해 여러분은 iOS앱 제작 툴인 Xcode에 상당히 익숙해질 것이며, Xcode에서 사용되는 "프로젝트 구조" 뿐만 아니라, "프로젝트의 각 항목을 찾아보는 방법" 에 대해서도 잘 이해하게 될 것입니다.  레슨의 모든 과정을 모두 마치고 나면 아래와 같이 멋진 여러분의 첫 번째 앱을 만들 수 있게 될 것입니다.

image: ../Art/BBUI_sim_finalUI_2x.png

Learning Objectives

레슨을 모두 마치면 할 수 있게 되는 것들:

  • Xcode에서 프로젝트 생성하기

    Xcode 프로젝트 템플릿에 생성된 주요 파일들의 기능에 대한 이해

    프로젝트의 파일을 열어보는 방법

    시뮬레이터에서 앱을 실행(Run)하는 방법

    스토리보드에 UI엘리먼트들을 추가하고, 이동 시키고, 사이즈를 조절하는 방법

    Attributes inspector를 이용하여 스토리보드에서 UI엘리먼트들의 속성을 편집하는 방법

    Outline view를 이용하여 스토리보드에 있는 UI엘리먼트들을 확인하고 재배치하는 방법

    Preview assistant editor를 이용하여 스토리보드의 UI를 미리 확인하는 방법

    Auto Layout기능을 이용하여 다양한 사이즈의 디바이스에 맞는 UI를 자동으로 설계하는 방법 

Create a New Project

Xcode는 다양한 형식의 앱을 만들기 위해 필요한 기본 템플릿을 제공합니다. 리스트를 나타내기 위한 테이블 뷰, 하단 메뉴를 제공하는 탭바는 물론 게임 앱을 만들기 위한 템플릿까지 기본으로 제공합니다. 이 템플릿에는 소스코드 파일은 물론 interface까지 모두 세팅되어 있습니다. 다양한 템플릿이 있지만 가장 기본이 되는 템플릿은 Simple View Application입니다. 우리도 이 템플릿을 이용하여 첫 번째 앱을 만들어보겠습니다.

To create a new project

새로운 프로젝트 만들기

  1. Xcode를 실행하세요. 아래와 같이 Welcome윈도우가 나타날것입니다.

     

    image: ../Art/BBUI_welcomewindow_2x.png

     

    만약 위와 같이 Welcome윈도우가 나타나지 않는다면, 이전에 프로젝트를 생성하여 이용한 적이 있는 경우일 것입니다. 당황하지 말고 아래의 단계를 진행하세요

  2. Welcome윈도우에서 "Create a new Xcode project"를 클릭하세요( 상단 메뉴바에서 "File > New > Project"를 클릭해도 됩니다). 템플릿을 선택하라는 다이얼로그가 나타날 것입니다.

  3. 왼쪽 섹션에서 "iOS > Application" 을 선택하세요

  4. 오른쪽에 화면이 변경되면, "Single View Appliacation"을 선택하고 오른쪽 밑에 "Next"를 클릭하세요

    image: ../Art/BBUI_singleviewapp_template_2x.png
  5. 새로운 다이얼로그가 나타나면 아래와 동일하게 값들을 입력해주세요

    • Product Name: FoodTracker

      Product Name은 프로젝트 및 앱의 이름으로 사용됩니다.

    • Organization Name: 여러분이 속한 조직(회사 등)의 이름을 입력하세요. 빈 칸으로 두셔도 무방합니다.

    • Organization Identifier: 여러분이 만든 앱임을 확인할 수 있는 식별자를 입력하세요. 딱히 필요 없으면 "com.example"을 입력하세요

    • Bundle Identifier: 이 부분은 여러분이 입력한 Product Name과 Organization identifier에 의해 자동으로 생성됩니다.

    • Language: Swift

    • Devices: Universal

      Universal 로 설정하면 아이폰과 아이패드 모두에서 작동합니다.

    • Use Core Data: Unselected.

    • Include Unit Tests: Selected.

    • Include UI Tests: Unselected.

  6. "Next"를 클릭하세요

  7. 다음 다이얼로그가 나타나면 프로젝트를 저장할 경로를 설정하고 "Create"를 클릭하세요

    아래 화면과 같이 Xcode의 workspace window에 새로운 프로젝트가 나타납니다.

     

     

     

    image: ../Art/BBUI_workspacewindow_2x.png

     

workspace윈도우에  "No code signing identities found"라는 경고 메시지가 나타날 수 있습니다. iOS개발자로 등록되지 않아서 나타나는 경고인데, 우리의 레슨에서는 필요 없는 내용이므로 신경 쓰지 않아도 됩니다.


Get Familiar with Xcode

Xcode는 여러분이 앱을 만들기 위해 필요한 모든것을 제공합니다. 앱을 만들기 위해 필요한 파일 관리 기능, 코드와 인터페이스를 작성하기 위한 편집 기능, 앱을 빌드하고 실행해볼 수 있는 기능뿐만 아니라, 강력한 통합 디버거도 제공합니다.

잠깐 짬을 내서 Xcode를 한번 살펴보세요. 레슨 과정을 거치면서 각 부분에 대해 자세히 설명해 드릴 것이니 너무 겁먹지 않으셔도 됩니다.

image: ../Art/BBUI_workspacewindow_callouts_2x.png

Run Simulator

Xcode가 제공하는 템플릿을 통해 프로젝트를 생성했기 때문에, 기본적인 내용은 모두 자동으로 세팅이 되어있습니다. 따라서 아무런 코드도 작성하지 않았지만, 별도 작업 없이도 앱을 빌드(build)하고 실행(Run)해볼 수 있습니다.

앱을 빌드하고 실행해보기 위해서는 Xcode에서 제공하는 시뮬레이터(Simulator)앱을 이용하면 됩니다. 시뮬레이터를 이용하면 실제 디바이스에서 앱이 어떻게 보이고, 어떻게 작동되는지를 테스트해볼 수 있습니다.

시뮬레이터는 다양한 사이즈/버전의 아이폰 및 아이패드를 옵션으로 제공합니다. 우리는 iPhone6 옵션을 사용하도록 하겠습니다.

To run your app in Simulator

  1. 아래 화면처럼 Scheme메뉴를 클릭하고 "iPhone6"을 선택해주세요

    Schem 팝업 메뉴를 클릭하면 앱을 빌드하고 실행시킬 시뮬레이터의 옵션을 선택할 수 있습니다. 

    image: ../Art/BBUI_schememenu_2x.png
  2. 툴바의 가장 왼쪽에 있는 "Run"버튼을 클릭해주세요image: ../Art/BBUI_toolbar_2x.png


    최상단의 메뉴바에서 "Product > Run" 을 클릭해도 동일한 기능을 수행합니다. (단축키 : Command-R)

    만약 앱을 빌드하고 실행시키는 것이 처음이라면 개발자모드(developer mode)를 활성화 시킬 것인지를 묻는 팝업창이 나타날 것입니다. 개발자 모드를 선택(Enable)하면 패스워드 입력이 필요한 일부 디버깅 기능을 사용할 때 매번 비밀번호를 입력하지 않아도 됩니다.

    image: ../Art/BBUI_developermode_2x.png

    만약 개발자 모드를 비활성화(Don't Enable) 한다면 특정 디버깅 기능 접근 시, 매번 비밀번호를 입력해야합니다. 우리 레슨에서는 개발자 모드를 활성화(Enable)하고 진행하겠습니다.

  3. 툴바의 중앙에 있는 "activity viewer" 영역에 빌드 과정에 대한 상태가 표시됩니다.

프로젝트 빌드 과정이 끝나면 자동으로 시뮬레이터가 구동되고 앱이 실행됩니다. 지금 나타나는 시뮬레이터 화면은 방금 전에 선택했던 iPhone6 용 시뮬레이터입니다. 앱이 실행되면, 아래 화면과 같이 앱의 이름(FoodTracker)을 보여주는 시작화면(Launch Screen)이 나타날 것입니다.

시작화면(Launch Screen)이 사라지고 나면, 아래의 화면이 나타납니다


image: ../Art/BBUI_sim_blank_2x.png

Simple View Application 템플릿은 위와 같이 비어있는 화면 하나를 보여주는 템플릿입니다. 물론 다른 템플릿들은 이보다는 좀더 복잡한 화면과 기능을 제공합니다. 따라서 여러분이 만들고자 하는 앱의 용도에 맞는 템플릿을 선택하여 것이 중요하며, 공부를 위해 각 템플릿으로 프로젝트를 만들어보고 실행해보는 것도 많은 도움이 될 것입니다.

시뮬레이터의 메뉴바에서 "Simulator > Quit Simulator"를 클릭하거나, 단축키로 "Command-Q"를 눌러서 시뮬레이터를 종료하세요

Review the Source Code

Single View Application 템플릿은 앱의 환경 설정을 위한 기본 소스 코드 파일을 자동으로 생성합니다. 이 중에서 AppDelegate.swift파일을 먼저 살펴보도록 하겠습니다.

To look at the AppDelegate.swift source file

  1. 아래 화면처럼 Xcode의 왼쪽 navigator 영역에서 "project navigator"를 선택해주세요. 

    만약 project navigator가 보이지 않는다면, 상단 메뉴바에서 "Veiw > Navigators > Show Project Navigator"를 클릭해주세요

    image: ../Art/BBUI_projectnavigator_2x.png
  2. FoodTrack폴더를 펼쳐주세요(왼쪽에 삼각형을 누르시면 됩니다)

  3. AppDelegate.swift파일을 선택하세요

    오른쪽의 main editor영역에 선택한 파일의 소스 코드가 나타납니다.

    image

    파일을 더블클릭하면 새창으로 나타나니 참고하시기 바랍니다.

The App Delegate Source File

AppDelegate.swift 소스파일은 두개의 주요 기능을 갖습니다.

  • AppDelegate.swift 소스코드는 앱의 시작점(entry point)를 생성하고, 앱으로 들어오는 이벤트를 처리하기 위한 run roop를 만드는 역할을 합니다. 소스코드 상에서 실제로 이 작업을 수행하는 것은 맨위에 선언되어 있는 @UIApplicationMain attribute입니다. @UIApplicationMain attribute가 application객체와 app delegate객체를 생성하여 위와 같은 작업을 합니다.

    application은 앱의 객체로서, app delegate와의 통신을 통해 앱의 상태변화를 감지하여 앱의 생애주기(life cycle)을 관리합니다.

    app delegate 또한 앱의 객체로서, 구체적으로는 AppDelegate클래스의 인스턴스입니다. app delegate는 window 객체를 생성하여 컨텐츠를 그리고, 앱의 상태 변화에 반응하게 합니다. 실제로 우리가 앱을 컨트롤 하기 위한 작업을 코딩하는 영역이기도 합니다. (*역자 : 앱의 상태 변화가 발생하면 application객체가 이를 감지하여, app delegate에 선언되어 있는 생애주기 메서드를 호출하여 실행합니다. 이러한 application객체 및 app delegate객체를 생성하는 역할을 @UIApplicationMain속성이 수행합니다.)

    (*run loop : 작업을 할당하고 앱에 들어오는 이벤트를 반복해서 처리하는 루프(event processing loop))

AppDelgate클래스는 단 하나의 프로퍼티를 갖고 있는데, 바로 UIWindow 객체인 window입니다. 이 window프로퍼티를 통해 app delegate는 컨텐츠를 그릴 수 있게 되고, 각종 변화에 대해서도 반응할 수 있게 됩니다. 참고로 window프로퍼티는 optional로 선언되어 있기 때문에 때에 따라 값이 없을 수도 있습니다.(nil) 

  1. var window: UIWindow?

AppDelegate클래스에는 아주 중요한 (템플릿)메서드들이 선언되어 있습니다. 바로 이 메서드들을 통해 application객체가 app delegate객체와 통신을 하여 앱의 상태 변화에 반응할 수 있게 됩니다.

  1. func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
  2. func applicationWillResignActive(application: UIApplication)
  3. func applicationDidEnterBackground(application: UIApplication)
  4. func applicationWillEnterForeground(application: UIApplication)
  5. func applicationDidBecomeActive(application: UIApplication)
  6. func applicationWillTerminate(application: UIApplication)

앱을 켜거나, 홈버튼을 눌러 끄거나, 완전히 종료시켜버리는 등 앱의 상태(state) 변화가 발생할 때, application 객체는 상황에 맞는 app delegate의 메서드를 호출하여 적절한 처리를 하게 됩니다. 물론 앱의 상태 변화 시, application객체가 자동으로 해당 메서드를 호출하므로 우리가 직접 메서드를 호출하는 코드를 작성할 필요는 없습니다. 

이 메서드들에는 디폴트 작동방식(default behavior)이 정의되어 있습니다. 즉, AppDelegate 클래스에서 이 메서들을 삭제하거나 구현부를 비워두어도, 앱의 상태변화에 따라 이 메서드들이 자동으로 호출되어 디폴트 작동방식 내용이 실행됩니다. 앱의 상태변화가 있을 때 해야할 작업들이 있다면 이 메서드들에 코드를 작성하면 됩니다. 이번 레슨에서는 별도로 app delegate 코드를 작성하지는 않겠습니다.

The View Controller Source File

Single View Application 템플릿은 또하나의 소스코드 파일을 생성하는데, 바로 ViewController.swift입니다. 프로젝트 네비게이터에서 ViewController.swift파일을 선택해주세요

image

ViewController는 UIViewController 를 상속받은 커스텀 클래스이기 때문에, UIViewController 클래스의 정의된 모든 것을 상속받습니다. 상속받은 내용을 커스터마이징 하기 위해서는 오버라이드를 해주시면 됩니다. 즉, viewDidLoad()와 didReceiveMemoryWarning()메서드를 오버라이드하여 사용하면 됩니다. 하지만 우리의 레슨에서는 didReceiveMemoryWarning()메서드는 사용할 일이 없으므로 그냥 삭제하셔도 됩니다. 

ViewController.swift 파일의 모습은 현재 아래와 같습니다.

  1. import UIKit
  2. class ViewController: UIViewController {
  3. override func viewDidLoad() {
  4. super.viewDidLoad()
  5. // Do any additional setup after loading the view, typically from a nib.
  6. }
  7. }

잠시 후에 이 소스코드 파일에 직접 코딩을 하도록 하겠습니다.

Open Your Storyboard

이제 앱의 스토리보드(storyboard)에서 작업하기 위한 모든 준비가 완료되었습니다. 스토리보드는 앱 UI(User Interface)의 시각적 표현(visual representation)으로, 컨텐츠를 보여주는 스크린 뿐만 아니라 스크린 간의 전환까지 표시됩니다. 스토리보드를 이용하여 앱의 레이아웃을 구성하면 앱의 실제 모습을 보면서 작업할 수 있습니다. 

To open your storyboard

  • 프로젝트 네비게이터에서 Main.storyboard파일을 선택하면 오른쪽의 Interface Buiilder에 스토리 보드가 표시됩니다. 스토리보드의 배경을 canvas라고 하는데, 바로 이 canvas에 ​UIElement들을 추가하고 배치할 수 있습니다.

아래 화면이 스토리보드의 모습입니다.

image

현재는 스토리보드는 딱 하나의 scene(앱의 컨텐츠를 보여주는 스크린)만 갖고 있습니다. 왼쪽에 있는 화살표는 이 scene이 앱의 첫 화면임을 표시하는 storyboard entry point입니다. 현재 scene은 하나의 view를 갖고 있으며, view contoller에 의해 관리됩니다. view와 viewController의 역할에 대해서는 나중에 자세히 알아보겠습니다.

iPhone6 시뮬레이터에서 앱을 실행시켰을 때의 화면과 스토리보드에서의 scene 화면의 비율이 다르게 보인다는 것을 눈치채셨나요? 이는 canvas에 표현되는 scene의 경우, 모든 디바이스 사이즈와 좌우(portrait/landscape)화면방향까지 고려하여 일반화(generalize)시킨 형태의 화면이기 때문입니다. 이렇게 일반화된 scene을 이용하여 적응형 인터페이스(adaptive interface)를 생성하면, 디바이스의 사이즈와 화면방향에 맞게 자동으로 인터페이스가 조정 적용됩니다.

Build the Basic UI

이제 드디어 기본적인 인터페이스를 만들어볼 시간입니다. scene상에 UI를 구성하여 FoodTracker앱에 새로운 음식을 추가해봅시다.

Xcode의 Object Library에 있는 object들을 스토리보드에 추가하고, 적절하게 배치하여 UI를 구성하면 됩니다. Object Library 가 제공하는 객체 들은 다음과 같이 세 종류로 나누어 볼 수 있습니다.

1. View : Button, Label 등 UI를 구성하는 엘리먼트 (눈에 보임)

2. ViewController : View를 컨트롤하고 관리하는 요소(안 보임)

3. Gesture Recognizer : 사용자의 터치를 다루는 요소(안 보임)

UI 상에 보이는 button, label과 같은 엘리먼트들을 View라고 합니다. 이 View들을 적절하게 배치하여 UI를 만들고, 이 View를 통해 컨텐츠를 보여주는 작업을 하면 됩니다. 각각의 View 객체는 컨텐츠를 보여주거나, 사용자의 입력에 반응할 수 있는 "자체(built-in) 기능"이 내장되어 있습니다.

iOS에서의 모든 view는 UIView의 객체이거나, UIView클래스를 상속받은 객체입니다.  UIView의 subclass들은 각각의 용도에 특화된 기능과 모양을 갖고 있습니다. 예를 들어, textField는 UIView의 서브클래스인 UITextField의 객체이며, 사용자가 글자를 입력할 수 있는 기능과 모양을 갖고있습니다.

To add a text field to your scene

  1. Object library를 열어주세요

    오른쪽 utility영역의 아래에 있는 Object libary를 열어보세요. library selector bar에서 세번째 버튼을 누르면 됩니다.(상단 메뉴바에서 "View>Utilites>ShowObjectLibrary"를 선택해도 됩니다)

    image

    각 객체의 이름, 설명, 모양이 나타납니다.

  2. 아래쪽의 검색창(filter filed)에서 "text field"를 검색해보세요

  3. TextField객체를 드래그해서 scene에 놓아보세요

    image

    확대가 필요하면 메뉴바에서 "Editor>Canvas>Zoom"을 클릭하세요

  4. textfield를 드래그해서 아래 화면과 같이 scene의 상단에 배치하고 왼쪽 경계선에 맞춰주세요.

    image

    푸른색 점선으로 나타나는 레아아웃 가이드(Layout Guide)가 적절하게 배치할 수 있도록 도와줍니다. 레이아웃 가이드는 객체를 드래그 하거나 크기 조정을 할때 나타납니다.

  5. textfield 객체를 한번 클릭하면 사이즈를 조정할 수 있는 작은 사각형 형태의 리사이즈 핸들(resize handle)이 나타납니다.  리사이즈 핸들을 드래그하여 아래 화면과 같이 사이즈를 조정해보세요

    image
  6. textfield의 좌우 리사이즈 핸들을 드래그해서 왼쪽, 오른쪽 경계에 맞추어 중앙정렬이 되도록 사이즈를 조정해보세요

    image

textfiled에 간단한 안내메시지(placeholder)를 추가하여, 디폴트 텍스트가 노출되게 할 수 있습니다.

To configure the text field’s placeholder text

  1. textField가 선택된 상태에서, utility area의 Attributes inspector를 열어주세요

    오른쪽 utility영역 상단의 inspector selector bar의 4번째 항목인 Attribute inspector를 선택하면 됩니다. Attribute inspector에서는 선택된 객체의 속성을 설정할 수 있습니다.  

    image
  2. Attribute inspector에서 Placeholder 필드를 찾아 "Enter meal name"이라고 타이핑하세요

  3. 타이핑을 다하고 엔터키를 누르면 화면에 반영됩니다. text field에 입력한 내용이 표시되면 정상입니다.

여기까지 완료 했다면 scene의 모습은 아래와 같을 것입니다.

image

textField 속성에는 textField를 탭했을 때 나오는 키보드에 대한 설정도 있습니다.

To configure the text field’s keyboard

  1. Make sure the text field is still selected. textField를 선택해주세요

  2. Attribute inspector에서 "Return Key"필드의 설정값을 "Done"으로 선택하세요

    이렇게하면 키보드 상에 노출되는 Return key의 텍스트가 "Done"으로 변경됩니다.

  3. Attribute inspector에서 "Auto-enable Return Key" 항목을 체크하세요

    이렇게 하면, textfield에 아무것도 입력하지 않은 상태에서는 Done 키를 비활성화 시켜 누를 수 없게 합니다.

이번에는 scene에 UILabel객체인 label을 추가해보겠습니다. label은 상호작용적인(Interaction) 측면은 없으며, 단순히 텍스트를 표시하는 역할만 하는 객체입니다. 추후에 UI 엘리먼트들 간의 상호작용 가능을 이해하기 위해 textField에 입력한 텍스트를 Label에 표시하는 작업을 해볼 예정입니다. 이를 통해 사용자의 입력을 받아 적절히 처리하는 방식에 대해서도 잘 이해할 수 있게 됩니다.

To add a label to your scene

  1. Object library의 검색창에서 label을 검색해보세요

  2. Label 객체를 드래그에서 scene에 배치하세요

  3. Label을 드래그해서 textfield위에 배치하고, 완쪽 경계선에 맞춰보세요

    아래 화면과 같이 작업하시면 됩니다.

    image
  4. Label을 더블클릭하면 텍스트를 입력할 수 있는 모드로 변경되는데, "Meal Name"이라고 입력해주세요

  5. 리턴키를 누르면 Label에 입력한 텍스트가 표시됩니다.

작업을 완료한 scene의 모습은 아래와 같습니다.

image

이제 UIButton객체인 button을 추가하겠습니다. button은 사용자와 상호작용이 가능한 객체입니다. 버튼을 누르면 소스상에 정의해둔 액션(action)이 실행되는 식으로 작동을 하게 됩니다. 버튼을 누르면 Label의 텍스트를 우리가 정의해둔 디폴트 값으로 변경하는 액션을 만드는 작업도 해볼 예정입니다. 

To add a button to your scene

  1. Object library의 검색창(filter field)에서 button 객체를 찾아보세요

  2. Button객체를 드래그해서 scene에 배치하세요

  3. button을 드래그해서 아래 화면과 같이 textfield 바로 아래에 배치하고, scene의 왼쪽 경계에 맞춰주세요

    image
  4. button 객체도 더블클릭하면 텍스트를 입력할 수 있게 되며, "Set Default Label Text"라고 입력하세요

  5. 마찬가지로 리턴키를 눌러 입력한 텍스트가 버튼에 표시되게 해주세요

완성된 scene의 모습은 아래와 같습니다.

image

outline view를 통해 scene에 추가한 UI엘리먼트들이 실제로 어떤 계층 구조로 배치되어 있는지 확인할 수 있습니다.

To view the outline view

  1. 스토리보드의 왼쪽 하단에서 outline 토글 버튼을 찾아보세요

    image
  2. outline view가 숨겨져있는 상태라면, 토글 버튼을 눌러서 펼쳐주세요

    토글을 클릭할때마다 outline view가 펼쳐지고, 닫힙니다.

outline view를 통해서 지금까지 추가한 객체들의 계층 구조를 볼 수 있습니다. 그런데 왜 우리가 추가한 textfield, label, button들이 우리가 만든적도없는 View안에 들어가 있는 것일까요?

view 객체들은 자기 자신을 스크린상에 표시하고 사용자의 입력에 반응하기도 하지만, 다른 view객체를 보함하는 컨테이너(container)역할도 수행합니다. 이를 뷰 계층구조(view hierarchy)라고 합니다. 다른 뷰를 포함하는 뷰를 슈퍼뷰(superview)라고 하며, 슈퍼뷰에 포함된 뷰를 서브뷰(subview)라고 합니다. 이러한 뷰 계층구조 상에서 뷰들은 서로 상대적으로 레이아웃을 구성하게 됩니다. 

image

일반적으로 각 scene은 자신만의 뷰 계층구조를 갖고 있으며, 뷰 계층구조의 최상위에 위치하는 것을 컨텐츠 뷰(content view)라고 합니다. 여기서는 ViewController에 포함되어 있는 View가 컨텐츠 뷰가 됩니다. textField, Label, Button와 같은 컨텐츠 들을 컨텐츠 뷰에 배치한다고 생각해도 될 것 같습니다. 그리고 우리가 scene 상에 추가하는 모든 view들은 이 컨텐츠뷰의 서브뷰가 됩니다.(물론 서브뷰 또한 자신의 서브뷰를 갖을 수 있습니다)

Preview Your Interface

Assistant editor 를 사용하면, 작업한 대로 앱의 레이아웃이 잘 나타나는지 체크해 볼 수 있습니다.

To preview your interface

  1. Xcode 툴바의 오른쪽에 있는 "Assistant editor"를 클릭하세요 

    image
  2. 화면이 작아서 잘 보이지 않는다면, 툴바에서 Navigator 토글과 Utilities 토글을 클릭해서 Editor영역을 크게 만들 수 있습니다.

    image

    outline view를 숨겨두는 것도 좋습니다.

  3. Assistant editor 상단의 editor selector bar에서 "Automatic"을 "Preview>Main.storyboard(Preview)로 바꿔주세요.

    image

Assistant editor 영역을 보면 textfiled가 오른쪽 화면을 삐져나가 있는 것을 확인할 수 있습니다. 스토리보드에서 분명히 잘 배치했던 것 같은데, 어째서 preview에서는 이렇게 보이는 걸까요?

image

처음에 언급했듯이, 우리는 지금 다양한 사이즈의 아이폰/아이패드에 적용하기 위한 "adaptive interface"를 설계하고 있습니다. 즉, 우리가 스토리보드에서 보고 있는 scene화면은 정확히 iPhone화면이 아니라, 모든 단말의 모든 사이즈의 화면을 일반화 시킨 화면이라는 것입니다. 따라서 다양한 사이즈의 화면에 적용될 interface를 정의해야합니다. 예를 들어  위의 text field는 iPhone에서는 작은 화면에 맞게 줄어들어야하고, iPad에서는 큰 화면에 맞게 늘어나야합니다. "Auto Layout"이라는 기능을 이용하면 쉽게 이런 작업을 할 수 있습니다.

Adopt Auto Layout

Auto Layout은 adaptive layout을 설계하는데 도움을 주는 아주 강력한 레이아웃 엔진이라고 할 수 있습니다. scene상에서 각 엘리먼트들을 어디에 배치하고 싶은지를 정의하기만 하면, Auto Layout 엔진이 자동으로 계산하여 엘리먼트들이 다양한 디바이스 상에서 실제로 어떻게 배치될 것인지를 결정합니다. 우리가 해야할 일은 컨스트레인트(constraints)라는 것을 이용하여 엘리먼트의 상대적 위치, 사이즈, 우선순위 등을 정의하는 것 뿐입니다. 실제로 공간을 계산하여 배치하는 일은 Auto Layout 엔진이 알아서 해줍니다.

Auto Layout과 함께 조합하여 레아이웃 작업을 할 수 있는 아주 좋은 방법이 하나 더 있습니다. 바로 UIStackView의 객체인 stack view입니다. stack view는 view들을 행/열등으로 조합하여 배치할 수 있게 하는 기능을 제공합니다. stack view는 Auto Layout과 조합하여 쓸때 강력한 효과를 발휘하며, 디바이스의 사이즈, 방향 전환 등에 따라 다양하게 변화하는 인터페이스를 쉽게 만들 수 있게 해줍니다. 

사용법은 간단합니다. 먼저 scene상에 배치되어 있는 UI엘리먼트들을 stack view로 감싸줍니다. 그 다음 이 stack view에 컨스트레인트(constraints)를 추가하여, 다양항 상황에 따라 적절하게 UI가 표시되도록 만들어 주면 됩니다.(*역자 : stack view기능은 Xcode7 부터 지원되는 기능이며, 레슨 진행에 반드시 필요한 기능은 아닙니다)

To add Auto Layout constraints to the meal scene

  1. 툴바에서 Standard Editor가 나타나게 해주세요

    image

    툴바에서 Navigator와 Utilities도 열어주세요

  2. Shift키를 누른 상태에서 textfield, label, button을 클릭해서 동시에 선택이 되도록 하세요

    image
  3. Canvas의 우측 하단에서 Stack버튼을 클릭하세요(메뉴바에서 Editor > Embed in > Stack View 를 클릭해도 됩니다.) 

    image

    선택해둔 UI엘리먼트들이 stack view로 감싸집니다. Xcode가 자동으로 레이아웃을 분석하여, 엘리먼트들이 수평이 아닌 수직으로 배치되어 감싸지도록 stack을 조정합니다.

    image
  4. outline view에서 Stack View를 선택하세요

    image
  5. Attribute inspector 로 가서 Spacing field에 12를 입력하고 리턴키를 누르세요를 치세요.

    stack view가 수직으로 늘어나고, 안에 있는 UI엘리먼트들의 수직 간격도 벌어지게 됩니다.

    image
  6. Canvas 우측 하단에서 Pin메뉴를 클릭하세요

    image
  7. "Spacing to nearest neighbor" 항목 위에서 수평(좌/우), 수직(상단) 컨스트레인트(constraints)를 클릭하세요. 클릭한 부문만 붉은색으로 표시됩니다.

    image

    이 컨스트레인트(constraints) 들은 가장 가까이에 있는 왼쪽, 오른쪽, 윗쪽 이웃과의 거리를 설정합니다. 가장 가까운 이웃이란, 선택된 엘리먼트에서 가장 가까이에 있는 UI엘리먼트를 의미합니다. 즉, 가장 가까이에 있는 superview, peer view(같은 계층의 뷰)를 의미하며, 가까이에 이런 view들이 없다면 margin이 될수도 있습니다. 여기서는 "Constraints to margins"항목이 체크되어 있기 때문에, 우리가 만든 stack view의 superview인 View의 마진으로 부터 상단, 좌, 우에 정해진 거리를 두고 위치하게 됩니다.

  8. 좌측, 우측에 0을 입력하고, 상단에는 60을 입력하여 컨스트레인트 거리를 설정합니다.

  9. 하단의 Update Frames메뉴에서 "items of New Constraints"를 선택하세요

    아래 화면과 같이 작업하면 됩니다.

    image
  10. Pin 메뉴의 맨 밑에서 "Add 3 Constraints" 버튼을 눌러주세요

    image

모두 완료하고 나면 아래 화면처럼 표시됩니다.

image

그런데 textfield의 사이즈가 우리가 원래 설정한 것처럼 길지 않습니다. 이걸 지금부터 고쳐보겠습니다.

To adjust the text field width in the meal scene

  1. 스토리보드의 scene에서 textfield를 선택해주세요

  2. 캔버스 우측하단에 있는 Pin메뉴를 다시 선택해주세요

    image
  3. "Spacing to nearest neighbor" 바로 위에서 좌,우 컨스트레인트를 클릭해서 빨간색이 되게 해주세요

  4. 좌우 수치 입력란에 0이라고 입력해주세요

  5. 하단의 "Update Frames"메뉴에서 "items of New Contraints"를 선택해주세요

    Pin메뉴 내용이 아래 화면과 같다면 정상입니다.

    image
  6. 맨 아래의 "Add 2 Contraints" 버튼을 클릭해주세요

    image
  7. text field가 선택된 상태에서 우측의 Utilites영역에서 Size inspector(image를 열어주세요. 

    Size inspector에서는 스토리보드에 있는 객체들의 크기와 위치를 설정할 수 있습니다.

    image
  8. intrinsic Size 필드에서 "Placeholder"를 선택해주세요

    text field의 사이즈는 컨텐츠를 표시하기 위해 필요한 최소한의 사이즈(intrinsic content size)에 맞게 설정됩니다. 하지만 임의의 기본 사이즈(placeholder intrinsic content size)를 설정할 수도 있습니다. intrinsic size 항목을 Placeholder로 설정하면 사용자가 더 긴 텍스트를 입력해도 잘리지 않고 잘 표시됩니다.

모든 것을 완료한 스토리보드 scene의  모습은 아래와 같습니다.

image

Checkpoint: 시뮬레이터에서 앱을 실행시켜보세요. 이번에는 text field가 화면 오른쪽으로 뚫고 나가지 않을 것입니다. text filed 영역을 터치하면 키보드가 나타납니다. 화면 방향을 돌리거나, 다른 디바이스에서 동작시키면 text field가 화면에 맞게 줄어들기도 하고, 늘어나기도 할 것입니다. 현재는 가로모드(landscape orientation)에서 상단의 status bar가 나타나지 않는다는 점을 기억해 두시기 바랍니다.

image

만약 제대로 작동되지 않는다면, "Auto Layout" 디버깅 기능을 사용할 수 있습니다. canvas의 우측 하단, Pin메뉴 오른쪽에 있는 "Resolve Auto Layout" 버튼을 눌러서 "Reset to Suggested Contraints" 를 선택하세요. Xcode가 자동으로 인터페이스에 적절한 constraints 를 설정해 줄 것입니다. 아니면 "Remove All Constraints" 를 눌러서 모든 constraints를 제거하고, 처음부터 다시 해보시기 바랍니다.

image

현재까지 작업한 scene에서 할 수 있는 것은 많지 않지만, 기본적인 인터페이스가 갖추어졌습니다. 이렇게 확장가능하면서도 제대로된 레이아웃을 갖추는 것은 앱을 만드는 작업의 가장 기본이 되는 내용입니다.


댓글