본문 바로가기

수업 정리

92일차 수업정리(swift - SDK)

**iOS SDK

    => SDK(Software Development Kit) - API라고도 하는데 어떤 플랫폼의 애플리케이션을 개발하기 위한 함수, 클래스의 집합

    => iOS 애플리케이션 개발을 위한 클래스의 집합

    => Project(작업단위 - 하나의 디렉토리) -> Target(Application)

        - 실제 애플리케이션을 개발시 1개의 프로젝트에 1개의  Target을 가지고 작업

        - 포트폴리오 작성시는 1개의 프로젝트에 여러개의 Target을 배치하는 형태로 작성

1. Project 생성

    => Xcode 에서 [File] - [New] - [Project]를 선택

  1) 플랫폼을 선택

    - iOS: iPhone, iPad, iPod 애플리케이션 개발

    - watchOS: 시계

    - tvOS: TV

    - macOS: 매킨토시 컴퓨터 애플리케이션 개발

    - Cross-Platform: 여러가지 플랫폼에서 동작하는 애플리케이션을 개발

 

  2) Application 과 Framework & Library

    => Application은 독자적으로 동작하는 프로그램

    => Framework 와 Library는 독자적으로는 동작하지 못하고 다른 Application에 포함되거나 만드는 것을 도와주는 프로그램

    => 실제 기업들은 Application 만드는 것 보다는 Library 만드는 일이 많음

        - 인터넷 뱅킹 애플리케이션 같은 경우 보안, 키보드 모듈 등은 별도의 업체에서 개발한 후 조립하여 애플리케이션 개발

        - 하드웨어 드라이버도 Library 형태로 개발

 

  3) Application

    => Single View App: 하나의 ViewController를 배치한 상태에서 작업할 수 있도록 해주는 프로젝트

        - 기본 프로젝트이고 이 프로젝트에서 모든 프로젝트로 변경이 가능

    => Game: Apple의 그래픽 가속 기술은 Sprite Kit을 포함한 프로젝트

    => Augmented Reality App: 증강현실 라이브러리를 포함한 프로젝트

    => Document Based App: 문서를 출력하기 위한 라이브러리를 포함한 프로젝트

        - 한글과 컴퓨터의 앱이나 PDF Viewer 앱들이 이 기반인데 문서를 공유할 수 있도록 처음부터 설정되서 만들어짐

    => Master Detail App: 왼쪽에 테이블 뷰, 오른쪽에 일반 뷰를 배치, 왼쪽선택시 오른쪽에 상세보기로 출력하는 애플리케이션 프로젝트

        - 세로 모드인 경우 테이블 뷰가 위에 메뉴 형태, 가로 모드 일 때는 테이블 뷰 형태로 출력(iPhone + 시리즈에서 동일하게 사용 가능)

    => Tabbed App: 하단에 탭을 배치

        - 탭의 크기가 변할 수 있는데 세로보기에 맞춰진 형태로 디자인 되어 있어서 버튼이 5개까지만 배치

        - 가로보기로 변경되었을 때 버튼의 모양이 이상해집니다.

    => Sticker Pack App: 아이콘의 모임 형태의 앱

    => IMessage App: 메시지 앱과 유사한 형태로 만들어지는 앱 - 채팅 앱에 유용

 

  4) Framework & Library

    => Framework: 애플리케이션 개발을 도와주는 하나의 프로그램

    => Static Library: 애플리케이션 개발을 할 때 애플리케이션에 포함시켜서 애플리케이션의 기능을 수행할 수 있도록 해주는 것

    => Metal Library: 그래픽 라이브러리

 

  5) 옵션 설정

    => 프로젝트 이름

    => 조직 이름

        - 2개가 합쳐져서 BundleIdentifier가 생성되고 마켓에서 구분되는 이름

    => 개발자 계정을 등록할 수 있는 Team 선택

    => Language: Objective-C 나 Swift - Swift 선택(이전 앱을 컨버전 : Objective-C)

    => User Interface: Storyboard(기존의 방식) 와 Swift UI(iOS 13에서 추가)

        - 현재의 앱 개발자들은 Storyboard를 주로 이용

 

    => Use Core Data(Apple In Memory DB - 데이터를 주기억장치에 보관하고 사용하는 데이터베이스, ORM의 개념)

        - core data 사용 여부 설정 : 나중에 다시 설정할 수 있음

    => Use Cloud Kit: iCloud 연동 라이브러리를 포함시켜주는 옵션

    => 테스트 클래스 생성 여부 

 

  6) 저장 위치 설절

 

  7) 프로젝트 생성

 

