92 iOS SDK
** iOS SDK
=> SDK(Software Development Kit - API(Application Programming Interface) 라고도 하는데 이떤 플랫포의 애플리케이션을 개발하기 위한 함수나 클래스의 집합
=> iOS 애플리케이션 개발을 위한 클래스의 집합
=> Project(작업 단위 - 하나의 디렉토리) -> Target(Application)
실제 애플리케이션을 개발할 때는 1개의 프로젝트에 1개의 Target을 가지고 작업
포트폴리오를 만들 때는 1개의 프로젝트에 여러 개의 Target을 배치하는 형태로 작성
1. Project 생성
Xcode에서 [File] - [New] - [Project]를 선택
1) 플랫폼을 선택
iOS : iPhone, iPad, iPod 애플리케이션 개발
watch OS : 시계
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 : 증강현실 라이브러리를 포함한 프로젝트
* 게임이나 증강현실은 그래픽 출력 기술이 중요시 되는 분야
=> Open GL ES 와 같은 기래픽 가속 기술을 이용해서 구현
Apple에서는 Open GL ES 보다 성능이 좋은 Sprite Kit을 제공하고 Android에서는 Surface View 나 Texture View 등을 제공한다.
우리나라에서는 위의 기술을 직접 이용하는 것보다는 Hybrid App 개발 형태인 Unity 나 Unreal을 구현한 후 빌드를 각각의 플랫폼으로 하는 경우가 많다.
최근의 Unity는 빌드를 할 때 각 플랫폼의 그래픽 가속 기술을 이용
Unity에서 그래픽을 구현하면 빌드를 할 때 Sprite Kit으로 변경해서 빌드를 한다.
=> 우리나라에서는 대부분 게임이나 증강현실을 Unity 와 같은 프레임워크를 이용해서 구현하는 경우가 많다.
=> 대형 게임회사는 Native 기술을 사용하는 것을 권장
=> Document Based App : 문서를 출력하기 위한 라이브러리를 포함한 프로젝트
한글과 컴퓨터의 앱이나 PDF Viewer 앱들이 이 기반인데 문서를 공유할 수 있도록 처음부터 설정되서 만들어진다.
=> Master Detail App : iPad 용으로 등장한 프로젝트인데 왼쪽에 테이블 뷰를 배치하고 오른쪽에 일반 뷰를 배치해서 왼쪽에서 선택하면 오른쪽에 상세보기 형태로 출력하는 애플리케이션 프로젝트
세로모드일 때는 테이블 뷰가 위에 메뉴 형태로 숨어버리고 가로 모드 일 때는 테이블 뷰 형태로 출력되도록 되어 있는데 iPhone+ 시리즈에서 동일하게 사용이 가능해졌다.
=> Tabbed App : 하단에 탭을 배치
탭의 크기가 변할 수 있는데 세로보기에 맞춰진 형태로 디자인 되어 있어서 버튼이 5개까지만 배치
가로보기로 변경되었을 때 버튼의 모양이 이상해진다.
=> Sticker Pack App : 아이콘의 모임 형태의 앱
=> iMassage 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.storyboard : 앱의 화면 디자인을 위한 스토리보드
=> UI 전체 구조를 파악하는데 도움을 줌
5) Assets : 프로젝트에 필요한 리소스 디렉토리
6) LaunchScreen.storyboard : 앱의 시작 화면을 위한 스토리보드
7) Info.plist : 프로젝트 설정 파일
8) Products : 배포되는 앱이 저장되는 디렉토리
=> Xcode 의 프로젝트에서는 디렉토리는 아무런 의미가 없다.
내부에 디렉토리를 만들고 자원을 배치해도 전부 루트 디렉토리에 옮겨서 하나의 디렉토리에 모든 파일을 저장하고 이것을 압축해서 스마트 폰에 설치하고 설치가되면 압축을 풀어서 가지고 있게 된다.
5. swift 와 storyboard
=> swift 파일을 소스를 작성하는 파일
=> storyboard는 화면 다지안을 위한 파일
Storyboard 파일을 선택하면 Interface Builder(줄여서 IB - 여기 만들어지는 파일을 XIB, NIB 라고도 한다.) 가 실행된다.
이전에는 화면 단위로 디자인 - 각각의 화면을 NIB라고 한다.
현재는 애플리케이션 단위로 디자인 - Storyboard
=> 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 {
// Override point for customization after application launch.
return true
}
=> 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 : 크기 설정 - AutoLayout 설정도 여기서 한다
6) Connection Inspector : 뷰와 뷰컨드롤러 사이의 연결에 대한 설정
=> 뷰 컨드롤러에 어떤 변수에 연결되었는지 이벤트에 어떤 메소드가 연결되었는지 확인
** iOS 의 화면 출력 구조
window(예전에는 AppDelegate의 멤버여쏙 지금은 SceneDelegate의 멤버) -> View -> Layer(출력을 위해서 그리는 개념)
=> window 위에 View를 직접 배치해도 되지만 기본적으로 ViewController를 이용해서 View를 배치
=> View를 배치하게 되면 View에 출력ㄷ해야 데이터만 비지니스 로직을 View가 소유하고 있어야 한다.
데이터바 비지니스 로직을 수정할 때 View의 코드로 수정을 해야 한다.
=> ViewController라고 하는 클래스를 제공해서 이 클래스에 비지니스 로직을 작성하고 View를 배치하도록 해서 비지니스 로직이 생성한 데이터를 View에 출력하는 구조를 갖도록 한다.
=> window 위에 ViewController의 view를 출력하는 형태이다.
=> ViewController의 분류
ContentViewController : 실제 출력을 위한 뷰컨트롤러
ContainerViewController : 출력을 담당하지 않고 뷰 컨트롤러의 관리를 담당하는 컨트롤러 - Navigation, Tab, Page, Split View Controller등이 있다.
Initial View Controller : 맨 처음 보여지는 뷰 컨드롤러
인터페이스 빌더에서 보면 왼쪽의 화살표
프로젝트를 만들고 실행을 했는데 에러는 없는데 까만 화면만 출력되는 경우 - 맨 차음 보여져야 하는 뷰가 설정이 안된 경우이다.
시작하는 뷰 컨트롤러를 설정해주면 된다.
인스팩터에서 is Initial View Controller 란에 체크하면 된다.
** 인터페이스 빌드에 디자인 한 뷰와 swift 파일을 연결
1. 변수 연결 - IBOutlet(인터페이스 빌더에 다지안 한 뷰와 연결하는 변수를 만들 때 사용하는 예약어)
=> 인터페이스 빌더와 swift 파일을 모두 화면에 출력
=> 인터페이스 빌더에 디자인 한 뷰를 선택하고 마우스 오른쪽을 클릭하고 [New Referencing Outlet] 항목의 오른쪽 동그라미를 선택하고 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 이 아닌 View에서 디자인이 가능한데 직접 연결은 안된다.
=> 윈도우 프로그래밍을 하는 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개 배치하고 각 버튼의 touch up inside 이벤트에 메소드를 2개 연결 (click1, click2)
** 시작 화면 디자인
=> Splash View 라고도 하는데 LaunchScreen.storyboard 에 디자인하면 앱이 시작될때 화면에 출력
=> 일정시간 동안 계속 출력되기를 원하면 AppDelegate.swift 파일의 didLaunchingWithOptions 메소드에 sleep(시간)을 추가하면 된다.
1. 시작화면에 사용할 이미지를 프로젝트에 복사
2. LaunchScreen.storyboard
3. AppDelegate.swift 파일의 메소드를 대기 시간을 설정
** iOS Application의 이벤트 처리
1. Hierachy Pattern
=> 자주 사용하는 이벤트 핸들러를 클래스에 미리 만들어 두고 메소드를 재정의해서 사용하는 방식
2. Delegate Pattern
=> 이벤트를 처리할 객체를 연결하는 방식
1) selector 형태 : 메소드를 설정해서 연결하는 방식
2) gesture 형태 : 이벤트에 해당하는 gesture 클래스 객체를 만들고 gesture 객체를 설정하는 방식
3) Protocol을 이용하는 방식 : 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객체.instaniateViewController(withIdentifier : 뷰컨트롤러의id)
UIViewController 타입의 인스턴스가 리턴됨
=> UIViewController 타입으로 리턴되므로 실제 사용을 할 때는 자신이 만든 ViewController 타입으로 강제 현변환해서 사용해야 한다.
=> 인터페이스 빌더에서 뷰컨트롤러를 추가한 경우에는 반드시 Class 속성을 이용해서 자신의 클래스 타입을 설정해야 하고 Identifier를 이용해서 자신을 구별할 수 있도록 만들어 주어야 한다.
5. UIViewController의 속성
1) UIView view : 뷰 컨트롤러의 뷰 - 뷰 컨트롤러에서는 최상위 뷰
2) UINavigationController navigationController, UITabBarController tabBarController
=> 2개의 속성은 nil이 될 수 있다.
=> 뷰 컨트롤러가 NavigationController나 TabBarController에 포함된 경우에 사용할 수 있는 속성
3) UINavigationItem nacigationItem, 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. UIViewConroller에서의 Touch 이벤트 처리
=> iOS에서는 터치이벤트가 바랭하면 FirstResponder에서 처리를 요청
1) UIResponder 클래스
=> 이벤트를 받을 수 있는 iOS 뷰의 최상위 클래스
=> UIResponder로 부터 상속을 받는 클래스는 터치 이벤트를 처리할 수 있다.
=> 관련된 메소드와 속성
canBrecomFirstResponder : 맨 처음 이벤트 처리를 위한 객체가 될 수 있는지 여부를 설정
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 파일에 터치 관련 메소드를 작성
//
// ViewController.swift
// TouchEventApp
//
// Created by Lee Seungbum on 2020/08/14.
// Copyright © 2020 Lee Seungbum. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var imgView: UIImageView!
@IBOutlet weak var lblTap: UILabel!
@IBOutlet weak var lblState: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
//터치를 하면 호출되는 메소드
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//터치 1개 가져오기
let touch = touches.first
//두드린 횟수 가져오기
let cnt:Int = 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)
}
}
}
=> 터치 이벤트는 뷰의 속성 중에서 isInteractionEnabled 속성이 true인 경우만 인지를 한다.
Label 이나 ImageView에 터치를 사용할려면 이 속성의 값을 true로 설정해야한다.
인터페이스 빌더에서는 속성 인스펙터에서 User Interaction Enabled 에 체크를 해주면 된다.
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.proentaion.isLandScape 의 값을 조사해서 처리
//뷰의 크기가 변경될 때 호출되는 메소드
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 가 되도록 설정
override func viewDidLoad() {
super.viewDidLoad()
//현재 뷰 컨트롤러가 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. 클립보드로 존재
=> 애플리케이션끼리 데이터를 공유할 수 있다.