Navigation Interface

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


iOS에서 내비게이션 인터페이스는 주로 계층적 구조의 화면전환을 위해 사용되는 드릴 다운 인터페이스(drill-down interface) 이다. 드릴 다운 인터페이스란 아래 그림과 같이 각 선택할 수 있는 항목에 대한 세부항목이 존재하는 인터페이스를 의미한다. 내비게이션 인터페이스는 내비게이션 컨트롤러를 통해 구현 한다.

정보의 흐름, 깊이를 가진다.

내비게이션 컨트롤러

내비게이션 컨트롤러는 컨테이너 뷰 컨트롤러로써(container view controller) 내비게이션 스택(navigation stack)을 사용하여 다른 뷰 컨트롤러를 관리한다. 여기서 내비게이션 스택에 담겨서 콘텐츠를 보여주게 되는 뷰 컨트롤러들을 컨텐트 뷰 컨트롤러(content view controller) 라고 한다.

내비게이션 컨트롤러는 두 개의 뷰를 화면에 표시한다.

  1. 하나는 내비게이션 스택뷰에 포함된 최상위 컨텐트 뷰 컨트롤러의 콘텐츠를 나타내는 뷰
  2. 나머지는 내비게이션 컨트롤러가 직접 관리하는 뷰(내비게이션바 또는 툴바)

추가로 내비게이션 인터페이스의 변화에 따른 특정 액션을 동작하도록 하기 위해 내비게이션 델리게이트 객체 를 사용할 수 있다.

내비게이션 스택이란?

내비게이션 컨트롤러에 의해 관리되는 내비게이션 스택(Navigation stack)은 뷰 컨트롤러를 담을 수 있는 배열 과도 같다. 내비게이션 스택에 가장 하위에 있는(가장 먼저 스택에 추가된) 뷰 컨트롤러는 내비게이션 컨트롤러의 루트 뷰 컨트롤러(root view controller) 가 된다. 루트 뷰 컨트롤러는 내비게이션 스택에서 팝(pop)되지 않는다. 내비게이션 스택의 가장 상위에 있는(가장 마지막에 푸시(push) 된) 뷰 컨트롤러는 최상위 뷰 컨트롤러로 화면에 보이게 된다.

이름에서도 알 수 있듯이 내비게이션 스택은 푸시(push)/팝(pop)을 통하여 아이템(뷰 컨트롤러)을 관리한다. 새로운 뷰 컨트롤러를 내비게이션 스택에 푸시(push)하거나 내비게이션 스택에 있는 뷰 컨트롤러를 삭제하기 위해 팝(pop)을 사용하며, 내비게이션 스택에 푸시(push) 된 각 뷰 컨트롤러들은 애플리케이션에 자신이 가지고 있는 뷰 계층 구조를 통해 콘텐츠를 표시하게 된다.

내비게이션 스택에서의 화면이동

UINavigationController 클래스의 메서드 또는 세그(segue)를 사용하여 내비게이션 스택의 뷰 컨트롤러를 추가/삭제할 수 있다. 또한 애플리케이션 실행 중 사용자가 내비게이션 인터페이스의 뒤로가기(back) 버튼을 사용하거나 화면의 왼쪽 가장자리를 스와이프(swipe)하여 스택에 있는 최상위 뷰 컨트롤러를 삭제하고 그 아래에 가려져 있던 뷰 컨트롤러의 콘텐츠를 보여줄 수도 있다. (세그(segue)는 스토리보드에서 한 화면에서 다른 화면으로의 전환을 의미한다. 세그도 내부적으로 UINavigationController 클래스의 메서드를 사용)

이해를 돕기 위한 간단한 예를 통해 내비게이션 스택의 상태에 따라 어떻게 화면이 이동하는지 보자.


내비게이션 스택의 푸시(push)

내비게이션 스택에 새로운 뷰 컨트롤러가 푸시 될 때 UIViewController 인스턴스가 생성되고 내비게이션 스택에 추가 된다.

1.가장 먼저 내비게이션 스택에 루트 뷰 컨트롤러만 들어가 있는 초기상태이다 (내비게이션 컨트롤러를 생성할 때 반드시 루트 뷰 컨트롤러가 설정되어 있어야 한다)

2.’뷰 컨트롤러1로 이동’이라는 버튼을 통해서 내비게이션 스택에 뷰 컨트롤러1을 푸시(push)!
뷰 컨트롤러1의 인스턴스가 생성되고 내비게이션 스택에 추가됨과 동시에 뷰 컨트롤러1이 최상위 뷰 컨트롤러로써 화면에 보이게 된다.

