주니곰의 괴발노트
SeSAC TIL - 22.07.15 본문
1. 오늘 배운 내용
- Show와 Modal 기능을 통해 화면 전환에 대해 배웠습니다.
- 뷰 컨트롤러의 생명주기에 대해 배웠고 어떤 화면에서 어떤 함수가 출력이 되는지(ex. ViewWillAppear 등) 확인해봤습니다.
- Userdefaults를 활용하여 데이터를 저장하고 활용해보는 것에 대해 배웠습니다.
2. Checklist
2-1. View Controller Transition
Show / Modal - Show를 화면전환에 사용할 경우 대부분의 뷰컨트롤러에서 기본 뷰컨트롤러 위에 덮어지는 방식으로 새로운 화면이 띄워집니다. 하지만 네비게이션 컨트롤러와 함께 사용할 경우, 덮어지는 방식이 아닌 오른쪽에서 왼쪽으로 화면전환이 되는 효과로 바뀌게 됩니다.
Modal의 경우에도 그냥 사용하면 Show와 똑같이 구현되나, 네비게이션 컨트롤러와 접목했을 시 화면 아래에서 올라오는 구조로 화면이 전환됩니다.
Push-Pop / Present-Dismiss - Push-Pop은 show방식의 화면전환을 할 때, 화면이 전환되는 방향을 의미합니다. Push는 새로운 화면으로 갈 때를 의미하고, Pop은 이전 화면으로 되돌아갈 때를 의미합니다.
Present-Dismiss는 Modal방식의 화면전환을 할 때, 화면이 전환되는 방향을 의미합니다. Present는 새로운 화면으로 갈 때를 의미하고, Dismiss은 이전 화면으로 되돌아갈 때를 의미합니다.
Segue - 스토리보드 상의 두 뷰 컨트롤러간 화면전환을 의미합니다. 스토리보드만 활용시에는 코드가 필요하지 않지만 코드로 화면 전환을 하려고 할 때는 Storyboard Segue의 Identifier를 활용해서 전환해야 합니다.
Unwind / UIStoryboardSegue - Unwind는 화면 전환을 실행 후, 다시 뒤로 돌아갈 때 사용합니다. 네비게이션 컨트롤러처럼 뒤로 돌아가는 버튼이 있을 경우 문제가 없지만, 화면 전환 후 나오는 버튼이 없다면 화면에 뷰가 계속 쌓여 문제가 될 수 있습니다. 이 문제를 해결하기 위해서는 반드시 Unwind를 활용하여 화면을 해제해줘야 합니다.
UIStoryboardSegue는 두 뷰 컨트롤러간 화면전환을 준비 및 실행하는 객체입니다. 클래스 타입이며 이를 상속해서 화면전환을 커스터마이징할 수 있습니다.
Presentation / Transition Style - Modal방식의 화면 전환을 할 때 사용가능합니다. Presentation은 화면을 어떤 스타일로 보여줄 것인지에 대한 내용이고, Transition Style은 화면 전환 효과에 대한 내용입니다. Transition Style 중 Cover Vertical의 경우, 책장을 위로 넘기는 듯한 효과가 있지만 Dismiss할 때 에러가 발생합니다..
2-2. View Controller LifeCycle
ViewDidLoad - 뷰 컨트롤러를 실행할 때, 한 번만 호출되는 메서드이며 RootView가 호출된 이후에 호출됩니다.
ViewWillAppear - 뷰 컨트롤러에 뷰가 추가가 될 것임을 알려주는 메서드입니다.
ViewDidAppear - 뷰 컨트롤러에 뷰가 추가가 되었다는 것을 알려주는 메서드입니다.
ViewWillDisappear - 뷰 컨트롤러에 뷰가 삭제가 될 것임을 알려주는 메서드입니다.
ViewDidDisappear - 뷰 컨트롤러에 뷰가 삭제가 되었다는 것을 알려주는 메서드입니다.
화면전환 스타일에 따른 생명주기 호출 시점 - show나 modal의 기본 화면 전환처럼 기본 화면에서 새 화면으로 전환 시 풀 스크린 모드가 아닐 경우, 전 화면의 ViewWillAppear, ViewDidAppear 등은 호출되지 않습니다. 이에 따라 화면 갱신도 되지 않기에 화면 전환 구조를 설계할 때 주의가 필요합니다.
2-3. UserDefaults
UserDefaults - 경량의 단일 데이터 값을 키와 밸류 타입으로 저장해주는 기능입니다. 이를 활용해서 필요한 데이터를 저장하여 사용할 수 있고, 자동로그인, 기본적인 사용자 정부 등을 저장할 수 있습니다. 추후 이 데이터에 접근하여 어떤 데이터가 쓰였는지 확인이 가능합니다.
3. 과제 및 실습
복습(넷플릭스 로그인 화면에서 화면 전환 기능 구현, 얼럿 띄우기, Date 저장하기, 감정일기 카운트 리셋 등)
if emailErrorLabel.text == "OK", passwordErrorLabel.text == "OK", referralCodeErrorLabel.text == "OK", emailTextField.text == "123456", passwordTextField.text == "654321" {
let alert = UIAlertController(title: "회원가입", message: "완료되었습니다!", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "취소", style: .cancel, handler: nil))
alert.addAction(UIAlertAction(title: "승인", style: .default, handler: { action -> Void in
self.performSegue(withIdentifier: "toSignedUp", sender: self)
}))
present(alert, animated: true)
}
- 기존 회원가입 코드에서 맞는 이메일 및 비밀번호를 입력하였을 때, Alert창을 띄우고 여기서 확인을 누르면 다음 화면으로 넘어가는 것을 구현했습니다.
- 버튼을 새로 만들어 UserDefault를 활용하여 자동로그인 기능을 구현하기 위해 현재 작업 중에 있습니다.
func showAlertController() {
// 흰 바탕 - UIAlertController
let alert = UIAlertController(title: "데이터 저장", message: "하시겠습니까?", preferredStyle: .alert)
// 버튼
let ok = UIAlertAction(title: "확인", style: .default) { action -> Void in
UserDefaults.standard.set(self.button1.titleLabel?.text, forKey: "dates1")
UserDefaults.standard.set(self.button2.titleLabel?.text, forKey: "dates2")
UserDefaults.standard.set(self.button3.titleLabel?.text, forKey: "dates3")
UserDefaults.standard.set(self.button4.titleLabel?.text, forKey: "dates4")
}
let cancel = UIAlertAction(title: "취소", style: .cancel, handler: nil)
// 1+2
alert.addAction(cancel)
alert.addAction(ok)
// present
present(alert, animated: true, completion: nil)
}
@IBAction func saveButtonTapped(_ sender: UIButton) {
showAlertController()
}
@IBAction func deleteButtonTapped(_ sender: UIButton) {
for i in 1...4 {
UserDefaults.standard.removeObject(forKey: "dates\(i)")
}
- 날짜를 선택하고 SAVE DATE버튼을 누를 경우, Alert 창을 띄우고 확인 버튼 누를 시 데이터 저장을 구현하였습니다.
- DELETE DATE버튼에는 Alert 창을 구현하지 않고 바로 삭제하는 기능을 넣어서 눌러도 변화가 없는 것처럼 보이지만 삭제 후 앱을 재실행하였을 때 잘 데이터가 삭제된 것을 확인할 수 있었습니다.
func showAlertController() {
// 흰 바탕 - UIAlertController
let alert = UIAlertController(title: "데이터 저장", message: "하시겠습니까?", preferredStyle: .actionSheet)
// 버튼
let delete = UIAlertAction(title: "삭제", style: .destructive) { action -> Void in
for i in 0...8 {
UserDefaults.standard.removeObject(forKey: "emotion\(i)")
self.labelsArray[i].text = "\(self.emoArray[i].0) \(UserDefaults.standard.integer(forKey: "emotion\(i)"))"
}
}
let cancel = UIAlertAction(title: "취소", style: .cancel, handler: nil)
let ok = UIAlertAction(title: "확인", style: .default, handler: nil)
let copy = UIAlertAction(title: "복사", style: .default, handler: nil)
// 1+2
alert.addAction(delete)
alert.addAction(copy)
alert.addAction(cancel)
alert.addAction(ok)
// present
present(alert, animated: true, completion: nil)
}
@IBAction func emotionButtonTapped(_ sender: UIButton) {
switch sender.currentTitle ?? "" {
case emoArray[0].0:
let currentValue = UserDefaults.standard.integer(forKey: "emotion0")
let updateValue = currentValue + 1
UserDefaults.standard.set(updateValue, forKey: "emotion0")
labelsArray[0].text = "\(emoArray[0].0) \(UserDefaults.standard.integer(forKey: "emotion0"))"
case emoArray[1].0:
let currentValue = UserDefaults.standard.integer(forKey: "emotion1")
let updateValue = currentValue + 1
UserDefaults.standard.set(updateValue, forKey: "emotion1")
labelsArray[1].text = "\(emoArray[1].0) \(UserDefaults.standard.integer(forKey: "emotion1"))"
case emoArray[2].0:
let currentValue = UserDefaults.standard.integer(forKey: "emotion2")
let updateValue = currentValue + 1
UserDefaults.standard.set(updateValue, forKey: "emotion2")
labelsArray[2].text = "\(emoArray[2].0) \(UserDefaults.standard.integer(forKey: "emotion2"))"
case emoArray[3].0:
let currentValue = UserDefaults.standard.integer(forKey: "emotion3")
let updateValue = currentValue + 1
UserDefaults.standard.set(updateValue, forKey: "emotion3")
labelsArray[3].text = "\(emoArray[3].0) \(UserDefaults.standard.integer(forKey: "emotion3"))"
case emoArray[4].0:
let currentValue = UserDefaults.standard.integer(forKey: "emotion4")
let updateValue = currentValue + 1
UserDefaults.standard.set(updateValue, forKey: "emotion4")
labelsArray[4].text = "\(emoArray[4].0) \(UserDefaults.standard.integer(forKey: "emotion4"))"
case emoArray[5].0:
let currentValue = UserDefaults.standard.integer(forKey: "emotion5")
let updateValue = currentValue + 1
UserDefaults.standard.set(updateValue, forKey: "emotion5")
labelsArray[5].text = "\(emoArray[5].0) \(UserDefaults.standard.integer(forKey: "emotion5"))"
case emoArray[6].0:
let currentValue = UserDefaults.standard.integer(forKey: "emotion6")
let updateValue = currentValue + 1
UserDefaults.standard.set(updateValue, forKey: "emotion6")
labelsArray[6].text = "\(emoArray[6].0) \(UserDefaults.standard.integer(forKey: "emotion6"))"
case emoArray[7].0:
let currentValue = UserDefaults.standard.integer(forKey: "emotion7")
let updateValue = currentValue + 1
UserDefaults.standard.set(updateValue, forKey: "emotion7")
labelsArray[7].text = "\(emoArray[7].0) \(UserDefaults.standard.integer(forKey: "emotion7"))"
case emoArray[8].0:
let currentValue = UserDefaults.standard.integer(forKey: "emotion8")
let updateValue = currentValue + 1
UserDefaults.standard.set(updateValue, forKey: "emotion8")
labelsArray[8].text = "\(emoArray[8].0) \(UserDefaults.standard.integer(forKey: "emotion8"))"
default:
break
}
}
@IBAction func saveButtonTapped(_ sender: UIButton) {
showAlertController()
}
- 각 감정버튼을 누를 경우, 누른 횟수가 바로 저장되도록 구현하였고, 앱을 껐다켜도 기존 데이터가 남아있음을 확인하였습니다.
- 그리고 SAVE버튼에 Alert창을 구현해놓고 Alert창 삭제를 누를 시 저장된 데이터를 지우도록 구현하였습니다.
4. 자료 출처
구글 검색어: what is segue show in xcode -> https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/UsingSegues.html
구글 검색어: about viewdidload in xcode -> https://stackoverflow.com/questions/44579445/what-is-viewdidload-for
구글 검색어: about viewwillappear in xcode -> https://developer.apple.com/documentation/uikit/uiviewcontroller/1621510-viewwillappear
'기타' 카테고리의 다른 글
SeSAC TIL - 22.07.19 (0) | 2022.07.20 |
---|---|
SeSAC TIL - 22.07.18 (0) | 2022.07.20 |
SeSAC TIL - 22.07.14 (0) | 2022.07.18 |
SeSAC TIL - 22.07.13 (0) | 2022.07.18 |
SeSAC TIL - 22.07.12 (0) | 2022.07.18 |