콘텐츠로 건너뛰기
Home » swift » Page 7

swift

Tap and Hold 구현하기 – iOS, Swift

tap and hold 구현하기

UIButton은 기본적으로 단일 탭에 대해서 액션 메시지를 발신하게끔 디자인되어 있고, 따라서 별도의 UITapGestureRecognizer가 없어도 동작할 수 있다. 하지만 더블탭, 트리플 탭이나 길게 누르기등의 동작에 대해서는 여타 다른 UIView들과 마찬가지로 동작 인식기를 필요로한다. 더 보기 »Tap and Hold 구현하기 – iOS, Swift

대용량 텍스트 파일을 한줄씩 읽기 – StreamReader를 작성하자

특정한 텍스트 파일을 읽어들여서 한 줄씩 처리하는 방법에서 가장 간단한 구현은 Stringinit(contentOfURL:encoding:)을 이용하여 텍스트 파일의 내용 전체를 하나의 문자열로 만든 다음에, 개행 문자를 이용해서 자르는 것이다.

let path = "~/Downloads/sample.txt"
let url = URL(fileURLWithPath: (NSString(string:path).expandingTildeInPath) // #1, #2
if let s = String(contentsOf: url) {
    for line in s.components(separatedBy:.newlines) {
        print(line)
    }
}

더 보기 »대용량 텍스트 파일을 한줄씩 읽기 – StreamReader를 작성하자

커스텀 뷰로 만든 UI 컴포넌트의 포커스링 그리기 – Cocoa

포커스 링

코코아 UI 요소에서 현재 포커스를 받은 UI 컴포넌트는 외부에 흐릿한 푸른 색 후광이 그려지며, 현재 포커스를 받고 있는 입력 디바이스라는 점을 시각적으로 피드백한다.  시중의 코코아 관련한 대부분의 책에서는 다음과 같이 draw: 메소드 내에서 포커스링을 그리는 것으로 포커스링을 흉내낼 수 있다고 한다. 1

override func draw(_ dirtyRect: NSRect) {
    // 배경을 칠하고,
    super.draw(dirtyRect)
    self.bgColor.set()
    NSBezierPath.fill(bounds)
    // 자신이 속한 윈도에서 자기가 제1응답자라면?
    if let fr = window?.firstResponder, fr === self {
        // 포커스 컬러로 세팅하여, 자신의 테두리 영역을 그린다.
        NSColor.keyboardFocusIndicatorColor.set()
        NSBezierPath.setDefaultLineWidth(4.0)
        NSBezierPath.strokeRect(bounds)
    }
}

그리고 제 1 응답자가 되었을 때 포커스링을 그리기 위해서는 뷰가 응답자 상태에 진입하거나 빠져나올 때마다 뷰를 새로 그리도록 갱신해야 한다.

override var acceptsFirstResponder: Bool { return true }
override func resignFirstResponder() -> Bool {
    NSLog("Resigning...")
    setNeedsDisplay(bounds)
    return true
}
override func becomeFirstResponder() -> Bool {
    NSLog("Becoming...")
    setNeedsDisplay(bounds)
    return true
}

더 보기 »커스텀 뷰로 만든 UI 컴포넌트의 포커스링 그리기 – Cocoa

배열리터럴로 만들 수 있는 클래스 정의하기

ExpressibleByArrayLiteral Set 인스턴스를 만들 때, Array와 같이 [1, 2, 3] 와 같은 식으로 배열 리터럴을 이용해서 초기화하는 것이 가능하다. 이렇게 배열 리터럴을 이용해서 초기화할 수 있는 것은 ExpressibleByArrayLiteral이라는 프로토콜을 따를 때 가능해지는 것으로, 커스텀 집합 혹은 컨테이너 타입을 만들 때, 이 프로토콜을 준수하면 배열리터럴로 해당 타입을 생성하는 것이 가능해진다. 이 프로토콜은 init(arrayLiteral:) 구현해주면 된다. 일전에 예제로 만들어 본 바 있는 Stack의 경우에도 이를 적용할 수 있다. 이 이니셜라이저는 실제로 [T] 타입의 배열로 된 인자를 받아서 각 원소들을 사용해서 스스로를 구성하게 되면… 더 보기 »배열리터럴로 만들 수 있는 클래스 정의하기

(Swift) 시퀀스와 관련된 Swift 표준 함수들

Swift 기본함수 중에는 <a href="https://soooprmx.com/archives/7047">Sequence</a>를 만드는 함수들이 제법 있다. 이러한 함수 중에서 가장 많이 사용할 법한 함수로 우선 stride()를 들 수 있다. 이 함수는 파라미터가 다른 두 가지 버전이 있는데 하나는 stride(from:to:by:) 이고 다른 하나는 stride(from:through:by:)이다. 첫번째 버전은 to: 뒤의 경계를 포함하지 않으며, 두 번째 버전은 ClosedRange처럼 뒤쪽 경계값을 포함한다. 이 함수들은 주로 for 문과 같이 쓰이면서 주어진 범위 내에서 step을 달리하여 건너뛰는 값들을 하나씩 얻을 수 있게 한다. 보통 정수범위의 이터레이션에 쓰이는데, 다음과 같이 10~20사이에서 0.2 씩 뛰면서 반복할… 더 보기 »(Swift) 시퀀스와 관련된 Swift 표준 함수들

Trie 자료구조 – Swift

for c in currentNode.children.keys.sorted() {트리(trie)자료 구조는 트리(tree)와 발음이 비슷한데, 실제로도 tree와 비슷한 형태로 문자열이나 이와 유사한 형태의 연속열들을 저장할 수 있는 자료 구조이다. 보통 영단어들을 저장할 때 유용한데, 다음과 같은 장점들을 가진다. 특정한 값을 찾을 때, 다른 구조들에 비해서 최악의 경우에서도 대개 더 나은 시간 복잡도를 보인다. 해시테이블과 달리 키 충돌을 고려할 필요가 없다. 특정한 요소에 다다르는 경로를 찾기위한 부가적인 해시 알고리듬을 요구하지 않는다. 알파벳순으로 정렬하기가 매우 쉽다. Trie는 어떤 단어의 첫글자와 그 다음에 올 수 있는 글자, 그리고 그… 더 보기 »Trie 자료구조 – Swift

enum 타입 사용법 정리 – Swift

Emumerations

“열거”타입은 임의의 관계를 맺는 값들을 하나의 타입으로 묶어서 타입-안전한 방식으로 다룰 수 있게 해준다. C에서도 enum 키워드를 이용해서 열거체를 선언할 수 있었는데, C의 열거체는 개별 정수에 대해서 다른 이름을 붙인 상수처럼 취급했다. 반면 Swift의 열거타입은 보다 유연하며 열거 타입 내의 개별 케이스가 단일 값을 대신해서 코드 상에서 구분하기 쉬운 이름을 갖는 것 보다 더 폭넓게 사용될 수 있다. 우선 각각의 케이스가 정수값이 아닌 실수나 문자열등의 다른 Swift 기본 타입의 값을 사용할 수 있다.

또한 각 케이스가 값 하나가 되는 것 외에 각각의 케이스가 연관 값을 갖는 것이 허용된다. 이 때에는 같은 열거형 내의 각각의 케이스가 서로 다른 타입의 연관 값을 갖는 것도 허용된다.

열거 타입은 Swift내에서 일급 클래스로 취급되며, 클래스가 가지는 계산 프로퍼티나 메소드를 포함하는 것도 가능하며, 이니셜라이저를 가지거나 확장도 할 수 있으며 따라서 프로토콜을 따르도록 정의될 수 있다.

더 보기 »enum 타입 사용법 정리 – Swift

required 가 붙은 이니셜라이저

UIView, UIViewController를 서브클래싱하는 코드를 작성하면서 init(frame:)을 오버라이딩하는 코드를 작성하면, Xcode는 매번 init?(coder:)가 정의되지 않았다는 컴파일 에러를 낸다. 일단 이 에러를 해결하려면 간단하게 부모 클래스의 이니셜라이저를 그대로 호출해주기만 하면 된다.

required override init?(coder aDecoder: NSCoder!) {
    super.init(coder: aDecoder)
}

왜 이 init?(coder:)는 자동으로 상속이 안되는 것일까?

잠깐, 이니셜라이저 관련한 프로그래밍 가이드에서는 required 이니셜라이저는 서브클래스에서 오버라이딩할 때 override를 붙이지 않는다고 했는데? Xcode는 override를 붙여야 한다고 한다. 이 부분은 재확인이 필요하다.
(https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-ID203)

더 보기 »required 가 붙은 이니셜라이저

(Swift) Set 타입

Set

일련의 값들이 순서를 가지고 (혹은 그 순서는 별로 중요하게 아니더라도) 집합을 이루고 있을 때 사용하는 가장 흔한 자료 구조는 배열이다. 배열은 원소들이 연속적으로 저장된다는 점에 기반하여 임의 원소에 빠르게 액세스할 수 있는 점과 선형적인 구조에 기반한 여러 테크닉들을 적용할 수 있다는 점에서 널리 사용된다.
하지만 배열은 집합과 관련된 문제에 대해서 항상 옳은 선택이 아닐 수 있다. 예를 들어 특정한 값이 집합내에 포함되어 있는지 여부는 contains(_:)를 통해서 손쉽게 알 수 있지만, 해당 메소드의 시간 복잡도는 $ O_{(n)} $ 이다. 이외에 배열은 두 개 이상의 배열에 대해서 합집합은 원소의 중복을 감안한다면 비교적 쉽게 얻을 수 있으나, 교집합이나 차집합에 대해서는 별도의 로직을 만들어서 이를 구해야하고 이 때의 성능도 거의 항상 $O_{(n)}$일 수 밖에 없다. 즉 개별 원소의 저장소로의 배열보다 집합 자체를 다뤄야 하는 상황이라면 배열보다 더 어울리는 자료구조가 있는데, 그것이 바로 Set이다.더 보기 »(Swift) Set 타입

프로퍼티와 전역변수 – Swift

Swift에서는 클래스나 구조체의 프로퍼티처럼 top-level의 자유 변수나 상수에 대해서도 계산된 프로퍼티나, `didSet`, `willSet`과 같은 옵저버 메소드를 정의하는 것이 가능하다.