2. 프로젝트를 생성하면 맨 처음 보이는 화면 - 프로젝트 설정 화면

    => 프로젝트에 대한 옵션을 설정 - 운영체제 버전 과 디바이스 그리고 방향에 대한 옵션을 주로 설정(사용할 라이브러리 추가)

 

3. Xcode 화면

  1) 왼쪽 창 : Navigator 영역

    =>프로젝트나 타겟에 대한 보기 화면

 

  2) 오른쪽 창 : Inspector 영역

    => 각각의 오브젝트에 대한 보기 화면

 

4. 프로젝트를 생성했을 때 만들어지는 파일

  1) AppDelegate.swift: iOS 프로젝트의 Entry Point

  2) SceneDelegate.swift: 보여지는 화면의 시작 -  iOS 12까지는 없음

    => 플랫폼 타겟을 13 아래로 설정하면 이 파일때문에 에러

  3) ViewController.swift: 첫번째 보여지는 뷰의 제어 파일

  4) Main.stroyboard: 앱의 화면 디자인을 위한 스토리보드

    => UI 전체 구조를 파악하는데 도움을 줌

  5) Assets: 프로젝트에 필요한 리소스 디렉토리

  6) LaunchScreen.storyboard: 앱의 시작 화면을 위한 스토리보드

  7) Info.plist: 프로젝트 설정 파일

  8) Products: 배포되는 앱이 저장되는 디렉토리

    => Xcode 의 프로젝트에서는 디렉토리는 의미 없음

        - 내부에 디렉토리를 만들고 자원을 배치해도 전부 루트 디렉토리에 옮겨서 하나의 디렉토리에 모든 파일 저장, 압축해서 스마트 폰에

         설치, 설치가 되면 압축을 풀어서 가지고 있음

 

5. swift 와 storyboard

    => swift 파일은 소스를 작성하는 파일

    => storyboard는 화면 디자인을 위한 파일

        - Storyboard 파일을 선택하면 Interface Builder(줄여서 IB - 여기 만들어지는 파일을 XIB, NIB 라고도 합니다.)가 실행

        - 이전에는 화면단위로 디자인 - 각각의 화면 : NIB

        - 현재는 애플리케이션 단위로 디자인 - Stroyboard

    => storyboard에 디자인 할 때 크기나 좌표를 설정할 때 단위가 없음

        - 해상도에 따라 실제 크기는 iOS 운영체제가 설정

 

6. iOS(Cocoa Touch) Application 실행 원리

  1) run 을 누름 : Application을 탭

 

  2) main 메소드가 실행됨 - swift 에서는 main 메소드 대신에 @UIApplicationMain 이 작성된 파일의 메소드가 호출

 

  3) AppDelegate 클래스의 인스턴스가 생성 - AppDelegate 와 SceneDelegate 의 객체는 직접 생성하지 않음

 

  4) AppDelegate 의 아래 메소드가 호출

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: 
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    => launchOptions에 앱이 실행된 방법을 전달 : 직접 탭을 했는지 아니면 다른 애플리케이션에서 호출한 것인지 

 

func applicationWillEnterForeground 라는 메소드를 호출

    =>첫번째 메소드는 앱이 종료된 상태에서 실행되는 경우에만 호출되고 아래 메소드는 실행되면 무조건 호출

 

  5) 사용자가 홈 버튼을 누르거나 전화 통화를 시도하면 앱은 백그라운드 상태로 진입

    - applicationDidEnterBackground 라는 메소드가 호출되고 종료될 때는 applicationWillTerminated 메소드가 호출

 