3.’뷰 컨트롤러2로 이동’이라는 버튼을 통해서 내비게이션 스택에 뷰 컨트롤러2도 푸시한다!
뷰 컨트롤러2의 인스턴스가 생성되고 내비게이션 스택에 추가되며 뷰 컨트롤러2가 최상위 뷰 컨트롤러로써 화면에 보이게 된다. 여기서 주목할 점은 새로운 뷰 컨트롤러가 추가될 때도 아래에 있는 뷰 컨트롤러들이(인스턴스) 삭제되지 않고 유지 되고 있다는 점이다.

내비게이션 스택의 팝(pop)

내비게이션 스택에 존재하는 뷰 컨트롤러가 팝 될 때 생성되었던 UIViewController의 인스턴스는 다른 곳에서 참조되고 있지 않다면 메모리에서 해제되고, 내비게이션 스택에서 삭제된다.

1.푸시 예제의 마지막 상태에서 상단 내비게이션바에 있는 뷰 컨트롤러1을(back button) 눌러서 뷰 컨트롤러2를 팝한다.
뷰 컨트롤러2가 내비게이션 스택에서 삭제되며 뷰 컨트롤러1이 다시 최상위 뷰 컨트롤러로써 화면에 보여지게 된다.

2.내비게이션바에서 루트 뷰 컨트롤러를(back button) 눌러서 뷰 컨트롤러1을 팝한다.
뷰 컨트롤러1이 메모리에서 해제되고 내비게이션 스택에서 삭제되며 루트 뷰 컨트롤러가 최상위 뷰 컨트롤러가 되고 화면에 보여지게 된다. 루트 뷰 컨트롤러는 내비게이션 스택에서 팝 되지 않으며 상단에 내비게이션바를 통해서도 루트 뷰 컨트롤러를 팝 하는 버튼이 따로 생성되어 있지 않은 것을 확인할 수 있다.

UINavigationController 클래스

위에서 설명한 내비게이션 컨트롤러와 내비게이션 스택의 동작들이 UINavigationController 클래스에서 어떻게 구현되어있는지 살펴본다.

내비게이션 컨트롤러의 생성

// 내비게이션 컨트롤러의 인스턴스를 생성하는 메서드
// 매개변수로 내비게이션 스택의 가장 아래에 있는 루트 뷰 컨트롤러가 될 뷰 컨트롤러를 넘겨준다
init(rootViewController: UIViewController)

내비게이션 스택의 뷰 컨트롤러에 대한 접근

// 내비게이션 스택에 있는 최상위 뷰 컨트롤러에 접근하기 위한 프로퍼티
var topViewController: UIViewController?

// 현재 내비게이션 인터페이스에서 보이는 뷰와 관련된 뷰 컨트롤러에 접근하기 위한 프로퍼티
var visibleViewController: UIViewController?

// 내비게이션 스택에 특정 뷰 컨트롤러에 접근하기 위한 프로퍼티(루트 뷰 컨트롤러의 인덱스는 0)
var viewController: [UIViewController]

내비게이션 스택의 푸시와 팝에 관한 메서드

// 내비게이션 스택에 뷰 컨트롤러를 푸시
// 푸시 된 뷰 컨트롤러는 최상위 뷰 컨트롤러로 화면에 표시된다
func pushViewController(UIViewController, animated: Bool)

// 내비게이션 스택에 있는 최상위 뷰 컨트롤러를 팝
// 최상위 뷰 컨트롤러 아래에 있던 뷰 컨트롤러의 콘텐츠가 화면에 표시된다
func popViewController(animated: Bool) -> UIViewController?

// 내비게이션 스택에서 루트 뷰 컨트롤러를 제외한 모든 뷰 컨트롤러를 팝
// 루트 뷰 컨트롤러가 최상위 뷰 컨트롤러가 된다
// 삭제된 모든 뷰 컨트롤러의 배열이 반환
func popToRootViewController(animated: Bool) -> [UIViewController]?

// 특정 뷰 컨트롤러가 내비게이션 스택에 최상위 뷰 컨트롤러가 되기 전까지 상위에 있는 뷰 컨트롤러들을 팝
func popToViewController(_ viewController: UIViewController,
		animated: Bool) -> [UIViewController]?

