🍎 아이-였-μ—μŠ€/πŸ“± iOS 개발

[iOS] UITableView + UITableViewCell (4): μ»€μŠ€ν…€ UITableViewCell

κ°œλ°œν•˜λŠ” ν›ˆμ΄ 2021. 9. 27. 02:59

μ»€μŠ€ν…€ 셀을 λ§Œλ“€μ–΄λ³΄μž

μ§€λ‚œ ν¬μŠ€νŠΈκΉŒμ§€ ν…Œμ΄λΈ” λ·°λ₯Ό λ§Œλ“€μ–΄ μ •μ μœΌλ‘œ 셀을 μž…λ ₯ν•΄ λ„£λŠ” 법, ν…Œμ΄λΈ” λ·° 컨트둀러 클래슀λ₯Ό μƒˆλ‘œ μƒμ„±ν•΄μ„œ 데이터λ₯Ό μžλ™μœΌλ‘œ μ…€λ‘œ λ„£λŠ” κ³Όμ •, 그리고 κ·Έ μ•ˆμ—μ„œ μ‚¬μš©λ˜λŠ” data source의 κ°œλ…κ³Ό μ…€μ˜ μž¬μ‚¬μš©μ— λŒ€ν•΄ μ •λ¦¬ν•΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€. 이제 ν…Œμ΄λΈ” 뷰의 λ§ˆμ§€λ§‰ μ‹œλ¦¬μ¦ˆμΈλ°μš”, 였늘의 λͺ©ν‘œλŠ” UITableViewCell의 μ»€μŠ€ν…€ 클래슀λ₯Ό λ§Œλ“€μ–΄μ„œ 더 μœ μ—°ν•˜κ²Œ 셀을 κ΅¬μ„±ν•˜λŠ” 방법을 μ •λ¦¬ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€. 

 

μ˜ˆμ œλ“€μ΄ 이전 ν¬μŠ€νŠΈλ“€μ—μ„œ μ΄μ–΄μ§‘λ‹ˆλ‹€! 특히 이 포슀트λ₯Ό 읽지 μ•ŠμœΌλ©΄ μ˜ˆμ œκ°€ 이해가 μ „ν˜€ μ•ˆλ  μˆ˜λ„ μžˆμ–΄μš”! 그럼 μ‹œμž‘ν•˜κ² μŠ΅λ‹ˆλ‹€~!

 

μ§€λ‚œ ν¬μŠ€νŠΈμ—μ„œλŠ” 이런 λͺ¨μ–‘μœΌλ‘œ ν…Œμ΄λΈ” λ·°λ₯Ό κ΅¬μ„±ν–ˆμ—ˆλŠ”λ°μš”, 사싀 ν•œ 가지 빠진 것이 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

 

여기에 λ³΄μ΄λŠ” 수/λ°œμ‹  μš”μΌμ΄ λΉ μ Έμžˆμ—ˆμŠ΅λ‹ˆλ‹€..! μ €ν¬λŠ” ν…Œμ΄λΈ” λ·°μ—μ„œ ν…μŠ€νŠΈλ₯Ό λ„£μ–΄μ£ΌκΈ° μœ„ν•΄μ„œ ContentConfigutration의 text와 secondary textλ₯Ό μ‚¬μš©ν–ˆμ—ˆμŠ΅λ‹ˆλ‹€. 그런데 μ΄λ ‡κ²Œ ν•˜λ©΄ μš”μΌ λ ˆμ΄λΈ”μ„ μΆ”κ°€ν•  μˆ˜κ°€ μ—†μ–΄μš”.. κ·Έλž˜μ„œ μ»€μŠ€ν…€ 셀을 λ§Œλ“€μ–΄μ„œ 내뢀에 λ ˆμ΄λΈ” μ„Έ 개λ₯Ό ν¬ν•¨ν•˜λŠ” 셀을 λ§Œλ“€μ–΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

클래슀 μΆ”κ°€ν•˜κΈ°

λ¨Όμ € μ»€μŠ€ν…€ 셀을 μœ„ν•œ 클래슀λ₯Ό μΆ”κ°€ν•΄μ£Όκ² μŠ΅λ‹ˆλ‹€.

 

νΌμ•Œ λ§Œλ“€κΈ°μ—μ„œ Cocoa Touch Classλ₯Ό μ„ νƒν•˜κ³ μš”,

 

UITableViewCell을 μƒμ†ν•˜λŠ” 클래슀λ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€!

 