7. Cocoa Touch Framework 구조(Hardware -> Core OS(Unix 기반) -> Core Service -> Media -> Cocoa Touch -> iOS Apll)

    => Core Service 와 Media, Cocoa Touch는 묶어서 표현

  1)Core OS

    => 하드웨어와 가장 가까운 계층

    => Unix 기반이라서 대부분 C언어로 작성

    => 데이터처리, 네트워크, 파일 접근 등의 기능을 수행

  2)Core Service

    => Core OS가 지원하지 않는 기능을 제공

    => 센서, 계정, 기본 라이브러리 등의 기능을 제공

  3)Media

    => 그래픽, 오디오, 비디오 등의 기능을 수행

    => C 와 Objective-C의 혼용

  4)Cocoa Touch(iOS)

    => UIKit(화면 출력 과 터치) 과 Foundation(기본적인 자료구조 제공)

 

8. Cocoa Touch Framework

    => Foundation 과 UIKit : 기본

    => Game Kit & Sprite Kit: 그래픽

    => iAd: 광고

    => MapKit: 지도 관련 - 내장

    => AddressBook - 주소록

    => EventKit - 캘린더

    => Extension - 일반 앱이 아니고 알림 등에서 사용하는 작은 앱

    => Handoff - 아이패드나 맥 PC에서 전화 사용

    => HealthKit: 신체정보 관련 정보 라이브러리이고 수집은 ResearchKit

    => HomeKit: iOT 관련 라이브러리

 

**화면 디자인: 인터페이스를 빌더를 사용하는 방법이 있고 코드로 디자인

1. 화면에 뷰를 배치

    => 스토리보드를 선택해서 인터페이스 빌더를 실행

    => Object 창에서 필요한 뷰를 선택하고 드래그

 

2. Inspector

    => Xcode에서 각 객체에 대한 설정을 위한 창

  1) File Inspector: 디자인 한 뷰가 속한 파일의 전체 경로 및 지역화에 대한 정보

  2) Quick Help: 간단한 도움말을 보여주고 세부 도움말로 이동할 수 있는 링크를 제공

  3) Identity Inspector: 클래스 종류 와 ID를 설정 - Custom Design을 할 때 주로 편집

  4) Attribute Inspector: 객체의 세부 속성을 설정

  5) Size Inspector: 크기 설정 - Auto Layout 설정

  6) Connection Inspector: 뷰와 뷰컨트롤러 사이의 연결에 대한 설정

    =>뷰 컨트롤러의 어떤 변수에 연결되었는지 이벤트에 어떤 메소드가 연결되었는지 확인

 

**iOS 의 화면 출력 구조

    - window(예전에는 AppDelegate 의 멤버였고 지금은 SceneDelegate 의 멤버) -> View - > Layer(출력을 위해서 그리는 개념)

    => window 위에 View를 직접 배치해도 되지만 기본적으로 ViewController를 이용해서 View를 배치

    => View를 배치하게 되면 View에 출력해야 데이터만 비지니스 로직을 View 가 소유하고 있어야 합니다.

        - 데이터바 비지니스 로직을 수정할 때 View의 코드도 수정을 해야 합니다.

    =>ViewController 라고 하는 클래스 제공, 이 클래스에 비지니스 로직을 작성, View를 배치하도록 해서 비지니스 로직이 생성한 데이터

        를 View에 출력하는 구조를 갖도록 합니다.

    => window 위에 ViewController의 view를 출력하는 형태

    => ViewController의 분류

        - Contents View Controller : 실제 출력을 위한 뷰 컨트롤러

        - Container View Controller : 뷰 컨트롤러의 관리를 담당하는 컨트롤러 - Navigation, Tab, Page, Split ViewController 들이 있음

        - Initial View Controller : 맨 처음 보여지는 뷰 컨트롤러

             - 인터페이스 빌더에서 보면 왼쪽에 화살표가 있는 뷰 컨트롤러 

    - 프로젝트를 만들고 실행시, 에러는 없는데 까만 화면만 출력 - 처음 보여져야 하는 뷰가 설정이 안된 경우, 시작하는 뷰 컨트롤러를 설정

      인스펙터에서 is Initial View Controller 란에 체크하면 됩니다.

 