내비게이션 인터페이스를 구성하는 두 가지 방법

스토리보드를 사용하여 내비게이션 인터페이스 구성하기

  1. 스토리보드에서 내비게이션 컨트롤러에 포함할 뷰 컨트롤러를 선택
  2. 메뉴에서 [Editor] - [Embed In] - [Navigation Controller]를 차례로 선택
  3. 선택한 뷰 컨트롤러가 내비게이션 컨트롤러의 루트 뷰 컨트롤러가 되면서 내비게이션 컨트롤러가 생성됨
  4. 위의 방법 외에도 객체 라이브러리에서 내비게이션 컨트롤러를 드로그 앤 드롭해서 캔버스에 올릴 경우 테이블 뷰를 포함한 루트 뷰 컨트롤러가 생성되면서 내비게이션 컨트롤러가 만들어짐

코드작성을 통해 내비게이션 인터페이스 구성하기

코드로 내비게이션 컨트롤러를 생성할 경우, 내비게이션 컨트롤러가 생성되기 원하는 적절한 지점에 내비게이션 컨트롤러를 생성할 수 있다. 예를 들어 내비게이션 컨트롤러가 애플리케이션 윈도우(window)의 루트 뷰로서 역할을 한다면, 내비게이션 컨트롤러를 applicationDidFinishLaunching: 메서드에 구현할 수 있다.

  1. 루트 뷰 컨트롤러가 될 뷰 컨트롤러를 생성 > 이 객체는 처음에 내비게이션 스택의 최상위 뷰 컨트롤러가 화면에 보이게 되고 내비게이션 바에 뒤로가기 버튼이 생성되지 않는다
  2. init(rootViewController: UIViewController) 메서드를 통해 내비게이션 컨트롤러를 초기화하고 생성
  3. 내비게이션 컨트롤러를 윈도우의 루트 뷰 컨트롤러로 설정
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        // 루트 뷰 컨트롤러가 될 뷰 컨트롤러를 생성
        let rootViewController = UIViewController()
        // 위에서 생성한 뷰 컨트롤러로 내비게이션 컨트롤러를 생성
        let navigationController = UINavigationController(rootViewController: rootViewController)

        self.window = UIWindow(frame: UIScreen.main.bounds)
        // 윈도우의 루트 뷰 컨트롤러로 내비게이션 컨트롤러를 설정
        self.window?.rootViewController = navigationController
        self.window?.makeKeyAndVisible()

        return true
    }

내비게이션바의 구성

내비게이션바는 내비게이션 컨트롤러에 의해 생성 된다.

내비게이션바는 내비게이션 컨트롤러의 관리를 받는 모든 뷰 컨트롤러의 상단에 표시 되며 최상위 뷰 컨트롤러가 변경될 때마다 내비게이션 컨트롤러는 내비게이션바를 업데이트한다.

내비게이션바는 다음과 같은 구조로 이루어져 있다.

H.I.G(Human Interface Guidelines)

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


H.I.G 문서는 애플리케이션을 개발할 때 필요한 디자인과 동작을 포함한 여러 규칙을 통하여 사용자 인터페이스를 어떻게 구성하는 방법에 대한 지침을 제시한다. H.I.G 문서의 가이드라인을 따라 인터페이스를 작성하면 사용자들로 하여금 새로운 애플리케이션을 처음 접하더라도 대부분의 iOS 사용자에게 익숙한 환경을 제공할 수 있다. 좋은 인터페이스를 사용자에게 제공하는 것은 애플리케이션의 사용자를 더 많이 끌어들일 수 있는 하나의 포인트가 될 수 있다.

왜 H.I.G 문서를 읽어야하나?

  • 애플리케이션을 설계할 때 사용자와 상호작용에 관해 생각하고 설계할 수 있다
  • 개발자가 아닌 사용자의 입장에서 애플리케이션을 바라보고 설계할 수 있다
  • 애플리케이션의 일관성을 유지할 수 있다
  • 기획자, 디자이너 등 협업에 있어 기준점을 제시하여 협업의 효율을 높일 수 있다
  • 이미 사용자에게 익숙한 환경을 제공하여 새로운 애플리케이션 사용의 진입장벽을 낮출 수 있다
  • 이미 검증된 사용자 경험을 이해하고 그것을 토대로 조금 더 유연한 사용자 경험을 설계할 수 있다