μ΄λ ‡κ²Œ μƒˆλ‘œμš΄ ν΄λž˜μŠ€κ°€ μΆ”κ°€λ˜μ—ˆλŠ”λ°μš”, 두 개의 λ©”μ„œλ“œκ°€ 기본적으둜 μƒμ„±λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. setSelectedλŠ” 셀이 μ„ νƒλ˜μ—ˆμ„ λ•Œμ˜ λ™μž‘μ„ μ§€μ •ν•˜λŠ” 것 κ°™μ£ ? 그런데 awakeFromNib()은 λ­˜κΉŒμš”? 주석을 λ³΄λ‹ˆ μ΄ˆκΈ°ν™” μ½”λ“œμΈ 것 같은데 더 μžμ„Ένžˆ μ•Œμ•„λ³΄κΈ° μœ„ν•΄μ„œ μ΄λ²ˆμ—λ„ μ—­μ‹œ κ³΅μ‹λ¬Έμ„œλ₯Ό μ°Ύμ•„λ΄€μŠ΅λ‹ˆλ‹€!

awakeFromNib μ•Œμ•„λ³΄κΈ°

https://developer.apple.com/documentation/objectivec/nsobject/1402907-awakefromnib

 

Apple Developer Documentation

 

developer.apple.com

πŸ’‘ The nib-loading infrastructure sends an awakeFromNib message to each object recreated from a nib archive, but only after all the objects in the archive have been loaded and initialized. When an object receives an awakeFromNib message, it is guaranteed to have all its outlet and action connections already established.

 

nibλŠ” 화면을 κ΅¬μ„±ν•˜λŠ” ν΄λž˜μŠ€λ“€μ„ XML둜 μ •μ˜ν•œ XIBλ₯Ό μ»΄νŒŒμΌν•œ νŒŒμΌμΈλ°μš”, nibκ°€ μ•„μΉ΄μ΄λΈŒ λ˜μ–΄μžˆλ‹€κ°€ 객체둜 생성될 λ•Œ μ•„μΉ΄μ΄λΈŒμ— ν¬ν•¨λœ λͺ¨λ“  객체가 μƒμ„±λ˜κ³  μ΄ˆκΈ°ν™”λ˜λ©΄ awakeFromNib λ©”μ‹œμ§€λ₯Ό λ‚΄λΆ€μ μœΌλ‘œ κ°μ²΄λ“€μ—κ²Œ 보낸닀고 ν•©λ‹ˆλ‹€. μ—¬κΈ°μ„œ μ•„μΉ΄μ΄λΈŒλŠ” μ–΄λ–€ ν΄λž˜μŠ€μ™€ κ·Έ ν΄λž˜μŠ€μ™€ μ°Έμ‘° 관계에 μžˆλŠ” ν΄λž˜μŠ€κΉŒμ§€ κ·Έλž˜ν”„λ‘œ λ¬Άμ–΄μ„œ μ €μž₯(아카이빙)ν•˜λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€. 객체듀이 이 λ©”μ‹œμ§€λ₯Ό λ°›μœΌλ©΄ μžμ‹ μ΄ 가지고 μžˆλŠ” 아웃렛 λ³€μˆ˜μ™€ μ•‘μ…˜ λ©”μ„œλ“œκ°€ λͺ¨λ‘ μ—°κ²°λ˜μ–΄ μžˆμŒμ„ 보μž₯ν•˜κ²Œ λ©λ‹ˆλ‹€. κ°„λ‹¨νžˆ λ§ν•΄μ„œ awakeFromNib은 화면에 λ³΄μ΄λŠ” 정보듀을 담은 객체가 생성&μ΄ˆκΈ°ν™”λ₯Ό λͺ¨λ‘ μ™„λ£Œν•œ 뒀에 ν˜ΈμΆœλ˜λŠ” λ©”μ„œλ“œλΌκ³  ν•  수 μžˆμŠ΅λ‹ˆλ‹€!

 

πŸ’‘ You must call the super implementation of awakeFromNib to give parent classes the opportunity to perform any additional initialization they require. Although the default implementation of this method does nothing, many UIKit classes provide non-empty implementations. You may call the super implementation at any point during your own awakeFromNib method.

 

awakeFromNib은 λ°˜λ“œμ‹œ superκ°€ 가지고 μžˆλŠ” λ©”μ„œλ“œλ„ ν•¨κ»˜ ν˜ΈμΆœν•΄μ•Ό ν•©λ‹ˆλ‹€. λ§Žμ€ UIKit ν΄λž˜μŠ€λ“€μ΄ 여기에 μ½”λ“œλ₯Ό ν¬ν•¨ν•˜κ³  μžˆλ‹€κ³  ν•˜λ„€μš”. μ»€μŠ€ν…€ ν΄λž˜μŠ€λ“€μ€ λŒ€λΆ€λΆ„ UIKit ν΄λž˜μŠ€λ“€μ„ μƒμ†ν•˜κΈ° λ•Œλ¬Έμ— λ°˜λ“œμ‹œ ν˜ΈμΆœν•΄μ•Όκ² λ„€μš”.

 