**인터페이스 빌더에 디자인 한 뷰 와 swift 파일을 연결

1. 변수 연결 - IBOutlet(인터페이스 빌더에 디자인 한 뷰와 연결하는 변수를 만들 때 사용하는 예약어)

    => 인터페이스 빌더와 swift 파일을 모두 화면에 출력

    => 인터페이스 빌더에 디자인 한 뷰를 선택하고 마우스 오른쪽을 클릭하고 [New Referencing Output] 항목의 오른쪽 동그라미를 선택하고 swift 파일에 드래그 한 후 떨어뜨리면 변수 이름 입력란이 보이고 이름을 입력하면 됨

 

@IBOutlet weak var label: UILabel!

 

@IBOutlet : 인터페이스 빌더의 뷰와 연결된 변수를 의미

weak : 약한 복사를 하겠다는 의미로 실제로는 변수를 연결만 함

!는 nil을 저장할 수 있도록 한 것이고 사용을 할 때는 !를 붙이지 않고 사용하겠다는 의미

 

이렇게 연결이되면 인터페이스 빌더에서 뷰를 선택하고 마지막 인스펙터를 보면 확인이 가능

 

2.실습

  1) 디자인 한 레이블을 ViewController.swift에 변수로 연결 - label

 

  2) ViewController.swift 파일의 viewDidLoad 메소드에 작성

    - label.text = "변수 연결"

 

3. 변수 연결 시 주의할 점

    => 변수를 연결하고 이름을 변경한다던가 삭제하는 경우에 인터페이스 빌더에서 연결을 해제하고 작업

    => 예외 메시지를 보면 key-value coding compliant 가 출력

        - 이 메시지가 보이면 연결이 잘못된 것이므로 연결을 수정해야 합니다.

    => 2개의 파일에서 작업하는 것이 번거러워서 개발자 들 중에는 코드로 디자인하는 경우도 있음

        - 코드로 디자인하게 되면 좌표나 크기 문제때문에 디자인하는데 시간이 오래 걸립니다.

    => 안드로이드도 xml 이 아닌 뷰에서 디자인이 가능한데 변수와 직접 연결은 안됨

    => 윈도우 프로그래밍을 하는 MFC 나 Visual C# 도 이와 유사한 방법을 사용

        - 웹 프로그래밍을 할 때 디자인도 이러한 프로그램이 있습니다.

 

4. 뷰에서 많이 사용하는 구조체

  1) CGSize: 크기 관련 구조체

    => width 와 height 속성을 소유

  2) CGPoint: 좌표 관련 구조체

    => x 와 y로 구성

  3) CGRect: CGSize 와 CGPoint 구조체의 결합

    => CGPoint 타입의 origin 과 CGSize 타입으로 size로 구성

  4) UIColor: 색상 구조체

    - UIColor.색상명 

    - UIColor.init(red:, green:, blue: alpha:)

    => 값들은 0.0 에서 1.0 사이로 설정

    => 값의 범위를 만드는 경우 

        색상의 값 - 0~ 255

       되도록이면 - 0.0 ~ 1.0, 0-100 

       범위는 절대값보다는 상대적인 값으로 만드는 것이 좋음

      절대값은 유지보수를 어렵게 함

 

**Interface Builder 에서 디자인 한 컨트롤에 이벤트 핸들러를 연결

    => IBAction: 인터페이스 빌더에서 디자인한 컨트롤러의 이벤트 핸들러에 대한 연결 예약어

    => 인터페이스 빌더에서 뷰를 선택하고 마우스 오른쪽을 클릭하고 이벤트 처리가 가능한 뷰들은 이벤트가 보이게 되는데 이벤트를 선택하고 ViewController.swift 파일로 드래그 하고 떨어뜨리면 메소드 이름을 입력하는 란이 보이게 되고 여기에 입력을 하면 메소드 생성

 