H.I.G 문서는 프로그래머뿐만 아니라 디자이너, 기획자, 테스터 등 iOS 애플리케이션 개발에 참여하는 모든 사람이 읽어보는 것을 추천

H.I.G의 내용 구성

  • Overview

iOS 플랫폼 테마의 특징과 인터페이스 요소에 관한 개요
iOS의 버전이 업데이트 되면 새로운 iOS 버전의 특징과 변화에 관해서도 설명

  • App Architecture

애플리케이션 아키텍처 설계 시 고려해야 할 사항을 설명

  • User Interaction

애플리케이션이 사용자와 상호작용하는 동작 설계 시 고려해야 할 사항을 설명

  • System Capabilities

시스템이 지원하는 여러 시스템 기능과 각 기능에 대해 설계 시 고려해야 할 사항을 설명

  • Visual Design

애플리케이션의 시각적인 요소 설계 시 고려해야 할 사항을 설명

  • Icons and Images

iOS에서의 이미지, 아이콘, 시작화면에 관한 내용과 지침에 관한 내용을 설명

  • Bars

iOS에서 사용하는 바의 각 역할과 용도에 관한 설명과 각 바를 구현할 때 고려해야 할 사항에 관한 내용

  • Views

뷰의 종류와 역할에 관해 설명하고 뷰 설계 시 고려해야 할 사항에 관한 내용

  • Controls

여러 가지 컨트롤 요소들에 관한 소개와 설계 시 고려해야 할 사항들에 관한 내용

  • Extensions

여러 가지 확장기능을 소개하고 확장 기능을 사용하는 애플리케이션 설계 시 고려해야 할 사항들에 관해 설명

  • Technologies

여러 기술을 구현할 수 있는 Kit에 관해 설명하고 해당 Kit 사용 시 설계지침에 관한 내용

  • Resources

플랫폼들에 대한 자원 제공에 관한 내용

MVC(Model-View-Controller Design Pattern)

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


MVC 디자인 패러다임

일단 기본적으로 우리 시스템 안의 모든 객체는 세가지로 나뉜다. > Model, View, Controller

1. Model

앱에서 ‘무엇’에 해당하는 UI와 독립적인 객체들이다. 집중력게임에서는 집중력게임을 할 줄 아는 부분에 해당하는 앱이다. 카드가 매치되는지 확인하고, 가져가며 언제 카드를 뒤집어야 하는지 그런 것들을 아는 부분이다. 즉, 집중력 게임에 대한 지식들을 의미한다.

하지만 그게 어떻게 화면에 나오지는 지에 대한 부분은 없다.

2. Controller

‘어떻게’에 해당한다. 어떻게 집중력 게임이 화면에 나오는지에 관심을 갖는다.
Model의 정보를 해석하고 구성해서 View에게 보내주는 역할 혹은 사용자와의 상호작용을 모델에게 해석해주는 역할

3. View

컨트롤러의 하인들로 보통 아주 일반적인 UI 요소들인데(UIButton, UILabel, UIViewController) 컨트롤러가 모델과 통신해 앱에서 어떤 것을 UI에 가져오도록 할 때 필요하다.

이러한 MVC는 세가지 캠프 사이의 커뮤니케이션을 관리하는 데에 의미가 있다. 캠프에 객체를 넣으면 서로 얘기할 때 특정한 규칙을 따라야 한다.

MVC 서로의 관계

Model과 Controller

Controller > Model: Controller가 원하는 대로 Model과 이야기 할 수 있다.

  • 무엇이 어떤건지에 대해 사용자에게 보여줘야 하기 때문에 모델에 대한 접근이 가능해야 한다.
  • 모델의 공개된 모든 기능과는 거의 무제한적인 대화가 가능하다.

Model > Controller: 직접적인 소통은 불가능하다.

  • Model은 UI와 독립적이고 Controller는 근본적으로 UI에 종속된다.

그러나 소통은 가능하다. Model의 데이터가 변경되었을때 해당 변경사항과 연결된 UI에도 업데이트를 하는 경우!

Notification & KVO(key value observing): Model의 변경사항을 방송하는 것

Model과 View

둘 사이의 소통은 불가능하다.

이유1: 모델은 UI와 독립적이지만, View는 UI에 의존한다.(View는 UI와 관련된 것들만을 포함한다)
이유2: View는 일반 객체일 뿐이다. (버튼 그 자체가 무슨일을 하는지는 알수가 없다.)

View와 Controller

