일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 면접을 위한 CS 전공 지식 노트 Tree
- Array vs Linked List
- CoreData
- tableview section별 다른 cell적용
- class struct
- Input Output
- firebase
- CarouselCollectionview
- TableView Section
- 자료구조
- 테이블뷰 나누기
- SWIFT
- @escaping
- 롤케이크 자르기
- Value Type Reference Type
- coremotion
- retain cycle
- Reference Cycle
- 양궁대회
- Carousel CollectionView
- til
- wil
- 강한 참조 순환
- 면접을 위한 CS전공 지식 노트
- UserDefaults
- NavigationSearchBar
- UIKit
- 프로그래머스
- ReferceCycle
- TableView
- Today
- Total
목록til (36)
개발하는 동글 :]

1. 앱 실행시 발생되는 일 main 함수가 실행 main 함수는 UIApplicationMain함수를 호출 UIApplicationMain함수는 앱의 본체에 해당하는 객체인 UIApplication 객체를 생성한다. nib파일을 사용하는 경우나, Info.plist 파일을 읽어들여 파일에 기록된 정보를 참고하여 그외에 필요한 데이터를 로드한다. 앱 델리게이트 객체를 만들고 앱 객체와 연결하고 런루프를 만드는 등 실행에 필요한 준비를 한다. 실행 완료를 앞두고 앱 객체가 앱 델리게이트에게 application:didFinishLaunchingWithOptions: 메시지를 보낸다. 2. 앱의 상태 변화 Not Running : 실행되지 않았거나, 시스템에 의해 종료된 상태 Inactive : 실행 중이지..
1. 구조체(Struct)에 대해서 설명해 주세요. 어떤 경우 사용하나요? 구조체란 프로퍼티를 저장하거나 메서드를 제공하고 이를 캡슐화할 수 있는 스위프트가 제공하는 타입입니다. 구조체의 특징은 값타입이며 상속이 불가능하고 타입캐스팅이 되지 않습니다. 이러한 구조체를 사용하는 경우로는 연관된 간단한 값의 집합을 캡슐화 하는 것만이 목적일 때 캡슐화된 값이 참조되는 것보다 복사되는 것이 합당할 때 구조체에 저장된 프로퍼티가 값 타입이며 참조되는 것보다 복사되는 것이 합당할 때 다른 타입으로부터 상속받거나 자신이 상속될 필요가 없을 때입니다. 지금 진행 중인 FinalTodo 프로젝트의 예시로는 간단한 UserData 및 FolderData 등 간단한 커스텀 타입을 정의할 때 이니셜라이저가 자동으로 생성되어..

1. 문제 상황 더보기 위의 이미지처럼 다양한 다양한 화면에서 비슷한 화면이 자주 사용된다. 그렇기에 반복되는 작업을 줄이고자 하였다. 2. 시도한 방법 2.1 LockScreenView 구현 더보기 // // LockScreenView.swift // FinalTodo // // Created by SeoJunYoung on 10/23/23. // import UIKit class LockScreenView: UIView { let titleLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title1) return label }() lazy var passwordCollectionView: UIColl..

1. 앱 잠금기능을 어떻게 구현할까? 앱 잠금기능을 db에 연동하여 사용할까라는 고민을 해보았다. 그래서 비밀번호를 찾는 기능까지 구현을 할까라는 생각을 하였다. 그렇게 참고할 앱들을 찾아보며 팀원들과 회의를 하던 중 팀원분이 다른 앱의 화면잠금 기능을 편리하게 구성하는 방법을 제시해 주셨다. 바로 아래와 같이 앱의 잠금을 암호를 분실했을 경우 앱을 삭제하고 재설치하는 방법이다. 이러한 방법으로 구현을 어떻게 할까 생각해 보았는데 그냥 유저의 비밀번호를 userDefault에 저장하여 관리하면 될 것 같다는 생각이 든다. 2. 이런 방식으로? 그럼 다음으로 어떠한 시점에 앱의 잠금 화면을 보여줘야 할까에 대한 고민이다. 보편적인 상황을 생각해 본다면 앱을 시작하는 순간, 다른 앱을 사용 하다가 다시 앱으..

