# 기본 동작

작업에 필요한 기본 단축키들은 아래와 같다.

  1. Command + Shift + L : 라이브러리 열기
  2. Command + Shift + Y : 디버그 영역 열기
  3. Control + Command + Option + Enter : 코드 영역(어시트턴트) 열기
  4. Command + R : 빌드

스토리보드 제작에 필요한 화면 영역을 인터페이스 빌더라고 한다.

인터페이스 빌더 우측 하단에는 다섯가지 기능을 제공하는 버튼 그룹이 있다.

  1. Update Frames : 생성한 제약조건 및 Align에 맞춰 요소를 제자리로 위치시킨다.
  2. Align : 화면 기준으로 현재 선택한 요소의 수평 및 수직정렬
  3. Constraints : 화면 기준 위치와 요소의 너비 및 높이 등을 조절할 수 있다.

# 코드 작성

라이브러리를 열어 원하는 요소를 화면에 끌어다 놓아 생성한다.

어시스턴트를 열고 생성한 라이브러리 요소를 Control버튼을 누른 채로 드래그 하여 코드영역에 내려놓으면 해당 라이브러리를 코드화시킨 부분이 자동으로 생성된다.

Name은 변수 영역이다. Label요소의 경우 @IBOutlet weak var 변수명: UILabel!이라는 코드가 작성됨

버튼요소 생성 후에는 이벤트핸들러 함수를 작성하게 된다. 마찬가지로 드래그하여 코드 영역에 끌어다놓으면 변수 생성이 아닌 함수가 생성된다.

import UIKit

class ViewController: UIViewController {



    @IBOutlet weak var myLabel: UILabel!


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }


    @IBAction func buttonHandler(_ sender: UIButton) {
        myLabel.text = "클릭됨!"
        myLabel.textColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
    }

}

어시스턴트 연결문제

커스텀 뷰컨트롤러에 대해 스토리보드와 어시트턴트가 잘 연결이 되지 않는 경우 뷰 컨트롤러를 선택한 뒤 Identity Inspector의 Custom Class 이름을 연결하고자 하는 뷰컨트롤러.swift의 클래스 이름으로 작성하면 된다. (자동완성으로 알아서 연결해줌)

buttonHandler라는 이름으로 함수를 생성하였고 감지하는 이벤트의 타입은 Touch up Inside로 하였다. (일반적으로 많이 사용되는 이벤트라고 함)

커넥션 변경

버튼의 경우 액션 감지 후 다른 동작을 명령하는 핸들러 정의 외에 버튼요소 자체를 수정해야 되는 경우도 있다.

컨트롤 + 드래그로 어시스턴트에 코드 추가 시 Connection 셀렉박스 값을 Action이 아닌 Outlet으로 설정하면 됨

스위프트는 타입 기반의 언어이기 때문에 myLabel이라는 레이블 객체 내부 속성을 수정할때에도 각 타입에 맞는 값들을 집어넣어야 한다.

text속성을 통해 내부 텍스트를 수정할 수 있고 textColor에 컬러 관련 타입의 값을 넣어 색상을 수정할 수 있다.

컬러 지정을 위해 스위프트는 컬러 리터럴 기능을 제공한다.

#colorLiteral을 입력한 뒤 여는괄호 (를 입력하면 자동으로 색상 선택을 위한 선택지들이 나타남. UIColor 타입에 접근해도 됨

UIColor 헥사코드 함수로 확장하기

스위프트의 UIColor에서는 기본적으로 헥사코드를 얻어내는 함수를 지원하지 않는다. 편의생성자를 활용하여 헥사코드로 컬러코드를 변환해주는 코드가 많이 있으므로 사용하자.

import UIKit

extension UIColor {

    // Hex String -> UIColor
    convenience init(hexString: String) {
        let hexString = hexString.trimmingCharacters(in: .whitespacesAndNewlines)
        let scanner = Scanner(string: hexString)

        if hexString.hasPrefix("#") {
            scanner.currentIndex = scanner.string.index(after: scanner.currentIndex)
        }

        var color: UInt64 = 0
        scanner.scanHexInt64(&color)

        let mask = 0x000000FF
        let r = Int(color >> 16) & mask
        let g = Int(color >> 8) & mask
        let b = Int(color) & mask

        let red   = CGFloat(r) / 255.0
        let green = CGFloat(g) / 255.0
        let blue  = CGFloat(b) / 255.0

        self.init(red: red, green: green, blue: blue, alpha: 1)
    }

    // UIColor -> Hex String
    var hexString: String? {
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0

        let multiplier = CGFloat(255.999999)

        guard self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) else {
            return nil
        }

        if alpha == 1.0 {
            return String(
                format: "#%02lX%02lX%02lX",
                Int(red * multiplier),
                Int(green * multiplier),
                Int(blue * multiplier)
            )
        }
        else {
            return String(
                format: "#%02lX%02lX%02lX%02lX",
                Int(red * multiplier),
                Int(green * multiplier),
                Int(blue * multiplier),
                Int(alpha * multiplier)
            )
        }
    }
}