Controller > View: View는 일반적으로 Controller의 하인들이다.

  • Controller는 outlet을 통해 View 객체들을 모두 관리할 수 있다.

View > Controller: 구조적으로 미리 정해진 방식을 통해 Controller에게 행위에 대한 요청(delegate)과 데이터에 대한 요청(data source)을 할 수 있다.

구조적: 이 통신을 하기로 했을 때 일반적인 객체는 어떻게 컨트롤러와 대화를 할지 조금 먼저 생각해놓고 있어야 한다는 것

더 나아가 targer-action의 구조를 통해 사용자의 행위에 따라 필요한 함수를 호출할 수도 있다.

  • target: 컨트롤러가 해야하는 건 자신에게 타겟을 만드는 것
  • action: UIButton이나 다른 것들은 액션을 가지고 버튼을 누를때마다 타겟을 호출

프로그래밍 디자인 패턴

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


프로그래밍 디자인 패턴

디자인 패턴이 객체지향 프로그래머에게 크게 영향을 미치게 된 계기는 “디자인 패턴 (Design Patterns)” 책이 출간되면서부터다. 이 책에서 GoF(Gang of Four의 약자로 “디자인 패턴 (Design Patterns)”의 저자들 Erich Gamma, Richard Helm, Ralph Johnson, Jone Vlisside 네 사람)는 객체지향설계를 위한 23개의 패턴을 기술 하였다. 이를 토대로 객체지향 분석/설계, 도메인 설계, 프로세스 조직/설계, 사용자 인터페이스 설계와 같은 다양한 분야에서 패턴과 패턴 언어에 대한 논문과 책들이 출간되고 객체지향 프로그래밍 개발에서 디자인 패턴이 폭넓게 사용되기 시작하였다.

• GoF
“특정한 상황에서 일반적 설계문제를 해결하기 위해 상호교류하는 수정 가능한 객체와 클래스들에 대한 설명이다.”

• 라만(C. Larman)GoF
“숙련된 객체지향 개발자 및 기타 소프트웨어 개발자는 소프트웨어 개발의 가이드라인이 되는 일반적인 원칙들과 관용적인 해결책들의 레퍼토리(repertoire)를 구축한다. 패턴은 이러한 원칙들과 관용적 해결책들이 문제와 해결책을 기술하는 구조적인 형태로 체계화되고 명명된 것이다.”

프로그래밍 디자인 패턴은 소프트웨어를 설계할 때 특정 상황에서 자주 사용하는 패턴을 정형화한 것이며, 좋은 소프트웨어 설계를 위한 개발자들의 경험적 산물이라고 할 수 있다.

프로그래밍 디자인 패턴의 특징

  • 경험을 통하여 얻을 수 있다
  • 특정한 형식을 갖고 체계적으로 작성되는 것이 일반적
  • 패턴에는 각기 다른 추상화 수준이 존재하며 계속 진화함

프로그래밍 디자인 패턴의 장점

의사소통에 도움을 준다. 디자인 패턴을 알고 있는 설계자들은 특정 문제에 대해 공통으로 알고 있는 패턴을 이용해 해결책에 대해 논의를 할 수 있기 때문에 더욱 원활하게 의사소통할 수 있다. 검증된 지식인 패턴을 사용하면 높은 완성도의 디자인을 빠른 시간에 만들어 낼 수 있기 때문에 소프트웨어 개발 비용을 줄일 수 있어서 경제적이며, 코드의 수준을 한 단계 높여 주고 적은 수의 클래스로 원하는 목적을 달성할 수 있는 환경이 제공된다.

좋은 설계나 아키텍처가 패턴이라는 이름으로 명명되어 있어 개발자는 그 패턴의 이름만으로도 그 소프트웨어의 구조를 알 수 있다. 이를 바탕으로 이전의 소프트웨어 개발에서 사용한 설계나 구조를 쉽게 이해할 수 있고, 새로운 소프트웨어로 빠르게 적용할 수 있어서 소프트웨어 재사용을 쉽게 해준다.

디자인 패턴의 분류

새로운 소프트웨어를 개발할 때마다 대부분 개발자는 어떤 클래스를 만들고 어느 시점에 객체를 생성하고 소멸시킬지, 데이터를 어떻게 받아서 처리할지, 구조 설계를 어떻게 할지 고민해야하는데, 디자인 패턴 분류는 위와 같이 소프트웨어 코드를 작성할 때 자주 반복되는 특정 상황에서 설계를 용이하게 하며 코드의 재사용이 용이하도록 패턴을 정리해 놓은 것이다.