πŸ’‘ During the instantiation process, each object in the archive is unarchived and then initialized with the method befitting its type. Objects that conform to the NSCoding protocol (including all subclasses of UIView and UIViewController) are initialized using their initWithCoder: method. All objects that do not conform to the NSCoding protocol are initialized using their init method. After all objects have been instantiated and initialized, the nib-loading code reestablishes the outlet and action connections for all of those objects. It then calls the awakeFromNib method of the objects. For more detailed information about the steps followed during the nib-loading process, see Nib Files in Resource Programming Guide.

 

κ°μ²΄λ“€μ˜ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜κ³  awakeFromNib이 λΆˆλ¦¬κΈ°κΉŒμ§€μ˜ 과정에 λŒ€ν•œ 더 μžμ„Έν•œ μ„€λͺ…μž…λ‹ˆλ‹€. 각 μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜λŠ” κ³Όμ •μ—μ„œ μ•„μΉ΄μ΄λΈŒ λ˜μ—ˆλ˜ 각 객체듀은 μ–Έμ•„μΉ΄μ΄λΈŒκ°€ λ˜λ©΄μ„œ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€. μ΄λ•Œ NSCoding ν”„λ‘œν† μ½œμ„ μ±„νƒν•˜κ³  μžˆλŠ” 객체듀은 λͺ¨λ‘ initWithCoder λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ³  κ·Έ μ™Έμ˜ 객체듀은 μžμ‹ μ˜ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€. λͺ¨λ“  객체의 μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜λ©΄ nib-loading μ½”λ“œκ°€ 객체듀이 가지고 μžˆλŠ” outletκ³Ό action을 λ‹€μ‹œ μ—°κ²°ν•˜λŠ” μž‘μ—…μ„ ν•©λ‹ˆλ‹€. 이 μž‘μ—…μ΄ μ™„λ£Œλ˜λ©΄ λ§ˆμ§€λ§‰μœΌλ‘œ awakeFromNib λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€.

 

πŸ’‘ Typically, you implement awakeFromNib for objects that require additional set up that cannot be done at design time. For example, you might use this method to customize the default configuration of any controls to match user preferences or the values in other controls. You might also use it to restore individual controls to some previous state of your application.

 

awakeFromNib은 μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜λŠ” μˆœκ°„μ— ν•˜μ§€ λͺ»ν•˜λŠ” 일듀 κ΅¬ν˜„ν•΄λ‘˜ 수 μžˆμŠ΅λ‹ˆλ‹€. Control에 λŒ€ν•œ 섀정을 μΆ”κ°€ν•˜κ±°λ‚˜ 이전 μƒνƒœλ₯Ό λ³΅μ›ν•˜λŠ” μ½”λ“œλ₯Ό μΆ”κ°€ν•  수 있죠!

 

μ»€μŠ€ν…€ μ…€ λ§Œλ“€κΈ°

그럼 이제 μ»€μŠ€ν…€ 셀을 λ§Œλ“€μ–΄μ„œ 방금 μƒμ„±ν–ˆλ˜ ν΄λž˜μŠ€μ™€ μ—°κ²°ν•΄μ£Όκ² μŠ΅λ‹ˆλ‹€. 사싀 μ»€μŠ€ν…€ 셀을 λ§Œλ“œλ €λ©΄ XIBλ₯Ό λ§Œλ“œλŠ” 것이 λ§žκ² μ§€λ§Œ μ—¬κΈ°μ„œλŠ” μƒλž΅ν•˜κ³  이전 ν¬μŠ€νŠΈμ—μ„œ μ‚¬μš©ν–ˆλ˜ μž¬μ‚¬μš© 셀에 클래슀만 μž…ν˜€μ£Όλ„λ‘ ν• κ²Œμš”.

 

λ¨Όμ € μ§€λ‚œ ν¬μŠ€νŠΈμ—μ„œ λ§Œλ“€μ–΄λ‘μ—ˆλ˜ μž¬μ‚¬μš© 셀에 클래슀λ₯Ό μƒμ„±ν•œ μ»€μŠ€ν…€ 클래슀λ₯Ό μΆ”κ°€ν•΄μ€λ‹ˆλ‹€.

 

μ„Έ μ’…λ₯˜μ˜ λ ˆμ΄λΈ”μ΄ ν•„μš”ν•˜κ² μ£ ? 

 

그리고 이 λ ˆμ΄λΈ”λ“€μ— μ ‘κ·Όν•΄μ„œ 값을 지정해주어야 ν•˜λ‹ˆ, Outlet λ³€μˆ˜λ₯Ό λ§Œλ“€μ–΄μ•Όν•©λ‹ˆλ‹€.

 