1. 버튼을 2개 배치

 

2. 각 버튼의 touch up inside 이벤트에 메소드를 2개 연결(click1, click2)

 

3. ViewController.swift 파일에 메소드의 코드 작성

@IBAction func click1(_ sender: Any) {
        self.view.backgroundColor = UIColor.red
    }
    
    @IBAction func click2(_ sender: Any) {
        self.view.backgroundColor = UIColor.init(red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0)
    }

 

**시작 화면 디자인

    => Splash View라고도 하는데 LaunchScreen.storyboard에 디자인 하면 앱이 시작될 때 화면에 출력

    => 일정 시간 동안 계속 출력되기를 원하면 AppDelegate.swift 파일의 didLaunchingWithOptions 메소드에 sleep(시간)을 추가

1. 시작화면에 사용할 이미지를 프로젝트에 복사

 

2. LaunchScreen.storyboard 파일에 이미지 뷰를 전체를 가득차게 만들고 image를 선택

 

3. AppDelegate.swift 파일의 메소드에 대기 시간을 설정

 

**iOS Application의 이벤트 처리

1. Hierachy Pattern

    => 자주 사용하는 이벤트 핸들러를 클래스에 미리 만들어두고 메소드를 재정의해서 사용하는 방식

 

2. Delegate Pattern

    => 이벤트를 처리할 객체를 연결하는 방식

  1) selector 형태: 메소드를 설정해서 연결하는 방식

 

  2) gesture 형태: 이벤트에 해당하는 gesture 클래스 객체를 만들고 gesture 객체를 설정하는 방식

 

  3) 프로토콜을 이용하는 형태: Delegate 나 DataSource 프로토콜을 conform해서 메소드를 구현하는 방식

    => 안드로이드나 다른 GUI 프로그래밍의 Delegate 패턴과 유사

    => 약간의 변형으로 Notification(사용자가 발생시키는 이벤트가 아니라 시스템에 의해 발생하는 이벤트)에 메소드를 연결하는 방식

 

3. Key - Value Observing

    => swift 에서는 property 값이 변경되는 것을 감지하는 방법이 제공

    => property 의 willSet 이나 didSet을 이용해서 이벤트 핸들링을 할 수 있음

        - 다른 언어에서는 getter 와 setter를 이용해서 구현하기 때문에 이것을 이벤트 핸들링으로 간주하지 않음

 

**UIViewController

    => iOS에서 하나의 화면을 관리하기 위한 클래스

1. 역할

    => 회전관리

    => 메모리 경고 처리

    => 흔들기, 메뉴 등을 처리

    => 뷰 관리

    => 뷰의 Delegate 나 DataSource 의 역할

 

2. 종류

    => Content Controller: UIViewController, UITableViewController, UICollectionViewController 등

    => Container Controller: UINavigationController, UITabBarController, UIPageController, UISplitViewController,

        UIModalViewController : 만들 때 1개 이상의 Content Controller가 있어야 함

 

3. 생성

    => 일반적으로 ContentController는 상속을 받는 클래스를 만들어서 필요한 메소드를 재정의

        - ContainerController들은 바로 인스턴스를 생성해서 사용

        - 기본 프로젝트를 생성하면 UIViewController로부터 상속받은 ViewController를 제공

 

4. 초기화 관련 메소드(생성자 - init)

1)default constructor : 매개변수가 없는 생성

init( )

 

2)init(coder : Coder) => Interface Builder에서 디자인 한 후 인스턴스를 생성하면 호출되는 생성자

=>이 생성자는 직접 호출할 수 없음

 

3)인터페이스 빌더에서 디자인 한 뷰 컨트롤러를 가지고 생성

=>Storyboard객체.instantiateViewController(withIdentifier: 뷰컨트롤러의id) 를 이용하면 UIViewController 타입의 인스턴스가 리턴됨