그중 가장 잘 알려진 분류법으로 GoF의 패턴분류 방법이 있다.

• 목적
패턴이 무엇을 하는지 정의하는 것으로 "생성", "구조", "행위" 중의 한 가지 목적을 갖는다.

  ◦ 생성 (Creational Pattern)
  객체의 생성 과정에 관여하는 패턴

  ◦ 구조 (Structural Pattern)
  클래스나 객체의 구성을 통해 더 큰 구조로 만들 수 있게 해주는 것과 관련된 패턴

  ◦ 행위 (Behavioral Pattern)
  패턴을 주로 클래스에 적용하는지 아니면 객체에 적용하는지에 따라 구분되는 패턴

• 범위
패턴을 클래스에 적용하는지 아니면 객체에 적용하는지에 따라 구분되는 패턴

  ◦ 클래스 패턴 (Class Pattern)
  클래스들과 하위 클래스 간의 관계를 다루는 패턴입니다. 컴파일 시에 관계가 결정

  ◦ 객체 패턴 (Object Patterns)
  객체 간의 관계를 다루며 보통 구성을 통해 정의됨.
  객체 패턴은 일반적으로 실행시간에 관계가 생성되기 때문에 더 동적이면서 유연

디자인 패턴의 종류

수많은 패턴 중 몇 가지 패턴의 종류를 간단하게 설명한다.

• 싱글턴 패턴 (Singleton Pattern)
목적 : 생성
범위 : 객체
객체의 생성에 관련된 패턴으로서 특정 클래스의 인스턴스가 오직 하나임을 보장하고 이 인스턴스에 접근할 방법을 제공

• 퍼사드 패턴 (Facade Pattern)
목적 : 구조
범위 : 객체
건물의 정문에 있는 안내소처럼 개발자가 사용해야 하는 서브 시스템의 가장 앞쪽에 위치하면서 하위 시스템에 있는 객체들을 사용할 수 있도록 하는 역할을 한다.
> 시스템의 복잡성을 줄이기 위해 서브 시스템을 구조화하고 서브 시스템으로의 접근을 하나의 퍼사드 객체로 제공하는 패턴

• 옵저버 패턴 (Observer Pattern)
목적 : 행위
범위 : 객체
객체의 상태변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 패턴

• 스트래티지 패턴 (Strategy Pattern)
목적 : 행위
범위 : 객체
알고리즘을 담당하는 각각의 클래스를 만들어 책임을 분산하기 위한 목적으로 만든 행위 패턴

• 팩토리 패턴 (Factory Pattern)
목적 : 생성
범위 : 클래스
객체를 생성하기 위한 인터페이스를 정의하지만 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 하위 클래스에서 이루어지도록 인스턴스 생성의 책임을 떠넘기는 패턴

• 어댑터 패턴 (Adapter Pattern)
목적 : 구조
범위 : 클래스, 객체
클래스의 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하는 패턴으로, 호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 동작하도록 함

소프트웨어 디자인 패턴을 사용할 때 생각해 볼 점

디자인 패턴은 특정 상황에 대한 선배 프로그래머의 경험의 산물이자 방법론으로 즉, 디자인 패턴은 모든 상황에서 만능은 아니다.

예를 들어 싱글턴 패턴을 적재적소에 활용하면 유용하겠지만, 적절치 못한 상황에 사용하면 오히려 큰 독이 될 수도 있다. 다양한 디자인 패턴을 아는 것도 중요하지만, 언제 어떻게 사용하는 것이 좋을지 고민하는 것도 굉장히 중요한 문제이다.

디자인 패턴은 그 종류도 다양해지고 있으며, 기존의 디자인 패턴을 변형하여 사용하는 경우도 많다. 다양한 디자인 패턴을 익히고 자신의 코드에 적용해 보되, 깊은 공부와 많은 고민은 필수!

iOS View 체계

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


뷰의 기본적인 역할

iOS에서 화면에 애플리케이션의 콘텐츠를 나타내기 위해 윈도우와 뷰를 사용한다.

  • 윈도우 는 그 자체로 콘텐츠를 표현할 수 없지만 애플리케이션의 뷰를 위한 컨테이너 역할을 한다.
  • 는 UIView 클래스 또는 UIView 클래스의 하위클래스(Subclass)의 인스턴스로 윈도우의 한 영역에서 콘텐츠를 보여준다.

