-
@Published 프로퍼티 래퍼를 protocol에 정의하기
문제 상황 Combine으로 작성한 코드를 테스트하는 중인데 @Published 프로퍼티 래퍼가 말썽입니다. ViewModel에 @Published 프로퍼티 래퍼 타입을 정의하고 ViewController에서 이 타입을 바인딩하여 ViewModel에 변화가 일어나면 ViewController가 감지할 수 있게 하기 위해서 사용했습니다. 위 상황을 코드로 간략하게 정리해봤습니다. 아래 코드는 책 목록을 보여주는 화면의 로직을 담당하는 ViewModel과 이를 바인딩하고 있는 ViewController입니다. bookList에 변화가 일어난다면 bookList publisher는 BookListViewController에 UI를 업데이트하라고 전달합니다. final class BookListViewModel..
-
ViewController 생명주기의 몰랐던 점 (feat. 트러블 슈팅)
ViewController 생명주기 호출 순서 iOS 개발을 한다면 ViewController 생명주기는 모두가 알고 있을 거예요. viewDidLoad -> viewWillAppear -> viewDidAppear -> viewWillDisappear -> viewDidDisappear 다른 뷰컨트롤러로 넘어가는 상황에서 현재 뷰컨트롤러의 viewWillDisppear가 먼저 호출될까 전환되는 뷰컨트롤러의 viewWillAppear가 먼저 호출될까? 도 디버깅을 해본다면 바로 알 수 있습니다. 테스트를 위해서 뷰컨트롤러의 모든 생명주기에 print문을 찍어볼게요. final class ViewController: UIViewController { override func viewDidLoad() { s..
-
[CoreAnimation] Layer에 CoreAnimation을 무한으로 체이닝할 수 있을까?
안녕하세요! 오늘은 코어애니메이션을 체이닝할 수 있는지에 대해 알아보려고 합니다. 그냥 체이닝이 아니라 무한 체이닝입니다! (살짝 스포하자면 실패했습니다.. 스레드문제인 거 같은데...) 일단 구현에 들어가보도록 할게요. 구현할 애니메이션은 아래 밤하늘이에요! 질문이 나오게 된 배경 위 질문이 왜 나오게 되었는 지 설명해볼게요. 먼저, 저는 밤하늘에 별이 반짝이는 애니메이션을 주고 싶었어요. 그래서 먼저 피그마로 별을 디자인했습니다! 왜 굳이 디자인을 해주었냐면, 별이 찍힐 좌표값을 알아야했기 때문입니다! 별을 구성하고 있는 모서리를 알아야 UIBezierPath로 경로를 그려줄 수 있어요. 이미지로 추출해서 layer의 contents로 넣어줘도 가능하지만 정밀한 컨트롤이 불가능할 것 같아서 직접 만들..
-
[CoreAnimation] 물체를 path 따라 움직이기 (feat. 우주비행사 날리기)
오늘은 이 우주비행사를 원하는 경로로 움직여보려고 합니다! 먼저 지난번에 알아본 CAKeyframeAnimation와 UIBezierPath의 개념에 대한 이해가 필요해요. 아래 두곳에 정리해두었는데 참고하시면 좋겠습니다! https://github.com/wody-d/woody-iOS-tip/blob/main/TIL_2022:10:19_uibezierpath.md GitHub - wody-d/woody-iOS-tip: 🐶 iOS에 대한 소소한 팁들과 개발하다 마주친 버그 해결기, 그리고 오늘 🐶 iOS에 대한 소소한 팁들과 개발하다 마주친 버그 해결기, 그리고 오늘 배운 것들을 모아둔 레포 - GitHub - wody-d/woody-iOS-tip: 🐶 iOS에 대한 소소한 팁들과 개발하다 마주친 버그 ..
-
[CoreAnimation] AnchorPoint, position의 관계 (feat. SwiftUI에선 anchortPoint가 없다..?)
뷰의 레이아웃을 위치시킬 때, 오토레이아웃을 사용하면 사실 frame, anchorPoint 등 레이아웃 관련 프로퍼티는 크게 신경 쓰지 않아도 됩니다. 그런데, 이번 프로젝트에서 frame을 이용해야 하는 조금 어려운 애니메이션을 구현해보는 구현 내용이 있었고 구현을 하다보니 이전에 공부하다 헷갈렸던 내용과 똑같은 곳에서 헷갈렸습니다. 그래서 이 글은 저와 비슷하게 헷갈리는 분들이 있을 수 있기 때문에 작성했습니다. layer프로퍼티에 있는 position은 무엇을 나타내는 값일까요? 라는 질문이 나오기까지의 과정을 설명하겠습니다. 먼저, Core Animation Basics 문서를 읽다보면 중간에 아래 그림이 나옵니다. "anchor point가 layer의 position에 얼마나 영향을 미치는지..
-
[CoreAnimation] Layer Masking (feat. 키 모양 만들기)
안녕하세요! 오늘은 레이어 마스킹에 대해서 알아보려 합니다. 트러블 슈팅도 조금 있습니다. 뷰의 일부를 잘라서 보여주고 싶은 애니메이션 구현 내용이 있었습니다. 보통 뷰의 모서리부분을 둥글게 자르는 프로퍼티로 layer.cornerRadius와 maskToBounds를 사용했습니다. 하지만 저희가 완전히 원하는 모양으로 잘라서 일부만 보여주고 싶은 상황이었습니다. 이 상황은 layer의 mask 프로퍼티를 이용해서 해결할 수 있었습니다. 애플에선 이렇게 설명을 합니다. An optional view whose alpha channel is used to mask a view’s content. 뷰의 콘텐츠를 마스킹하는데 알파 채널을 사용하는 선택적 뷰라고 해석할 수 있는데 뷰의 일부만을 보여주고 싶을 때..
-
[CoreAnimation] CAReplicatorLayer 알아보기
CAReplicatorLayer 위치, 색깔, 시간 등의 transformation 룰을 지키면서 하나의 레이어를 복제해서 복잡한 레이아웃을 구성해주는 객체입니다. let replicatorLayer = CAReplicatorLayer() let redSquare = CALayer() redSquare.backgroundColor = NSColor.white.cgColor redSquare.frame = CGRect(x: 0, y: 0, width: 100, height: 100) let instanceCount = 5 replicatorLayer.instanceCount = instanceCount replicatorLayer.instanceTransform = CATransform3DMakeTrans..
-
[Programmers] 수식 최대화 (Level 2)
문제 https://school.programmers.co.kr/learn/courses/30/lessons/67257 프로그래머스 코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요. programmers.co.kr 문제 요약 연산자가 "+", "-", "*(곱셈)" 3가지가 있는 수식이 있습니다. 연산자들의 우선순위는 같은 게 없고, 항상 우위에 있는 게 있습니다. 연산자의 우선순위를 예를 들면, *(곱셈), + > - (❎) *(곱셈) > + > - (✅) *(곱셈) > - > + (✅) 와 같이 동일한 우선순위를 정의할 수 없습니다. 이런 상황에서 연산 수식을 최대화할 때의 상금 금액을 구하는 문제..
-
[Swift] string radix initializer
Swift radix 구현 방법 보통 아래와 같이 함수를 구현한다. func radixTo(_ radix: Int, with number: Int) -> String { var result: String = "" var number: Int = number while number > 0 { result.append("\(number % radix)") number /= radix } return String(result.reversed()) } let number = 10 let radix2: String = radixTo(2, with: 10) // 1010 let radix3: String = radixTo(3, with: 10) // 101 하지만 swift는 String의 initializer로 ..
-
[Swift] 영문자로만 이루어진 String 알아내기 + String Index 쉽게 접근하기
영문자로 된 글자만 유효하고, 기타 공백, 숫자, 특수 문자가 들어있는 경우는 제외하는 경우 Swift로 코드를 어떻게 짜볼까? 두가지 방법이 있을 수 있다. 1. 기타 공백, 숫자, 특수 문자의 문자열을 정의해서 포함하는 지 여부 확인 2. 영문자인 문자열을 정의해서 포함하는 지 여부 확인 func makingArr(_ str: String) -> [String] { var result = [String]() for i in 0.. Bool { for character in str { if "~₩!@#$%^&*()_-+=}{\";:/?.>,
-
[Stash] 커밋하기는 껄끄럽고 브랜치는 변경해야할 때 (feat. Fork)
#Git #Fork #Stash Git의 기능 중 하나인 stashing에 대해 새롭게 알게 되어 포스팅해보자 한다. Stashing이란? 한 가지 상황을 예로 들어보자. 어떤 프로젝트의 한 부분을 담당하는 중이다. 뭔가 작업하는 일이 있고, 갑자기 다른 요청이 들어와서 잠시 브랜치를 변경해야 할 일이 생겼다. 이런 상황에 아직 완료하지 않은 일을 커밋하는 것이 꺼려진다. (이전엔 하던 작업을 후딱 완료하고 브랜치를 변경하거나 정말 급하게 변경해야할 땐 "~~~하는중" 라고 commit 메세지를 남겼었던 기억이 있다..) 하지만, Stash 명령을 사용하면 커밋하지 않고 나중에 다시 돌아와 작업을 할 수 있다. git Stash 명령은 워킹 디렉토리에서 수정한 파일들만 저장하게 된다. Stash는 Mod..
-
[Programmers] 위장
문제링크 👉 https://programmers.co.kr/learn/courses/30/lessons/42578?language=swift 문제 이해 스파이들이 매일 다른 옷으로 위장하는데 그 경우의 수를 구하는 문제입니당 문제 풀이 문제 입출력 예 1번을 보면, headgear로는 "yellowhat", "green_turban" 2개가 있고 eyewear로는 "bluesunglasses" 1개가 있습니다. 그래서 스파이가 옷을 입는 경우의 수로는 1. yellow_hat 2. blue_sunglasses 3. green_turban 4. yellow_hat + blue_sunglasses 5. green_turban + blue_sunglasses 이렇게 5개를 생각할 수 있어요. 옷의 종류는 한개..