-
Review of Connect the UI to Code (2) - Food TrackeriOS/๐ค App 2021. 1. 19. 00:25
Define an Action to Perform
iOS ์ฑ์ ์ด๋ฒคํธ ๊ธฐ๋ฐ ํ๋ก๊ทธ๋๋ฐ ( event-driven programming ) ๊ธฐ๋ฐ์ ๋๋ค.
์ด๊ฒ์ ์ฑ์ ์คํ ํ๋ฆ์ด ์ด๋ฒคํธ์ ์ํด ์ ํด์ง๋ค๋ ์๋ฏธ์ ๋๋ค.
์ด๋ฒคํธ์๋ ์์คํ ์ด ๋ฐ์์ํค๋ ์ด๋ฒคํธ(system events)์ ์ฑ ์ฌ์ฉ์๊ฐ ๋ฐ์์ํค๋ action ์ด ์์ต๋๋ค.
์ฌ์ฉ์๊ฐ UI๋ฅผ ํตํด ์คํ์ํจ Action์ด ์ฑ ๋ด ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํต๋๋ค.
" The user performs actions in the interface that trigger events in the app "
์ฆ, ์ฑ์ ์ฝ๋ ์กฐ๊ฐ์ด ์คํ๋๋ ์๊ธฐ๋ฅผ ์ฌ์ฉ์๊ฐ ์ ์ดํ ์ ์์ต๋๋ค.
action ์ฆ action method๋ ์ฑ์์ ๋ฐ์ํ๋ ์ด๋ฒคํธ์ ์ฐ๊ฒฐ๋์ด ์๋ ์ฝ๋ ์กฐ๊ฐ์ ๋๋ค.
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์์คํ ์ ์ฝ๋ ์กฐ๊ฐ์ ์คํ์ํต๋๋ค.
์ด๋ฒคํธ์ ์ฐ๊ฒฐ๋ ์ฝ๋๋ฅผ ์ด์ฉํด์ ๊ฐ๋ฐ์๋ ์ฑ์ flow (์คํ ํ๋ฆ)์ ๊ฐ์ ์ ์ผ๋ก ์ ์ดํ ์ ์์ต๋๋ค.
์ค์ ๋ฐฉ๋ฒ
์ด์ ๊ธ์ outlet ๊ณผ ๊ฐ์ด, ์ปจํธ๋กค์ ๋๋ฅธ ์ํ๋ก ์ํ๋ ๋ทฐ๋ฅผ View Controller๋ฅผ ๋๋๊ทธ & ๋๋กญํ๋ฉด ๋ฉ๋๋ค.
์ด ๋์์ ํตํด @IBAction func๋ผ๋ ํค์๋๋ก ์์ํ๋ ๋ฉ์๋๋ฅผ ์์ฑํ๊ฒ ๋ฉ๋๋ค.
Outlet ์์์ ๋ค๋ฅธ ๋ถ๋ถ์ Connection ์ด `Outlet` ์ด ์๋ `Action`์ผ๋ก ์ ํํ์๋ค๋ ์ ์ ๋๋ค.
๋ํ ์ฌ์ง ์์์ Type์ `Any`๋ก ํ์์ง๋ง, View Controller ํ์ผ๋ง ๋ณด๊ณ ์ด๋ค ํ์ ์ ์ค๋ธ์ ํธ๊ฐ ํธ์ถํ๋ ๋ฉ์๋์ธ์ง ์๊ธฐ ์ํด์๋ `UIButton`์ผ๋ก ํน์ ํ๋ ๊ฒ์ด ๊ฐ๋ ์ฑ ์ธก๋ฉด์์ ๋ซ๋ค๊ณ ์๊ฐ๋ฉ๋๋ค.
์ถ๊ฐ์ ์ผ๋ก `Touch Up Inside` ๋ ์ด๋ฒคํธ์ ์ข ๋ฅ๋ก์, ์ผ๋ฐ์ ์ผ๋ก ์๊ฐํ๋ ํญ ๋์์ ๋ฐ์ํ๋ ์ด๋ฒคํธ์ ๋๋ค.
์๋ฐํ ์ด์ผ๊ธฐํ๊ธฐ ์ํด `Touch Up Outside` ์ด๋ฒคํธ์ ๋น๊ตํด๋ณด๊ฒ ์ต๋๋ค.
์ฌ์ฉ์์ ๋์์ ์ผ๋จ Touch์ Up์ผ๋ก ๋ถ๋ฆฌํด์ ์๊ฐํด์ผ ํฉ๋๋ค.
๋ง ๊ทธ๋๋ก 1. (์๊ฐ๋ฝ์ผ๋ก) ํฐ์นํ๋ ๋์๊ณผ 2. (์๊ฐ๋ฝ์) ๋ผ๋ ๋์์ผ๋ก ๊ตฌ๋ถํ๋ ๊ฒ์ ๋๋ค.
Touch Up Inside ๋ ๋ทฐ๋ฅผ ํฐ์นํ๊ณ ์๋ ์ํ์์ ํด๋น ๋ทฐ์ ๋ฐ์ด๋๋ฆฌ ๋ด(Inside)์์ ์๊ฐ๋ฝ์ ๋ผ๋ฉด ๋ฐ์ํฉ๋๋ค.
์ผ๋ฐ์ ์ธ ํญ ๋์์ด๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค.
Touch Up Outside ๋ ๋ทฐ๋ฅผ ํฐ์นํ๊ณ ์๋ ์ํ์์ ๋๋๊ทธํ ์ฑ๋ก ์ด๋ํ์ฌ ๋ทฐ์ ๋ฐ์ด๋๋ฆฌ ๋ฐ๊นฅ(Outside)์์ ์๊ฐ๋ฝ์ ๋ผ๋ฉด ๋ฐ์ํฉ๋๋ค.
์ ๋ ๋ณดํต ๋ฒํผ์ ์๋ชป ๋๋ ์ ๋ ์ด ๋์์ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฒํผ์ ํฐ์นํ๊ณ ์๋ ์ํ์์ ๋ผ์ง ์๊ณ ์๊ฐ๋ฝ์ ๋์ด์ ๋ค๋ฅธ ๊ณณ์์ ๋ผ๋ฉด, ํด๋น ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฉ์๋๋ฅผ ๋ณดํต ๊ตฌํํ์ง ์๊ธฐ ๋๋ฌธ์ ` ์ทจ์` ์ ์ ์ฌํ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
์์ฑํ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
@IBAction func setDefaultLabelText(_ sender: UIButton) { mealNameLabel.text = "Default Text" }
UIButton ์ค๋ธ์ ํธ์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด, setDefaultLabelText(_:) ๋ฉ์๋๊ฐ ํธ์ถ๋๊ณ , Outlet์ผ๋ก ์ฐ๊ฒฐ๋ mealNameLable์ text ์์ฑ์ด ๋ฐ๋๊ฒ ๋ฉ๋๋ค.
๋ทฐ์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์์คํ ์ด action method๋ฅผ ํธ์ถํ๊ณ sender ์ค๋ธ์ ํธ(์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋ทฐ)๋ฅผ ๋ณด๋์ผ๋ก์จ ๋ฉ์์ง๋ฅผ ์ ๋ฌํฉ๋๋ค.
์ด๊ฒ์ iOS์์๋ target-action pattern์ด๋ผ๊ณ ํฉ๋๋ค.
" Target-action is a design pattern where one object sends a message to another object when a specific event occurs. "
์ฌ๊ธฐ์ setDefaultLabelText(_:)์ ํ๋ผ๋ฏธํฐ sender๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ UIButton ์ค๋ธ์ ํธ์ ๋๋ค.
Process User Input
UITextfield์ ์ ๋ ฅํ ๋ด์ฉ์ Return ํค๋ฅผ ๋๋ ์ ๋ UILabel์ ๋ฐ์ํ๊ณ ์ถ์ ์ํฉ์ ๋๋ค.
์ฌ๊ธฐ์ Text Field์ delegate๋ฅผ View Controller๋ก ์ค์ ํด์ค๋๋ค.
Delegate๋ ์ด๋ค ํ๋์ `๋์ ์ํํด์ฃผ๋` ๊ฐ์ฒด์ ๋๋ค.
์ฉ์ด ์ ๋ฆฌ๋ฅผ ํ๋ฉด ์ฌ๊ธฐ์ Text Field๋ `delegating object` ๊ฐ ๋๊ณ , View Controller๋ `delegate` ์ด ๋ฉ๋๋ค.
Delegating object๋ delegate์ ์ฐธ์กฐ๋ฅผ ๊ณ์ ๊ฐ์ง๊ณ ์์ผ๋ฉด์, ํ์ํ ๋์ delegate์๊ฒ ๋ฉ์์ง๋ฅผ ๋ณด๋ ๋๋ค.
๋ฉ์์ง์๋ delegating object๊ฐ ๋ค๋ฃจ๊ฑฐ๋ ๋ค๋ฃจ๋ ค๊ณ ํ๋ ์ด๋ฒคํธ์ ๋ํ ๋ด์ฉ์ด ๋ค์ด ์์ต๋๋ค.
Delagate๋ ์ด ๋ฉ์์ง์ ๋ง๊ฒ ๋ฐ์ํฉ๋๋ค.
์๋ฅผ ๋ค๋ฉด 1. ์์ ์ด๋ ๋ค๋ฅธ ๋ทฐ์ ์ํ๋ฅผ ๋ฐ๊พผ๋ค๋๊ฐ, 2. ์ด๋ฒคํธ๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋์ง์ ๋ํ ๊ฐ์ ๋ฆฌํดํฉ๋๋ค.
Text Field์ delegate ๋ Text Field ๊ฐ text๋ฅผ ์์ ํ๊ณ ์๋ ๋์ Text Field์ ์ํตํ๊ณ , ์ค์ํ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ์๊ฒ ๋ฉ๋๋ค.
์ฌ๊ธฐ์๋ ์ฌ์ฉ์๊ฐ text ์์ ์ ์์ํ๊ฑฐ๋ ๋ง์ณค์ ๋ ๊ฐ ๋ ์ ์์ต๋๋ค.
์ด๋ค ๊ฐ์ฒด์ Delegate๊ฐ ๋๊ธฐ ์ํด์๋ ์ ์ ํ protocol์ ์ฑํํด์ผ ํฉ๋๋ค.
๊ด๋ จ ๊ธ: Protocol Overview, Delegate Pattern
text field์ delegate ์ด ๋๊ธฐ ์ํด ํ์ํ ํ๋กํ ์ฝ์ UITextFieldDelegate์ ๋๋ค.
๋ณดํต ์์ ์ ๊ด๋ฆฌํ๊ณ ์๋ View Controller๋ฅผ delegate๋ก ์ค์ ํฉ๋๋ค.
์ค์ ํ๋ ๋ฐฉ๋ฒ์ ํฌ๊ฒ 2๊ฐ์ง๊ฐ ์๋๋ฐ, ์์ ๊ด๋ จ ๊ธ์ ์ ์์ผ๋ฏ๋ก ์๋ตํ๊ฒ ์ต๋๋ค.
extension ViewController: UITextFieldDelegate { func textFieldShouldReturn(_ textField: UITextField) -> Bool { // code } func textFieldDidEndEditing(_ textField: UITextField) { // code } }
Delegate Protocol์ extension ๋ฌธ๋ฒ์ ํตํด adopt ํ ์ฝ๋์ ๋๋ค.
์ด ํ๋กํ ์ฝ์ ํ์์ ์ผ๋ก ๊ตฌํํด์ผ ๋ฉ์๋๊ฐ ๋ฐ๋ก ์์ผ๋ฏ๋ก, ์ฉ๋์ ๋ง๋ ๋ฉ์๋ ๋ ๊ฐ์ง๋ง ๊ตฌํํ์์ต๋๋ค.
๊ด๋ จ ๊ธ: UITextFieldDelegate - Apple Developer Documentation
UIKit์ API ์๋ช ๋ฐฉ์์ ์ผ์ฒด๊ฐ์ด ์์ด์ ์ฐธ ์ข์ต๋๋ค.
Should, Did, Will๊ณผ ๊ฐ์ ๋์ฌ๋ฅผ ๋ฉ์๋ ๋ช ์ ๋ฃ์ด์ ํธ์ถ ์์ ์ ์ ์ถํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ฌผ๋ก ์ ํํ ํธ์ถ ์์ ์ ํ์ธ์ Documentation์ด๋ Xcode ๊ฐ ์ ๊ณตํ๋ Quick help๋ฅผ ํตํ์ฌ ํ์ธํด์ผ ํฉ๋๋ค.
๋ฐ๋ผ์ textFieldShouldReturn(_:) ๋ฉ์๋๋ ์ฌ์ฉ์๊ฐ ์ด๋ฏธ Return ํค๋ฅผ ํญ ํ๊ณ , ์ด๊ฒ์ ์ฒ๋ฆฌํ๊ธฐ ์ง์ ์ ํธ์ถ๋๋ ๋ฉ์๋์ผ ๊ฒ์ ๋๋ค.
First Responder
์ฌ์ฉ์๊ฐ Text Field๋ฅผ ํญ ํ ๋, ์ด๊ฒ์ด first responder ๊ฐ ๋ฉ๋๋ค.
์ฑ์์ first responder๋ ์ต์ผ์ ์์ ์ฑ ์ด๋ฒคํธ๋ฅผ ๋ฐ๋ ๊ฐ์ฒด์ ๋๋ค. (ํค ์ด๋ฒคํธ, ๋ชจ์ ์ด๋ฒคํธ, action ๋ฉ์์ง ๋ฑ)
์ฆ, ์ฌ์ฉ์์ ์ํด ์ฑ์ฑ๋ ์ด๋ฒคํธ๋ค์ first responder๊ฐ ์ฒซ ๋ฒ์งธ๋ก ๋ฐ๋๋ก routing ๋์ด ์์ต๋๋ค.
Text Field๊ฐ first responder๊ฐ ๋๋ฉด, iOS๋ ํ๋ฉด์ ํค๋ณด๋๋ฅผ ๋์์ฃผ๊ณ , Text Field๋ฅผ ์ํ ์์ ์ธ์ (editing session)์ ์ฝ๋๋ค.
์ฌ์ฉ์๊ฐ ํค๋ณด๋๋ก ์ ๋ ฅํ๋ ๊ฒ๋ค์ด Text Field์ ์ฑ์์ง๊ฒ ๋ฉ๋๋ค.
์ฌ์ฉ์๊ฐ Text Field ์์ ์ ๋๋ด๊ณ ์ถ์ ๋, Text Field๋ first responder๋ฅผ ๊ทธ๋ง๋์ด์ผ ํฉ๋๋ค.
์์ ์ ๋๋ด๋ฉด Text Field๋ ๋ ์ด์ active ๊ฐ์ฒด๊ฐ ๋ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. (๋ ์ด์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ ์ฒ๋ฆฌํ ํ์๊ฐ)
์ด๋๋ ๋ค๋ฅธ ์ ์ ํ ๊ฐ์ฒด๊ฐ first responder๊ฐ ๋๋ ๊ฒ์ด ๋ง์ ๊ฒ์ ๋๋ค.
extension ViewController: UITextFieldDelegate { func textFieldShouldReturn(_ textField: UITextField) -> Bool { // Hide the keyboard. textField.resignFirstResponder() return true } func textFieldDidEndEditing(_ textField: UITextField) { mealNameLabel.text = textField.text } }
Text Field ๊ฐ ๋ ์ด์ fisrt responder๊ฐ ์๋๊ฒ ๋๋ฉด, textFieldDidEndEditing(_:) ๋ฉ์๋๊ฐ ํธ์ถ๋ฉ๋๋ค.
๊ด๋ จ ๊ธ: Bool ์ ๋ฐํํ๋ Delegate Method
//MARK: ์ ์ฌ์ฉ
์ฃผ์์ผ๋ก //MARK: Properties์ ๊ฐ์ ๋ฌธ๊ตฌ๋ฅผ ์ถ๊ฐํด๋๋ฉด, ์ฝ๋๊ฐ ๊ธธ์ด์ง๋ ์ํฉ์์ ์ฝ๊ฒ ํด๋น ์์น๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.
XCode๊ฐ Functions menu์์ // MARK: ์ฃผ์์ ์ธ์ํด์ ๋ณด์ฌ์ฃผ๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋!
๋ค์ ๊ธ: Review of Work with View Controllers (1) - Food Tracker
'iOS > ๐ค App' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Review of Implement a Custom Control (1) - FoodTracker (0) 2021.01.21 Review of Work with View Controllers (2) - Food Tracker (0) 2021.01.19 Review of Work with View Controllers (1) - Food Tracker (0) 2021.01.19 Review of Connect the UI to Code (1) - Food Tracker (0) 2021.01.18 Review of Build a Basic UI - Food Tracker (0) 2021.01.18