일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- enum
- 문자열 보간법
- Realm
- 프로퍼티 관찰자
- swift
- 패스트캠퍼스후기
- 옵셔널 체이닝
- 기본문법
- 열거형
- 패스트캠퍼스
- userDefaults
- cancelAsyncWrite
- 함수
- ios
- TableView
- Git
- switch
- 직장인인강
- RawValue
- 패캠챌린지
- Background
- xcode
- 30개프로젝트로배우는iOS앱개발withSwift초격자패키지Online
- SeSAC
- Optional Chaining
- 인스펙터
- 독학
- Threading
- beginAsyncWrite
- 직장인자기계발
- Today
- Total
아삭아삭 iOS 개발
[TIL] 2022.07.12 (SeSAC iOS) 본문
오늘 공부한 내용들을 내가 잊지 않기 위해 기록합니다.
틀린 내용이 있을 수 있는 점 참고 부탁드립니다 :)
■ 오늘의 과제
1) Raw String
과제목표 : swift5에서 새로 등장한 rawstring이 무엇인지 알아보고, playground에서 실습해보기 (스스로 학습 및 구현)
(정리한 내용과 예시들은 playground로 구현해보며 내용이 길어져 별도 포스팅으로 업로드 예정입니다~)
//링크 예정 자리//
2) 감정 다이어리 프로젝트 코드 개선
과제목표 : 함수의 반환값, 열거형, 등을 활용해 감정 다이어리 프로젝트 코드 개선수정
■ 개선사항
<AS-IS> | <TO-BE> |
감정버튼 9개 개별 Outlet 연결 | 감정버튼 9개 모두 하나의 Outlet Collection 연결 |
스토리보드를 통한 감정버튼 Image 9개 개별등록 | 코드상 반복문(for문)을 통한 감정버튼 Image 9개 일괄등록 |
감정별 클릭 수가 담길 변수 9개 개별생성 | 감정별 클릭 수가 담길 배열 1개 통합생성 |
switch문을 사용한 감정일기 로직 구현 - 각 감정 9개에 해당할 경우, 클릭 수 개별증가 - 그 외 |
tag를 사용한 감정일기 로직 구현 - 클릭된 버튼의 tag에 해당하는 감정숫자 증가 및 출력 |
감정 레이블에서 String 출력 | 감정 레이블에서 Raw String 사용 (필요기능은 아니나 오늘 공부내용 활용 목적) |
■ 추가 공부 필요 Keyword
- tag를 사용한 추가적인 케이스 및 샘플
■ 상세코드
<AS-IS>
import UIKit
class ViewController: UIViewController {
var emotionDataArray: [Emotion] = [
Emotion(emotionalSlime: UIImage(named: "sesac_slime1.png")!, emotions: "행복해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime2.png")!, emotions: "사랑해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime3.png")!, emotions: "좋아해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime4.png")!, emotions: "분노해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime5.png")!, emotions: "심심해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime6.png")!, emotions: "지루해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime7.png")!, emotions: "당황해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime8.png")!, emotions: "서운해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime9.png")!, emotions: "슬퍼해")
]
@IBOutlet weak var slime1: UIButton!
@IBOutlet weak var slime2: UIButton!
@IBOutlet weak var slime3: UIButton!
@IBOutlet weak var slime4: UIButton!
@IBOutlet weak var slime5: UIButton!
@IBOutlet weak var slime6: UIButton!
@IBOutlet weak var slime7: UIButton!
@IBOutlet weak var slime8: UIButton!
@IBOutlet weak var slime9: UIButton!
@IBOutlet var emotionLabels: [UILabel]!
var n1: Int = 0
var n2: Int = 0
var n3: Int = 0
var n4: Int = 0
var n5: Int = 0
var n6: Int = 0
var n7: Int = 0
var n8: Int = 0
var n9: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
setUI()
}
// MARK: - 초기화면 ui설정
func setUI() {
for i in 0...8 {
// emotionButtons[i].setImage(emotionDataArray[i].emotionalSlime, for: .normal)
emotionLabels[i].text = "\(emotionDataArray[i].emotions) 0"
}
}
// MARK: - 감정버튼 클릭시 로직
@IBAction func buttonTapped(_ sender: UIButton) {
switch sender {
case slime1:
n1 += 1
emotionLabels[0].text = "\(emotionDataArray[0].emotions) \(n1)"
case slime2:
n2 += 1
emotionLabels[1].text = "\(emotionDataArray[1].emotions) \(n2)"
case slime3:
n3 += 1
emotionLabels[2].text = "\(emotionDataArray[2].emotions) \(n3)"
case slime4:
n4 += 1
emotionLabels[3].text = "\(emotionDataArray[3].emotions) \(n4)"
case slime5:
n5 += 1
emotionLabels[4].text = "\(emotionDataArray[4].emotions) \(n5)"
case slime6:
n6 += 1
emotionLabels[5].text = "\(emotionDataArray[5].emotions) \(n6)"
case slime7:
n7 += 1
emotionLabels[6].text = "\(emotionDataArray[6].emotions) \(n7)"
case slime8:
n8 += 1
emotionLabels[7].text = "\(emotionDataArray[7].emotions) \(n8)"
case slime9:
n9 += 1
emotionLabels[8].text = "\(emotionDataArray[8].emotions) \(n9)"
default:
print("오늘은 별 감정이 들지 않았습니다.")
}
}
}
<TO-BE>
import UIKit
struct Emotion {
var emotionalSlime: UIImage
let emotions: String
}
import UIKit
class ViewController: UIViewController {
var emotionDataArray: [Emotion] = [
Emotion(emotionalSlime: UIImage(named: "sesac_slime1.png")!, emotions: "행복해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime2.png")!, emotions: "사랑해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime3.png")!, emotions: "좋아해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime4.png")!, emotions: "분노해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime5.png")!, emotions: "심심해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime6.png")!, emotions: "지루해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime7.png")!, emotions: "당황해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime8.png")!, emotions: "서운해"),
Emotion(emotionalSlime: UIImage(named: "sesac_slime9.png")!, emotions: "슬퍼해")
]
@IBOutlet var slimeImages: [UIButton]!
@IBOutlet var emotionLabels: [UILabel]!
var emotionArray = [0, 0, 0, 0, 0, 0, 0, 0, 0]
override func viewDidLoad() {
super.viewDidLoad()
for i in 0...8 {
slimeImages[i].setImage(emotionDataArray[i].emotionalSlime, for: .normal)
emotionLabels[i].text = #"\#(emotionDataArray[i].emotions) "0""#
}
}
@IBAction func buttonTapped(_ sender: UIButton) {
emotionArray[sender.tag] += 1 // 클릭한 버튼의 tag 찾고, 해당 서브스크립트 감정숫자에 1 더해줌
emotionLabels[sender.tag].text = #"\#(emotionDataArray[sender.tag].emotions) \#(emotionArray[sender.tag])"# // 전체 감정숫자 출력
}
}
3) 신조어 검색기 프로젝트 코드 개선
과제목표 : 함수의 반환값, 열거형, 스위치 구문 등을 활용해 신조어 검색기 프로젝트 코드 개선수정
■ 개선사항
<AS-IS> | <TO-BE> |
신조어 데이터 dictionary로 정의 | 신조어 데이터 enum로 정의 |
해시테그 샘플용으로 dictionary의 key값 4개 랜덤추출 | 해시테그 샘플용으로 enum의 allCases에서 4개 랜덤추출 |
if구문을 사용한 신조어 검색결과 추출 로직 구현 - 공란으로 검색할 경우 - dictionary의 key값과 일치하지 않는 경우 - dictionary의 key값과 일치한 경우 |
switch구문을 사용한 신조어 검색결과 추출 로직 구현 - 각 신조어 rawValue에 해당하는 경우 - 그 외 |
■ 추가 공부 필요 Keyword
- CustomStringConvertible 프로토콜
- CaseIterable 프로토콜
- enum, switch 구문 활용 예시 등
■ 상세코드
<AS-IS>
import UIKit
class HomeViewController: UIViewController, UITextFieldDelegate {
var newCoinedWord: [String : String] = [
"윰차" : "유명인과 무명인을 차별한다는 뜻",
"알잘딱깔쎈" : "알아서 잘! 깔끔하고 센스있게~!",
"내또출" : "내일 또 출근한다",
"H워얼V" : "사랑한다는 뜻. 사랑해의 형태를 뒤집어서 표현한 것",
"많관부" : "'많은 관심 부탁드립니다'의 줄임말",
"회의주의자" : "뻑하면 회의하자고 하는 직장인",
"글설리" : "글쓴이를 설레게 하는 리플",
"Whyrano" : "왜이러냐의 사투리 표현인 와이라노를 영어로 적은 말",
"너 뭐 돼?" : "'너가 혹시 뭐라도 돼? 라는 뜻으로 유튜버 레오제이님으로 유명해진 유행어",
"당모치" : "당연히 모든 치킨은 옳다",
"돼지런하다" : "평소에는 행동이 느린데 먹을 때만 엄청 부지런하다",
"무물" : "무엇이든 물어보세요"
]
@IBOutlet weak var searchTextField: UITextField!
@IBOutlet var hashTags: [UIButton]!
@IBOutlet weak var resultLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
changeNewCoinedWordRandom()
setUI()
searchTextField.delegate = self
}
func setUI() {
// 검색 텍스트 필드 설정
searchTextField.keyboardType = .default
searchTextField.backgroundColor = UIColor.white
searchTextField.borderStyle = .line
searchTextField.layer.borderColor = UIColor.black.cgColor
searchTextField.attributedPlaceholder = NSAttributedString(string: "신조어를 입력해주세요!", attributes: [NSAttributedString.Key.foregroundColor : UIColor.lightGray])
searchTextField.autocorrectionType = .no
// 텍스트필드 내부에 좌측 여백주기
searchTextField.leftPadding()
// hashTags ui 설정
for i in hashTags {
i.backgroundColor = .white
i.layer.borderWidth = 1
i.layer.borderColor = UIColor.black.cgColor
i.setTitleColor(.black, for: .normal)
}
// 결과라벨
resultLabel.textColor = .black
resultLabel.font = UIFont.systemFont(ofSize: 18)
resultLabel.text = "신조어의 의미를 알아봅시다!"
}
// MARK: - 신조어 예제 해쉬테그 랜덤표기
func changeNewCoinedWordRandom() {
// 신조어 키값 4개를 랜덤으로 추출하기
var randomKeys: [String] = []
while randomKeys.count < 4 {
let randomkey = newCoinedWord.keys.randomElement()!
if !randomKeys.contains(randomkey) {
randomKeys.append(randomkey)
}
print(randomKeys.sorted())
}
// 버튼 4개에 반복하여 적용
for i in 0...3 {
hashTags[i].setTitle("\(randomKeys[i])", for: .normal)
hashTags[i].setTitleColor(.black, for: .normal)
hashTags[i].backgroundColor = .white
hashTags[i].layer.cornerRadius = 8
hashTags[i].clipsToBounds = true
hashTags[i].layer.borderWidth = 1
hashTags[i].layer.borderColor = UIColor.black.cgColor
}
}
// MARK: - 검색버튼 클릭시
@IBAction func searchButtonTapped(_ sender: UIButton) {
searchLogic()
changeNewCoinedWordRandom()
}
// MARK: - 키보드 엔터키 클릭시
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
searchLogic()
changeNewCoinedWordRandom()
return true
}
// MARK: - 신조어 검색 로직 및 키보드 내리기
func searchLogic() {
// searchTextField.text? == "" 대신 .isEmpty로 개선
if searchTextField.text!.isEmpty {
self.presentAlert(title: "신조어를 입력해주세요.")
return
} else if !newCoinedWord.keys.contains(searchTextField.text!) {
self.presentAlert(title: "찾으시는 신조어가 사전에 없습니다. 다른 신조어를 검색해주세요.")
return
}
resultLabel.text = newCoinedWord[searchTextField.text!]
view.endEditing(true)
}
// MARK: - view 탭시 (키보드가 올라와있다면) 키보드를 내려줌
@IBAction func tapGestureClicked(_ sender: UITapGestureRecognizer) {
view.endEditing(true)
}
}
<TO-BE>
import UIKit
enum NewCoinedWord: String, CustomStringConvertible, CaseIterable {
case 윰차
case 알잘딱깔쎈
case 내또출
case H워얼V
case 많관부
case 회의주의자
case 글설리
case Whyrano
case 너뭐돼
case 당모치
case 돼지런하다
case 무물
var description: String {
switch self {
case .윰차: return "유명인과 무명인을 차별한다는 뜻"
case .알잘딱깔쎈: return "알아서 잘! 깔끔하고 센스있게~!"
case .내또출: return "내일 또 출근한다"
case .H워얼V: return "사랑한다는 뜻. 사랑해의 형태를 뒤집어서 표현한 것"
case .많관부: return "'많은 관심 부탁드립니다'의 줄임말"
case .회의주의자: return "뻑하면 회의하자고 하는 직장인"
case .글설리: return "글쓴이를 설레게 하는 리플"
case .Whyrano: return "왜이러냐의 사투리 표현인 와이라노를 영어로 적은 말"
case .너뭐돼: return "'너가 혹시 뭐라도 돼? 라는 뜻으로 유튜버 레오제이님으로 유명해진 유행어"
case .당모치: return "당연히 모든 치킨은 옳다"
case .돼지런하다: return "평소에는 행동이 느린데 먹을 때만 엄청 부지런하다"
case .무물: return "무엇이든 물어보세요"
}
}
}
class HomeViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var searchTextField: UITextField!
@IBOutlet var hashTags: [UIButton]!
@IBOutlet weak var resultLabel: UILabel!
var word1: NewCoinedWord = .윰차
var word2: NewCoinedWord = .알잘딱깔쎈
var word3: NewCoinedWord = .내또출
var word4: NewCoinedWord = .H워얼V
var word5: NewCoinedWord = .많관부
var word6: NewCoinedWord = .회의주의자
var word7: NewCoinedWord = .글설리
var word8: NewCoinedWord = .Whyrano
var word9: NewCoinedWord = .너뭐돼
var word10: NewCoinedWord = .당모치
var word11: NewCoinedWord = .돼지런하다
var word12: NewCoinedWord = .무물
override func viewDidLoad() {
super.viewDidLoad()
changeNewCoinedWordRandom()
setUI()
searchTextField.delegate = self
}
func setUI() {
// 검색 텍스트 필드 설정
searchTextField.keyboardType = .default
searchTextField.backgroundColor = UIColor.white
searchTextField.borderStyle = .line
searchTextField.layer.borderColor = UIColor.black.cgColor
searchTextField.attributedPlaceholder = NSAttributedString(string: "신조어를 입력해주세요!", attributes: [NSAttributedString.Key.foregroundColor : UIColor.lightGray])
searchTextField.autocorrectionType = .no
searchTextField.leftPadding()
// hashTags ui 설정
for i in hashTags {
i.backgroundColor = .white
i.layer.borderWidth = 1
i.layer.borderColor = UIColor.black.cgColor
i.setTitleColor(.black, for: .normal)
}
// 결과라벨
resultLabel.textColor = .black
resultLabel.font = UIFont.systemFont(ofSize: 18)
resultLabel.text = "신조어의 의미를 알아봅시다!"
}
// MARK: - 검색버튼 클릭시
@IBAction func searchButtonTapped(_ sender: UIButton) {
searchLogic()
changeNewCoinedWordRandom()
}
// MARK: - 키보드 엔터키 클릭시
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
searchLogic()
changeNewCoinedWordRandom()
return true
}
// MARK: - 신조어 검색 로직 및 키보드 내리기
func searchLogic() {
let text = searchTextField.text
switch text {
case word1.rawValue:
resultLabel.text = word1.description
case word2.rawValue:
resultLabel.text = word2.description
case word3.rawValue:
resultLabel.text = word3.description
case word4.rawValue:
resultLabel.text = word4.description
case word5.rawValue:
resultLabel.text = word5.description
case word6.rawValue:
resultLabel.text = word6.description
case word7.rawValue:
resultLabel.text = word7.description
case word8.rawValue:
resultLabel.text = word8.description
case word9.rawValue:
resultLabel.text = word9.description
case word10.rawValue:
resultLabel.text = word10.description
case word11.rawValue:
resultLabel.text = word11.description
case word12.rawValue:
resultLabel.text = word12.description
default:
resultLabel.text = "검색 결과가 없습니다. 다른 신조어를 검색해주세요."
}
view.endEditing(true)
}
// MARK: - 신조어 예제 해시테그 랜덤표기
func changeNewCoinedWordRandom() {
// 신조어 키값 4개 랜덤 추출
var randomKeys: [String] = []
while randomKeys.count < 4 {
let randomkey = NewCoinedWord.allCases.randomElement()!
print(randomkey)
if !randomKeys.contains(randomkey.rawValue) {
randomKeys.append(randomkey.rawValue)
}
print(randomKeys.sorted())
}
// 버튼 4개에 반복 적용
for i in 0...3 {
hashTags[i].setTitle("\(randomKeys[i])", for: .normal)
hashTags[i].setTitleColor(.black, for: .normal)
hashTags[i].backgroundColor = .white
hashTags[i].layer.cornerRadius = 8
hashTags[i].clipsToBounds = true
hashTags[i].layer.borderWidth = 1
hashTags[i].layer.borderColor = UIColor.black.cgColor
}
}
// MARK: - view 탭시 (키보드가 올라와있다면) 키보드를 내려줌
@IBAction func tapGestureClicked(_ sender: UITapGestureRecognizer) {
view.endEditing(true)
}
}
오늘의 소감
코드를 짤 때 enum 및 switch구문이 필요한 경우와 tag사용이 필요한 경우에 대한 구분을 좀 더 생각해볼 필요가 있겠다.
tag사용법을 처음 알게되어 앞으로도 종종 적절한 상황에 잘 사용하고 싶다.
2), 3) 과제로직 중 함수의 반환값을 사용한 개선사항이 더 있을 것 같은데, 아직 잘 그려지지 않는다.
다른 새싹분들은 어떻게 구현했는지 궁금하다~!
개인적으로 문자열 보간법을 사용해서 그때그때 필요한 값을 (변수명을 입력하거나 i등을 활용해서) 유동적으로 출력할 수 있다는 점이 마음에 든다.
그래서 문자열 보간법 사용에 손이 잘 가는 것 같다.
데일리 과제는 아직까지 잘 하고 있는데, Mission사항까지 깊게 알아보지 못해서 아쉽다.
좀더 빠르게 과제를 끝내고 mission도 놓치지 않도록 시간분배 잘해야겠다!
참고자료
'TIL(Today I Learned)' 카테고리의 다른 글
[TIL] 2022.07.14 (SeSAC iOS) (0) | 2022.07.14 |
---|---|
[TIL] 2022.07.13 (SeSAC iOS) (0) | 2022.07.13 |
[TIL] 2022.07.11 (SeSAC iOS) (0) | 2022.07.11 |
[TIL] 2022.07.09~10 (SeSAC iOS) (0) | 2022.07.11 |
[TIL] 2022.07.08 (SeSAC iOS) (0) | 2022.07.08 |