=>UIViewController 타입으로 리턴되므로 실제 사용을 할 때는 자신이 만든 ViewController 타입으로 강제 형 변환해서 사용해야 합니다.

=>인터페이스 빌더에서 뷰 컨트롤러를 추가한 경우에는 반드시 Class 속성을 이용해서 자신의 클래스 타입을 설정해야 하고 identifier를 이용해서 자신을 구별할 수 있도록 만들어 주어야 합니다.

 

5.UIViewController의 속성

1)UIView view: 뷰 컨트롤러의 뷰 - 뷰 컨트롤러에서는 최상위 뷰

 

2)UINavigationController navigationController, UITabBarController tabBarController

=>2개의 속성은 nil 이 될 수 있습니다.

=>뷰 컨트롤러가 NavigationController 나 TabBarController에 포함된 경우에 사용할 수 있는 속성

 

3)UINavigationItem navigationItem, UITabBarItem tabBarItem

=>뷰 컨트롤러가 NavigationController 나 TabBarController에 포함된 경우에 사용할 수 있는 속성

 

4)String title

=>뷰 컨트롤러의 제목 속성인데 보통때는 표시가 안되고 NavigationController에 속한 경우 NavigationController의 NavigationBar의 titleView에 출력되고 TabBarController에 속한 경우에는 tabBarItem에 표시됩니다.

 

5)UIViewController presentingViewController: 자신을 출력할 수 있도록 해준 컨트롤러의 참조를 저장

 

6.수명 주기

생성자 -> loadView(뷰 컨트롤러 객체가 생성되고 뷰를 메모리에 로드할 때 호출되는 메소드) -> viewDidLoad(뷰를 메모리에 전부 로드하고 호출되는 메소드) -> viewWillAppear(뷰가 화면에 보여지기 직전에 호출되는 메소드) -> viewDidAppear(뷰가 화면에 보여지고 난 후 호출되는 메소드) -> viewWillDisappear(뷰가 사라지기 직전에 호출되는 메소드) -> viewDidDisappear(뷰가 사라진 후 호출되는 메소드) -> viewDidUnload(뷰가 메모리에서 제거되면 호출되는 메소드)

 

=>appear 와 관련된 메소드는 뷰가 보여지는 것과 관련되어 있고 나머지 메소드들은 뷰 컨트롤러의 생성과 소멸에 관련된 메소드

 

현재 뷰 컨트롤러가 다른 뷰 컨트롤러를 호출하고 난 후 호출된 뷰 컨트롤러가 제거되면 appear 관련된 메소드만 호출됩니다.

 

7.기타 메소드

=>didReceiveMemoryWarning: 메모리가 부족해서 경고 발생할 때 호출되는 메소드로 한 곳에서 호출되면 다른 모든 뷰 컨트롤러에서도 호출됩니다.

 

8.UIViewController에서의 Touch 이벤트 처리

=>iOS에서는 터치이벤트가 발생하면 FirstResponder에게 처리를 요청

1)UIResponder 클래스

=>이벤트를 처리할 수 있는 iOS 뷰의 최상위 클래스

=>UIResponder로부터 상속을 받은 클래스는 터치 이벤트를 처리할 수 있음

=>관련된 메소드와 속성

canBecomFirstResponder: 맨 처음 이벤트를 받기 위한 객체가 될 수 있는지 여부를 설정

becomeFirstResponder(): 맨 처음 이벤트를 받기 위한 객체가 되도록 설정하는 메소드

resignFirstResponder(): 이벤트 처리를 하지 않도록 설정

 

2)Touch 처리 관련 메소드

func touchesBegan(Set<UITouch>, UIEvent): 터치가 시작되었을 때

func touchesMoved(Set<UITouch>, UIEvent): 터치하고 움직일 때

func touchesEnded(Set<UITouch>, UIEvent): 터치가 종료되었을 때

func touchesCancelled(Set<UITouch>, UIEvent): 터치가 취소된 경우로 현재 애플리케이션이 백그라운드로 상태로 갈 때 - 전화왔을 때

 

