일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- UIKit
- RxSwift
- swift 점선
- identifiable
- 타임라인 포맷팅
- button configuration
- uikit toast
- custom navigation bar
- 버튼 피드백
- swift bottomsheet
- rxdatasources
- task cancel
- reactorkit
- claen architecture
- coordinator
- scene delegate
- SWIFT
- custombottomsheet
- swift custom ui
- task cancellation
- DP
- swift navigationcontroller
- domain data
- swift dashed line
- traits
- custom ui
- swift 백준
- BFS
- Tuist
- swift concurrency
- Today
- Total
목록분류 전체보기 (84)
김경록의 앱 개발 여정
iOS 앱 개발자라면 누구나 익숙한 AppDelegate 방식. 앱 생명주기의 중심이었죠.그런데 이제는… Apple이 SceneDelegate를 강제하려고 합니다.정말 AppDelegate는 사라지는 걸까요?그리고 우리는 지금 무엇을 준비해야 할까요?🌀 SceneDelegate가 뭐길래?iOS 13부터 도입된 Scene 기반 Life Cycle은 앱을 하나 이상의 "Scene"으로 나누어 관리할 수 있게 해줍니다.간단히 말하면, 앱의 UI 상태를 독립적으로 관리할 수 있는 구조죠.예를 들어 iPad에서 여러 개의 앱 창(윈도우)을 동시에 띄울 수 있는 것도 Scene 구조 덕분입니다.🔥 그런데 왜 지금 이렇게 중요한가?Apple은 iOS 18.4부터 다음 조건을 강제합니다✅ Info.plist에 UI..
🔊 개요앱을 만들 때 Button은 필수적이고, 자동으로 터치 피드백을 제공합니다.(눌렸을 때 색깔이 바뀐다던가)하지만 종종 버튼을 눌렀을 때 아무런 반응이 없는 것처럼 보이는 문제를 겪게 되죠.그럴 땐 대부분 아래 이유 중 하나입니다.👇 1. AttributedString에서 색상을 직접 지정한 경우(configuraton 사용 시)configuration 사용 시 폰트를 지정할 때 AttriibutedString을 사용하게 됩니다.그때 foregroundColor 또한 지정이 가능하며 이것으로 글자색을 바꿀 수도 있습니다. let attributedTitle = AttributedString( "이미지", attributes: AttributeContainer([ .font..
✅ 구조적 동시성과 작업 취소구조적 동시성이란?부모 Task가 종료되기 전까지, 그 아래에서 생성된 자식 Task들도 모두 종료되어야 하는 규칙Swift의 async let, withTaskGroup 이 대표적인 구조적 동시성 도구취소는 위에서 아래로 전파됨 (부모 → 자식)즉, 부모가 취소되면, 구조적으로 연결된 자식들도 자동으로 취소됨구조적 동시성에 관한 이전 글 ) https://roks-apps.tistory.com/76 ✅ async let의 작업 취소특징async let 은 선언된 순간 비동기 작업을 시작하고, 자동으로 취소 전파 대상이 됨await 하기 전에 부모 Task가 취소되면, async let 작업도 취소됨특별히 .cancel() 하지 않아도 자동으로 정리(cleanup) 됨예시fu..
작업의 즉시 멈춤이 아닌, ‘취소를 전파’하는 개념Swift의 Task는 취소를 요청받더라도, 즉시 중단되는 것이 아니다.대신, “취소되었다는 신호” 를 내부적으로 가지고 있고, 작업 내에서 그 신호를 직접 확인하고 적절히 대응해야 함.이걸 "cooperative cancellation" 이라고도 함. 작업이 스스로 확인하고 정리하는 방식.(협동적 취소)부모-자식 관계와 취소 전파Swift의 structured concurrency에서는 부모 Task가 있고, 그 안에 자식 Task가 만들어질 수 있어.부모 Task가 취소되면, 자식 Task에게도 취소가 전파됨.하지만! 자식 작업이 완전히 끝날 때까지 (심지어 에러가 발생했더라도), 부모 작업은 기다림.즉, 취소되더라도 자식 작업은 graceful하게 ..

📘 개요MVVM 패턴에서 ViewModel(이하 VM)은 UI 요소와 독립적이어야 한다고들 합니다.그런데 그 '독립성'의 기준은 어디일까요?예를 들어, UIKit을 import 하지 않으면 독립적인 걸까요?UILabel의 텍스트처럼 화면에 표현될 값을 포장하여 다루는 건 괜찮을까요? (ex: n 개, n원)혹은 View가 isHidden일지 말지를 판단하는 Bool값을 ViewModel에서 들고 있는 건 괜찮을까요?이 글은 제가 실제로 진행한 프로젝트에서 MVVM을 따르고 있다고 생각했지만, 결과적으로는 안티 패턴에 가까운 코드를 작성했던 경험을 되돌아보며,ReactorKit을 기준으로 어떤 식으로 View와 ViewModel의 책임을 분리했는지 정리한 글입니다🎭 “State는 화면의 상태”라는 말의..

앱에서 사용자에게 간단한 알림을 제공할 때 흔히 사용하는 토스트메시지를 구현해 보았습니다.이번 포스팅에서는 iOS에서 토스트 메시지를 어떻게 구현했는지,그리고 이를 앱 전반에서 안전하고 일관되게 사용하기 위해 어떤 설계 원칙을 적용했는지에 대한 경험을 적어보겠습니다. 🍞 토스트 메시지 구현토스트 메시지는 화면 하단(혹은 지정한 위치)에 잠깐 나타났다가 사라지는 UI 컴포넌트입니다.저는 아래와 같이 토스트 메시지를 구현했습니다.import UIKitimport SnapKitfinal class ToastManager { static let shared = ToastManager() private var isShowingToast = false private init() {}..

이번에 다룰 커스텀 UI는 위와 같은 스타일입니다.단순한 버튼처럼 보이지만, 자세히 보면 테두리가 점선으로 되어 있는 걸 알 수 있습니다.UIKit에서 기본 제공하는 borderStyle 옵션은 다음과 같습니다:.none.line.bezel.roundedRect하지만 이 중 어떤 것도 점선 테두리는 지원하지 않죠.(제가 모르는걸 수도..?ㅎㅎ..)물론 UIView를 하나 덧씌워서 해결할 수 있을까도 고민했지만,문제는 단순한 overlay가 아니라 ‘점선’ 그 자체였습니다.결국 선택지는 하나.CAShapeLayer와 UIBezierPath를 이용해 직접 그리는 방식으로 가야 했습니다.이번 포스팅에서는 실전 예제와 함께,점선 테두리를 가진 UIButton을 만드는 방법을 정리해 보겠습니다.🧱 기본 버튼 스..

https://www.acmicpc.net/problem/2212 풀이 아이디어위 예제 입력을 예시로 설명 1. 오름차순으로 정렬 ( 1 3 6 6 7 9 )2. 앞자리랑 차이나는 거리 계산(gaps) -> ( 2 3 0 1 2) 3. 거리 차이를 최소로 만들어야 하고, 우리는 그걸 k개의 집중국 수 (그룹) 만큼으로 나눌 수 있다.센서를 K개의 그룹으로 나누기 위해선센서 사이를 K - 1번 끊어야 함왜냐면,6개의 센서를 2그룹으로 나누려면 → 1번 끊어야 하고6개를 3그룹으로 나누려면 → 2번 끊어야 하니까. 4. 고로 내림차순으로 정렬된 거리 배열에서 k-1 만큼 뗴어내고 나머지를 합쳐주면 됨 풀이let n = Int(readLine()!)!let k = Int(readLine()!)!var i..
Swift Structured ConcurrencySwift의 Structured Concurrency는 비동기 작업을 계층적으로 구조화하여 코드의 가독성과 안전성을 높이는 방식이다. 이 개념 내에서 async let과 TaskGroup은 병렬 처리를 위한 핵심 도구로 사용된다.1. async let 활용개요async let은 고정된 개수의 비동기 작업을 병렬로 실행할 때 사용된다. 선언된 async let은 즉시 실행되며, 이후에 await 키워드를 사용하여 결과를 기다릴 수 있다. 스코프를 벗어나기 전에 반드시 결과를 await해야 한다.예시 코드func fetchUser() async -> String { try? await Task.sleep(nanoseconds: 1_000_000_000)..

풀이 아이디어그리디 알고리즘 문제입니다.조건을 떠올리면 바로 풀 수 있는 문제인데30의 배수라는 조건을 떠올려보면,일단 끝이 무조건 0입니다.또 각 자릿수의 합이 무조건 3의 배수입니다. 이 조건을 따른 자세한 풀이는 아래와 같습니다. 풀이let n = readLine()!let arr = n.map { Int(String($0))! }// 0을 가지고있고, 배열 총합이 3의 배수인지 확인합니다.if arr.contains(0) && arr.reduce(0, +) % 3 == 0 { //숫자를 뺄수있는 문제가 아니므로 그냥 무조건 정답입니다. //다른 순서대로 섞어도 결국 각자리 합이 3의 배수가 안나오면 30의 배수가 될 수 없음 let result = arr.sorted(by: >).map ..