μ΄λ ‡κ²Œ 3개의 UILabel에 λŒ€ν•œ Outlet λ³€μˆ˜λ₯Ό λ§Œλ“€κ³ ,

 

μŠ€ν† λ¦¬λ³΄λ“œλ‘œ μ΄λ™ν•΄μ„œ μ΄λ ‡κ²Œ Outletκ³Ό λ§Œλ“€μ–΄λ‘” λ ˆμ΄λΈ”μ„ μ—°κ²°ν•©λ‹ˆλ‹€. 

 

그럼 이제 μ€€λΉ„λŠ” 된 것 κ°™λ„€μš”. 이제 λ·° 컨트둀러둜 μ΄λ™ν•΄μ„œ μ…€ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€μ–΄ ν…Œμ΄λΈ” λ·°μ—κ²Œ λ°˜ν™˜ν•΄μ£ΌλŠ” cellForRowAt λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

셀에 데이터λ₯Ό μž…ν˜€ λ°˜ν™˜ν•˜κΈ°

이전 ν¬μŠ€νŠΈμ—μ„œ κ΅¬ν˜„ν–ˆλ˜ λ©”μ„œλ“œμ—μ„œ μˆ˜μ •ν•  사항듀이 μƒκ²ΌμŠ΅λ‹ˆλ‹€! λ¨Όμ € dequeueReusableCellμ—μ„œ 셀을 κΊΌλ‚΄μ„œ 데이터λ₯Ό μž…ν˜€μ£Όμ–΄μ•Ό ν•˜λŠ”λ°μš”,

이 λ©”μ„œλ“œλŠ” μš°λ¦¬κ°€ λ§Œλ“  μ»€μŠ€ν…€ 클래슀의 μƒμœ„ 클래슀인 UITableViewCell 클래슀λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. κ·Έλž˜μ„œ 이 μƒνƒœλ‘œλŠ” μš°λ¦¬κ°€ λ§Œλ“  λ ˆμ΄λΈ”λ“€μ˜ Outlet λ³€μˆ˜μ— μ ‘κ·Όν•  μˆ˜κ°€ μ—†μ£ . 이λ₯Ό μœ„ν•΄μ„œ λ°˜ν™˜λ°›μ€ UITableViewCell을 μ»€μŠ€ν…€ 클래슀둜 λ‹€μš΄μΊμŠ€νŒ…μ„ ν•΄μ£Όμ–΄μ•Όν•©λ‹ˆλ‹€.

 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
.
.
.

μ΄λ ‡κ²Œμš”!

 

그럼 이제 Outlet λ³€μˆ˜λ“€μ— μ ‘κ·Όν•  수 있겠죠? μ§€κΈˆλΆ€ν„°λŠ” 이전 ν¬μŠ€νŠΈμ—μ„œ κ΅¬ν˜„ν–ˆλ˜ λ‚΄μš©μ„ 쑰금만 λ³€κ²½ν•΄μ£Όλ©΄ λ©λ‹ˆλ‹€~!

 

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
        cell.name.text = sections[indexPath.section][indexPath.row].name
        cell.callType.text = sections[indexPath.section][indexPath.row].type
        cell.day.text = sections[indexPath.section][indexPath.row].day
        cell.accessoryType = .detailButton
        return cell
    }

μž¬μ‚¬μš© μ…€ μΈμŠ€ν„΄μŠ€κ°€ 가진 Outlet λ³€μˆ˜μΈ λ ˆμ΄λΈ”λ“€μ— ν˜„μž¬ μΈλ±μŠ€μ— λ§žλŠ” 데이터듀을 λΆˆλŸ¬μ™€ λ„£μ–΄μ£Όκ³  κ·ΈλŒ€λ‘œ λ°˜ν™˜ν•˜λ©΄ λμž…λ‹ˆλ‹€! 

 

그럼 싀행해보죠!

이제 μ œλ²• μ—°λ½μ²˜ μ•±μ˜ ν…Œμ΄λΈ”κ³Ό λΉ„μŠ·ν•΄μ‘Œλ„€μš”~! 

 

주말을 λͺ¨λ‘ 썼던 ν…Œμ΄λΈ” λ·° μ •λ³΅ν•˜κΈ° ν”„λ‘œμ νŠΈκ°€ λλ‚¬μŠ΅λ‹ˆλ‹€γ… γ…  XIBλ₯Ό λ§Œλ“€μ–΄μ„œ μ»€μŠ€ν…€ 셀을 λ§Œλ“€κ³  μ½”λ“œλ‘œ λ„£μ–΄μ£ΌλŠ” 것도 ν•˜κ³ μ‹Άμ€λ° 이번주 μ€‘μœΌλ‘œ 이 ν¬μŠ€νŠΈμ— μ—…λ°μ΄νŠΈ 해보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€. μ½μ–΄μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€!!