Set이 UITouch의 집합인데 UITouch가 손가락 하나의 터치 정보를 저장하는 클래스

 

3)UITouch 의 속성 및 메소드

=>TimeInterval timestamp: 터치가 발생한 시간

=>UITouch.Phase phase: 터치의 상태로 began, moved, stationary(누르고 있는 경우), ended cancelled

=>Int tapCount: 두드린 횟수

=>UIView view: 터치가 발생한 뷰

=>UIWindow window: 터치가 발생한 윈도우

=>location(in:UIView) -> CGPoint : 매개변수로 대입한 뷰를 기준으로 한 터치의 좌표

 

4)4개의 레이블과 1개의 이미지 뷰를 배치해서 이미지 뷰에서 터치가 발생하면 터치의 상태와 두드린 횟수를 레이블에 출력하고 이미지 뷰를 선택한 상태에서 터치를 이동하면 이미지 뷰가 따라 다니도록 하기

 

=>프로젝트를 생성하거나 기존 프로젝트에 Target을 추가

 

=>이미지 파일을 프로젝트에 추가(디렉토리를 만들어서 추가해도 되고 프로젝트 안에 추가해도 됨)

 

=>4개의 레이블 과 1개의 이미지 뷰를 ViewController의 화면에 배치 - Main.storyboard를 열어서 디자인

 

=>디자인 한 뷰를 제어하기 위한 변수를 설정 

소스코드를 열어놓고 뷰를 선택하고 마우스 오른쪽을 클릭해서 [New Referencing Outlet]을 선택하고 소스코드 창의 클래스 안의 영역에 드래그 앤 드랍을 하면 변수이름을 입력할 수 있는 대화상자가 출력되므로 이 대화상자에 이름을 입력

 

레이블 1개는 lblState 다른 하나의 레이블은 lblTap 그리고 이미지 뷰는 imgView로 연결

 

=>ViewController.swift 파일에 터치 관련 메소드를 작성

 

    //터치를 하면 호출되는 메소드
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        //터치 1개 가져오기
        let touch = touches.first 

        //두드린 횟수 가져오기
        let cnt = touch!.tapCount

        //출력
        lblTap.text = "\(cnt) 번 두드림"
        lblState.text = "터치 시작"
    } 

    //터치가 종료되었을 때 호출되는 메소드
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        lblState.text = "터치 종료"
    }  

    //터치가 움직일 때 호출되는 메소드
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        //터치 1개 가져오기
        let touch = touches.first
       
        //터치가 이미지 뷰에서 발생한 경우에만
        if touch!.view == imgView{

        //이미지 뷰를 터치가 발생한 지점으로 이동
        imgView.center = touch!.location(in: self.view)
        }
    }

 

=>터치 이벤트는 뷰의 속성 중에서 isUserInteractionEnabled 속성이 true 인 경우만 인지를 합니다.

Label 이나 ImageView에 터치를 사용할려면 이 속성의 값을 true로 설정

인터페이스 빌더에서는 속성 인스펙터에서 UserInteractionEnabled 에 체크를 해주면 됩니다.

 

5)ViewController에 여러 개의 뷰가 존재하고 여러 개의 뷰에서 터치를 처리해야 하는 경우에 이 방식을 사용합니다.

뷰가 1개나 2개 정도이면 Gesture를 이용하는 것이 효율적입니다.

 

 

9.회전 처리

1)앱이 실행될 때의 앱의 방향을 설정하고자 하는 경우

AppDelegate.swift 파일에 func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?)-> UIInterfaceOrientationMask

메소드를 오버라이딩 해서 방향을 리턴하면 됩니다.

가로 방향으로 시작하고자 하는 경우에만 오버라이딩합니다.

 

2)뷰 컨트롤러의 회전 지원 여부를 결정하는 프로퍼티

var shouldAutorotate: Bool { get }

=>get 안에서 false를 리턴하면 회전을 지원하지 않고 true를 리턴하면 회전을 지원합니다.

기본값이 true 이므로 회전을 지원하지 않고자 할 때만 false를 리턴하면 됩니다.

 

