일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- NavigationSearchBar
- ReferceCycle
- class struct
- UIKit
- 양궁대회
- @escaping
- Input Output
- UserDefaults
- CoreData
- 롤케이크 자르기
- Carousel CollectionView
- wil
- Array vs Linked List
- 강한 참조 순환
- 면접을 위한 CS전공 지식 노트
- firebase
- Reference Cycle
- 프로그래머스
- coremotion
- 테이블뷰 나누기
- CarouselCollectionview
- 자료구조
- TableView Section
- til
- 면접을 위한 CS 전공 지식 노트 Tree
- SWIFT
- retain cycle
- tableview section별 다른 cell적용
- TableView
- Value Type Reference Type
- Today
- Total
목록분류 전체보기 (63)
개발하는 동글 :]
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. 문제 상황 개인과제를 진행하던 중 viewController가 deinit이 되지 않는 문제가 발생하였다. 무엇인가가 강한 참조순환이 되고 있어서 메모리에서 해제되지 않는 것이라고 판단하였다 그렇기에 처음으로 한 시도는 viewController을 사용하는 클로저에 모두 [weak self]를 붙이기 시작하였다. 그럼에도 viewController은 메모리에서 해제되지 않았기에 어떤 부분에서 강한 참조순환이 생기는지 찾기 시작하였다 2. 그래서 어디서 발생하는가? class ToDoListCell: UITableViewCell { var cellDelegate: ButtonTappedDelegate? } extension ToDoListViewController: UITableViewDelegate..
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. MVVM 양식에 맞게 코드를 적어보자! 아직은 아키텍처 패턴은 잘 모르겠지만 MVVM에 맞게 한 번 코드를 짜보자! 그럼 MVVM은 뭘까? MVVM 패턴을 사용하는 경우 앱은 다음 계층으로 나뉩니다. 모델 계층은 비즈니스 데이터를 나타내는 형식을 정의합니다. 여기에는 코어 앱 도메인을 모델링하는 데 필요한 모든 항목이 포함되며, 종종 코어 앱 논리가 포함됩니다. 이 계층은 뷰 및 뷰 모델 계층과는 완전히 별개이며, 클라우드에 부분적으로 상주하는 경우가 많습니다. 뷰 계층은 UI를 정의합니다. 태그에는 특정 UI 구성 요소와 다양한 뷰 모델 및 모델 멤버 간의 연결을 정의하는 데이터 바인딩이 포함되어 있습니다. 경우에 따라 코드 숨김 파일은 UI를 사용자 지정하거나 조작하는 데 필요한 추가 코드를 포..
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. 목표? 일단 구현한 후 코드를 이해하는 것을 목표로 CoreData를 사용해보자. 2. 구현 2.1 CoreData의 Model 만들기 먼저 새롭게 CoreData의 Data Model 파일을 만들어준 뒤 Entities를 새롭게 하나 만들어서 원하는 속성들을 만들어준다. 2.2 AppDelegate파일 수정 //AppDelegate // MARK: - Core Data stack lazy var persistentContainer: NSPersistentContainer = { let container = NSPersistentContainer(name: "MyToDoApp_3") container.loadPersistentStores(completionHandler: { (storeDescrip..
1. 왜 UIButton을 커스텀하게 되었는가? 위의 이미지처럼 버튼을 3번 사용하게 되는데 중복되는 코드들을 줄일 수 없을까?라는 고민에서 시작하게 되었다. 그 고민의 결과로 UIButton을 커스텀해보자는 생각을 하게 되었다. 2. 사용 전과 후 비교 func setUpCheckListButton(){ view.addSubview(checkListButton) checkListButton.setTitle("title", for: .normal) // 중복 checkListButton.setTitleColor(.link, for: .normal) // 중복 checkListButton.snp.makeConstraints { make in make.centerX.equalTo(view.snp.center..
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[\..
1. 클로저의 강한 참조 순환은 왜 발생할까? class HTMLElement { let name: String let text: String? lazy var asHTML: () -> String = { if let text = self.text { return "\(text)" } else { return "" } } init(name: String, text: String? = nil) { self.name = name self.text = text } deinit { print("\(name) is being deinitialized") } } 해당 클래스는 name과 text, lazy asHTML 속성을 가지고 있다. 그리고 asHTML속성을 살펴보면 text에 따라 값을 반환하는 함수이다. ..
1. ScrollView 만들기 private let contentScrollView = UIScrollView() 1. 먼저 ScrollView 컴포넌트를 생성해 준다. private func setUpContentScrollView(){ view.addSubview(contentScrollView) contentScrollView.snp.makeConstraints{ make in make.edges.equalTo(view.safeAreaLayoutGuide) } } 2. 뷰에 addSubView를 해준 다음 스크롤 뷰의 상, 하, 좌, 우 제약을 잡아준다. 2. ContentView 만들기 private let contentView = UIView() 1. ContentView를 UIView로 생성..
import Foundation func solution(_ topping:[Int]) -> Int { var array1:[Int:Int] = [:] var array2:[Int:Int] = [:] var count = 0 for i in topping{ if array1[i] == nil{ array1[i] = 1 } else { array1[i]! += 1 } } for i in topping{ if array1[i]! == 1{ array1[i] = nil } else { array1[i]! -= 1 } if array2[i] == nil{ array2[i] = 1 } else { array2[i]! += 1 } if array1.keys.count == array2.keys.count{ coun..