뷰가 나타낼 수 있는 콘텐츠는 이미지, 문자, 도형 등과 같이 다양하며, 뷰는 또 다른 뷰를 관리하고 구성하기 위해 사용되기도 한다. 뷰는 제스처 인식기(gesture recognizer) 를 사용하거나 직접 터치 이벤트를 처리할 수 있으며, 또한 뷰 계층(view hierarchy)구조에서 부모뷰(parent view)는 자식뷰(child view)의 위치와 크기를 관리한다.

나타내고자 하는 유형의 콘텐츠에 적합한 뷰를 여러 개 사용하여 뷰 계층(view hierarchy)구조를 구성하고 이를 통해 콘텐츠를 보여주는 것이 좋다. 예를 들어 UIKit에는 이미지, 텍스트 그리고 다른 유형의 콘텐츠를 나타내는 뷰가 포함되어 있다.

뷰 계층(View hierarchy)

뷰 계층구조와 서브뷰 관리

뷰는 자신의 콘텐츠를 보여주는 것과 더불어, 다른 뷰를 위한 컨테이너로써의 역할도 한다. 하나의 뷰가 다른 뷰를 포함할 때, 두 뷰 사이에 부모-자식 관계가 생성된다.
해당 관계에서는 자식뷰는 서브뷰(subview) 로, 부모뷰는 슈퍼뷰(superview) 로 불려집니다.

부모-자식 관계 형성은 애플리케이션의 시각적 모습과 동작 모두에 영향을 미친다.

예시

1.슈퍼뷰와 서브뷰의 관계에서 서브뷰가 불투명할 경우 아래 그림과 같이 슈퍼뷰가 서브뷰에 가려진다.

2.서브뷰가 반투명할 경우 서브뷰와 슈퍼뷰의 콘텐츠가 서로 섞여 화면에 보여진다.

  • 아래 그림과 같이 원래 노란색이었던 뷰가 슈퍼뷰의 빨간색과 섞여 주황색으로 화면에 보이게 됩니다.

3.슈퍼뷰는 하나의 배열 안에 서브뷰를 순서대로 저장한다. 만약 하나의 슈퍼뷰에 포함된 두 서브뷰가 서로 겹치게 되면, 나중에 추가된(또는 서브뷰 배열의 끝으로 옮겨진) 서브뷰가 맨 위에 보여진다.

4.두 서브뷰가 모두 반투명할 경우 뒤에 있는 모든 뷰들이 섞여 화면에 보여진다.

뷰 계층 생성과 관련된 더 많은 정보를 원하면, Creating and Managing a View Hierarchy를 참조

뷰 계층의 생성과 관리

OS 애플리케이션에서 뷰 계층을 만드는 방법에는 인터페이스 빌더를 이용하는 방법과 코드를 작성하는 방법이 있다.

코드작성 방식을 사용할 경우 서브뷰를 부모뷰에 추가하기 위해, 부모뷰의 addSubView(_:) 메서드를 호출한다. 이 메서드는 해당 서브뷰를 서브뷰 목록의 마지막에 추가 합니다. 부모뷰의 서브뷰를 제거하기 위해서는 서브뷰의 removeFromSuperView() 메서드를 호출한다. 이 외에도 서브뷰를 부모뷰 목록의 중간에 삽입하기 위해 insertSubview(_:at:), 부모뷰 내에 이미존재하는 서브뷰를 정렬하기 위해 bringSubView(toFront:), sendSubview(toBack:) 등의 메서드들을 호출할 수 있다.

뷰의 좌표계

UIKit에서 기본이 되는 좌표계는 좌측 상단 모서리를 원점 으로 하며, 원점으로부터 아래쪽, 오른쪽 방향으로 확장된다.
좌표값은 해상도와 상관없이 콘텐츠의 위치를 잡는 부동소수점을 사용 하여 나타냅니다.

프레임과 바운드

iOS의 좌표체계의 시작은 왼쪽 위부터 시작
즉, 제일 왼쪽의 제일 위의 지점이 (0, 0) 이다. 또, 수평축은 x로, 수직축은 y로 표현

  • 뷰의 프레임(frame): 뷰의 크기와 위치를 슈퍼뷰의 좌표계를 기준으로 나타냄
  • 바운드(bounds): 뷰의 크기와 위치를 해당 뷰 자신의 좌표계를 기준으로 나타냄