3)회전이 발생했을 때 호출되는 메소드 - 예전에는 다른 메소드

=>뷰의 크기가 변경되었을 때 호출되는 메소드

func viewWillTransition(to size:CGSize, with coordinator:UIViewControllerTransitionCoordinater){

=>UIDevice.current.orientation.isLandScape 의 값을 조사해서 true 면 가로 false이면 세로입니다.

}

 

=>var didRotate:(NSNotification) -> Void = {notification in 

UIDevice.current.orientation.isLandScape 의 값을 조사해서 처리

}

 

4)시뮬레이터 회전 : Command(Window키) + 방향키

 

5)회전을 감지해서 방향을 콘솔에 출력하기

=>ViewController.swift 파일에 메소드 재정의

//뷰의 크기가 변경되었을 때 호출되는 메소드
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        if UIDevice.current.orientation.isLandscape{
            NSLog("가로")
        }
        else{
            NSLog("세로")
        }
    }

    //회전 지원 방향을 설정하는 프로퍼티
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
        return [.all]
    }

 

10.흔들기 이벤트

=>motion 이벤트도 뷰 컨트롤러가 처리

=>motion은 touch 와 메소드 이름이 유사 

=>touch 대신에 motion으로 시작

 

=>흔들기 이벤트를 사용하고자 하는 뷰 컨트롤러는 FirstResponder 가 될 수 있어야 하고 FirstResponder 가 된 상태에서만 흔들기 이벤트를 처리할 수 있습니다.

=>FirstResponder: 현재 포커스를 가진 객체

 

=>흔들기 이벤트가 사용되는 대표적인 예는 아이폰 기본 앱 중에서 음악 재생 앱에서 음악 재생 리스트를 초기화할 때 사용합니다. 

 

1)FirstResponder가 될 수 있도록 해주는 프로퍼티를 오버라이딩

    //FirstResponder가 될 수 있도록 해주는 프로퍼티
    override var canBecomeFirstResponder: Bool{
        get{
            return true
        }
    }

 

2)viewDidLoad 메소드에 ViewController가 FirstResponder 가 되도록 설정

//현재 뷰 컨트롤러가 FirstResponder가 되도록 설정
//키보드를 사용할 수 있는 객체가
//FirstResponder가 되면 키보드가 화면에
//출력되고 키보드를 누르면 뷰에 입력됩니다.
self.becomeFirstResponder()

 

3)흔들기 시작하면 호출되는 메소드를 재정의

    //흔들기 시작하면 호출되는 메소드
    override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        NSLog("흔들기")
    }

 

11. Menu

=>Menu도 ViewController에서 설정

=>모바일에서 메뉴가 잘 사용되지 않음

메뉴바가 별도로 존재하지 않기 때문에 보여주기가 어려워서 

 

12. UIApplication 클래스

=>애플리케이션을 의미하는 클래스

=>직접 인스턴스 생성은 안되고 shared 라는 속성을 이용해서 접근을 합니다.

=>iOS에서는 시스템이 제공하는 클래스의 인스턴스들은 전부 그 클래스의 static 프로퍼티를 이용해서 접근이 가능합니다.

 

=>(AppDelegate)UIApplication.shared.delegate: 자신의 App의 AppDelegate 클래스의 인스턴스에 접근하는 방법 - 앱 사용 중에 모든 곳에서 데이터를 공유하고자 하면 AppDelegate 클래스에 프로퍼티를 만들고 이 속성을 이용해서 접근하면 됩니다.

 

=>UIApplication.shared.applicationIconBadgeNumber: 아이콘에 숫자 출력 - 0으로 설정하면 숫자가 안보이게 됩니다.

푸시 노티피케이션을 만들어서 푸시가 오면 숫자를 1씩 증가시키고 메시지를 읽거나 어떤 행위를 하면 숫자를 0으로 만들어서 초기화를 시킵니다.

 

13.클립보드도 존재

=>애플리케이션끼리 데이터를 공유할 수 있습니다.