1. 왜 dismiss후 present 가 필요 할까? 지금 구현한 LockScreen ViewController는 비밀번호가 일치 할 때 TargetViewController를 띄워주는 기능을 하고 있다. 이렇게 작동하게 될 때 NavigationController에 쌓이는 컨트롤러는 아래와 같다 여기서 문제가 발생하였다. LockScreen ViewController는 메모리에 올라와있어 불필요한 메모리와 이 후 뷰에서 접근이 가능한 상태가 되는 문제가 발생한다 그렇기에 비밀번호가 일치해서 다음 화면으로 넘어갈 때 LockScreenViewController를 dismiss한 후 targetViewController를 present하는 방법이 필요하다. 2. 어떠한 방법으로 해결할 수 있을까? 2.1..
1. 오늘의 회고 오늘 팀회의로 이슈 관리를 어떻게 할 것인가, 코드리뷰를 어떠한 방식으로 진행할 것인가,에 대한 방안을 회의하였다. 다양한 의견들이 있었고 나의 의견은 이슈관리는 깃허브의 이슈를 사용하는 것과 코드리뷰는 단순히 매일 밤 회의에서 화면 공유를 하는 방식으로 하자고 제안하였다. 그 후 회의의 결과로는 이슈관리는 깃허브 이슈관리를 사용, 코드리뷰는 매일 5시까지 pr을 올린 후 회의시간 전까지 각자 질문 및 코드를 설명하는 것으로 결정하였다. 이 회의를 통해 느끼게 된 것은 어떻게 협업을 할 것인가를 이유 없이 선정하게 된다면 팀원 모두가 힘든 시간을 가지게 된다. 만약 코드리뷰를 매일 밤 회의에서 진행하였다면 회의가 길어지고 팀원들 모두가 지치고 부담을 가지고 작업을 할 것 같다. 이렇듯 ..
1. 함수명으로 정확히 기능을 구별하여 구현하기 먼저 로그인 및 회원가입에 대한 정보를 전달해 주는 LoginResult 구조체를 만들어 주자. struct LoginResult { var isSuccess: Bool let email: String var errorMessage: String? } 그 후 Firebase에서 제공하는 메서드를 통해 각각 로그인과 회원가입에 대한 메서드를 만들어 준다. import Foundation import FirebaseCore import FirebaseAuth struct LoginManager { func trySignUp(email:String, password: String, completion: @escaping (LoginResult) -> Void) ..
1. Custom Delegate 구현하기 memoView.contentTextView.delegate = self memoView.optionCollectionView.delegate = self memoView.optionCollectionView.dataSource = self 평소 커스텀 뷰를 사용하며 커스텀 뷰에 포함된 collectionView 및 textView 등 다양한 컴포넌트의 delegate들을 이런 식으로 사용해 왔다. 그러다 문득 이러한 델리게이트를 통합하면 어떨까?라는 생각을 하여 구현을 시도해 보았다. 먼저 memoview에서 사용 될 collectionview만 하나로 만드는 작업으로 실험을 해 보았다. collection의 delegate와 datasoure에서 사용하는 메..

1. TIL 1.1 오늘의 회고 1.Task 관리 노션을 이용하여 팀원들이 어떠한 작업을 하고 있으며 남은 Task들을 관리하기 용이하게 만들어 일정 관리를 시작하였다. 위의 이미지처럼 작업 목록들을 미리 만들어 둔 뒤 회의를 통하여 담당자를 배정 및 진행상황을 확인하는 방법으로 프로젝트를 진행하기 시작하였다. 2. 와이어프레임 제작 팀원 모두가 참가하여 figma를 이용하여 와이어 프레임 제작을 하였다. 와이어 프레임을 사용하여 PointColor 및 Font 규격을 정하였다. 1.2 내일의 목표 1. 회의를 통해 작업 배정하기 2. 배정받은 작업 진행하기
1. Coredata VS UserDefaults 1.1 Coredata CoreData는 "데이터베이스"가 아니라 이를 지원하는 "프레임워크"라는 것이 특징입니다. 대규모 데이터를 저장하거나 체계적인 데이터베이스가 필요할 때 사용하는 것이 적절합니다. 링크드 리스트처럼 객체를 탐색하다 보니 탐색 성능은 비교적 나쁘고, Thread-Safe 하지 않아 Lock으로 동기화 처리를 해줘야 합니다. 대신, 원하는 데이터가 메모리에 올릴 수 있기 때문에 대규모 데이터를 저장해도 메모리 효율이 떨어지지 않습니다. 종합하면 대규모 데이터를 저장해야하는 상황에서 영속성 기능을 포함한 CoreData의 다른 기능도 필요하다면 CoreData를 선택하는 것이 적절해 보입니다. 1.2 UserDefaults UserDef..
1. Observables 패턴 사용해 보기! MVVM패턴을 사용하기 위해서 Observable 패턴 사용을 연습해 보았다 2. Observable 클래스를 생성 class Observable { var value: T { didSet { listener?(value) } } private var listener: ((T) -> Void)? init(_ value: T) { self.value = value } func bind(_ closure: @escaping (T) -> Void) { closure(value) listener = closure } } Observable 타입을 이용하여 bind 및 value값을 사용가능한 상태로 만들어준다. 3. Observable Type을 채택한다. fina..

1. 문제 상황 Observable class Observable { var value: T { didSet { listener?(value) } } private var listener: ((T) -> Void)? init(_ value: T) { self.value = value } func bind(_ closure: @escaping (T) -> Void) { closure(value) listener = closure } } ViewModel final class FTOPViewModel { var rangeBTtitle: Observable = Observable("단어장 선택") var vocaList: Observable = Observable([]) } bind viewModel.voca..

1. Try func textFieldDidChangeSelection(_ textField: UITextField) { var text = textField.text ?? "" let width = textField.frame.width if width > (Constant.screenWidth - (Constant.defalutPadding * 2)) { text.popLast() diaryAddView.titleTextField.text = text } } 처음 생각해 본 접근으로는 textfield의 넓이를 주지 않은 다음 textfield의 넓이가 글자수에 따라 넓어질 때 그 넓이가 일정한 넓이보다 커질 경우 마지막 글자를 제거한 뒤 텍스트 필드에 재할당 하는 방식이다. 결과는? 위의 동영상과 ..

1. 팀 프로젝트의 시작 1.1 팀 프로젝트에서의 역할 위의 이미지의 화면을 담당하기로 하였고 첫 화면은 Carousel CollectionView 를 적용하고 두번 째 modal 페이지는 다양한 animation을 적용해볼 예정이다 1.2 Carousel CollectionView의 적용 전에 연습해 보았던 Carousel CollectionView 를 적용한 모습 1.3 전체 코드 // // FeatureViewController.swift // oewoboka // // Created by 김도현 on 2023/09/25. // import Foundation import UIKit import SnapKit final class FeatureViewController: UIViewControlle..
1. TIL 1.1 오늘의 회고 1. 스터디에서 진행하는 프로젝트의 UI작업을 진행하며 Animation을 사용해 보았다. 2. 다른 분 코드의 코어 데이터에서 CRUD의 read 부분의 버그의 이유를 발견하였다. 1.2 내일의 목표 1. 스터디에서 진행하는 앱의 Animation 구현을 계속해서 시도해 보자! 2. Protocol, Enum, Generics에 대한 문법공부를 꾸준히 지속하자! 3. 기회가 된다면 디자인 패턴도 공부해 보자..?

1. 프로토콜 제약 func testFunc(num1:T, num2:T) -> Bool{ return num1 == num2 } testFunc(num1: 1, num2: 1) 이러한 제네릭 함수가 있다고 가정해 보자. 이 함수는 컴파일러에서 "Binary operator '==' cannot be applied to two 'T' operands"라는 에러를 알려준다 즉 이진 연산자 == 은 T라는 것에 적용할 수 없다는 것이다. 왜 이런 일이 발생할까? T는 Equatable 프로토콜을 채택하고 있지 않기 때문에 == 연산자를 사용할 수 없다. 그렇다면 문제를 해결하는 방법은 무엇일까? func testFunc(num1:T, num2:T) -> Bool{ return num1 == num2 } tes..
1. Generics(제네릭)이 해결하는 문제! 먼저 간단한 예시를 통해 알아보자! var num1 = 1 var num2 = 2 위와 같이 두 개의 변수가 있고 두 변수를 교환하는 함수를 작성해 보자. var doubleNum1 = 1.1 var doubleNum2 = 1.2 func swapTwoInts(_ a: inout Int, _ b: inout Int) { let tempA = a a = b b = tempA } swapTwoInts(&num1, &num2) func swapTwoDoubles(_ a: inout Double, _ b: inout Double) { let tempA = a a = b b = tempA } swapTwoInts(&num1, &num2) swapTwoDoubles(..
1. CoreData의 사용을 위한 CoreDataManager 구현 CoreData사용을 위해 CoreDataManager를 만들어 보는 것을 시도해 보자! CoreDataManager를 사용하기 위해 class를 만들고 싱글톤 패턴으로 만든 뒤 기본적인 프로퍼티를 만들어 보자. final class CoreDataManager{ static let shared = CoreDataManager() private init() {} private let appDelegate = UIApplication.shared.delegate as? AppDelegate private lazy var context = appDelegate?.persistentContainer.viewContext private let..

1. 구현 영상 2. 구현 1. 사용할 이미지 배열, imageView, collectionView 생성 var imageDatas = [ UIImage(named: "image1"), UIImage(named: "image2"), UIImage(named: "image3"), UIImage(named: "image4"), UIImage(named: "image5"), UIImage(named: "image6"), UIImage(named: "image7") ] var imageView = UIImageView() let myCollectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let collectionView..

1. DispatchQueue?공식문서의 내용을 살펴보면 DispatchQueue는 앱의 기본 스레드 또는 백그라운드 스레드에서 작업의 동기 또는 비동기 실행을 관리하는 Class이다. 이 것을 확인해 보기 위해 아래의 두 개의 메서드를 만들어서 확인해 보자.func shortWork(_ num:Int){ DispatchQueue.global().async { print("shortWork[\(num)]Start") print("1") print("2") print("3") print("4") print("5") print("shortWork[\(num)]End") } } func longWork(_ num:Int){ DispatchQueue.global().async { print("longWork[\..