// 출처: https://www.hangge.com/blog/cache/detail_2305.html

이미지 리터럴

이미지를 다루기 위해서는 좌측 프로젝트 네비게이터 메뉴에서 Assets파일 내에 각종 이미지 애셋들을 드래그 앤 드롭하면 된다.

이후 코드상에 불러오기 위해서는 컬러리터럴과 동일한 방식으로 #imageLiteral입력 후 여는괄호를 입력하면 이미지 목록들이 선택할 수 있게 나타난다.

텍스트 정렬을 위해 사용되는 타입은 NSTextAlignment가 있고 열거형 타입이다. myLabel.textAlignment = NSTextAlignment.케이스명으로 활용한다.

기본 코드에 사용되는 것들

  1. @IBOutlet : 인터페이스 빌더 아웃렛(출구), 생성한 요소가 내부 속성 등의 변화를 감지하여 스토리보드로 내보냄
  2. @IBAction : 스토리보드로부터 이벤트를 감지하여 함수를 실행
  3. override func viewDidLoad() : 앱이 들어온 뒤 처음 실행시키는 함수, 웹 컴포넌트 componentDidMount사이클과 유사

# import Foundation

실제 스위프트 자체적으로 제공하는 기능은 매우 한정적이다. 이때 UIKit과 같은 Foundation Framework들을 임포트 하여 다양한 기능 (날짜, 네트워크 통신 등의)들을 사용할 수 있게 된다.

플레이그라운드 파일만 생성하더라도 첫줄에 import UIKit이 작성되어 있는 것을 확인할 수 있다.

각종 기본 기능 사용에는 import Foundation이 있어도 되지만 UIKit이 파운데이션을 포함하고 있기 때문에 UIKit을 가져오고 있음

애플에서 앱 제작에 필요한 계층을 네가지로 구성해놓았음

  1. Cocoa Touch Framework - 앱 UI를 다루는 데에 필요
  2. Media Framework - 사진 및 동영상 처리에 필요
  3. Core Services Framework - Foundation, 웹킷, 인앱결제 등에 필요
  4. Core OS Framework - 블루투스, 보안, 터치ID 등

# 요소 그룹화

특정 요소 생성후 이를 복사 및 그룹화 하여 배치하려는 경우가 있다. CSS 플렉스박스를 생각하면 됨

라이브러리에서 요소 생성후 Option키를 누른채로 스토리보드 내에 드래그 앤 드롭을 하면 요소 그대로 복사가 되어 생성된다.

해당 요소들을 모두 선택한 뒤 우측 하단 Embed in View 버튼을 클릭하여 Stack View를 선택하면 요소들이 그룹화 된다.

이 요소들을 제약조건과 함께 배치하기 위해서는 다음과 같은 것들이 필요하다.

  1. 상단 또는 하단 스페이싱
  2. 좌우측 스페이싱 (마진값)
  3. 요소들의 높이값
  4. 스택뷰 선택 - 어트리뷰트 Distribution설정, 박스 너비값 분배
  5. 요소 하나 선택 - Control + 드래그 후 배치하는 스택 뷰 다른 요소까지 드래그하여 나타난 드롭다운 메뉴 중 Aspect Ratio 선택, 우측상단 Size Inspector메뉴 선택하여 Multiplier 1:1로 설정

코드 분리

자바스크립트 모듈 시스템과는 다르게 스위프트에서는 빌드시에 모든 코드가 한곳에 모이게 된다.

열거형 타입 선언을 메인함수 내에 사용하지 않고 외부 Customtype.swift파일로 생성한 뒤 코드를 작성하면 별도의 export import 없이 코드를 불러올 수 있다.

// Type.swift
enum Type{
    case one
    case two
}
// ...
var myCase: Type = Type.one; // 자동으로 불러와서 사용 가능

자바스크립트 기준으로 이벤트핸들러에 전달되는 event 파라미터는 스위프트에서 sender가 그 역할을 한다.

@IBAction func resetButtonTapped(_ sender: UIButton) {
    guard let myTitle = sender.currentTitle else {return}

    // 나머지 코드
}

sender.currentTitle이 자바스크립트에서 event.target.value과 같은 역할을 하는 것이다.

# 커맨드 라인 활용하기

xcode 프로젝트 생성 시 macOS - Command Line Tools로 앱을 생성하면 커맨드라인을 활용한 앱을 제작할 수 있다.

터미널에서 사용자에게 입력받도록 해주는 함수는 readLine()이 있다.

# div태그

xcode UI 라이브러리중에는 UIView 요소가 있다. div태그와 유사하게 박스치는 역할을 함.

# Reference

  1. 인프런 - 앨런 swift 문법 마스터 스쿨 (opens new window)
  2. 스위프트 헥사코드 얻어내기 (opens new window)