본문 바로가기
UIKit

UITableView

by iOS 개린이 2022. 4. 12.

1. UITableView 사용 및 메시지 모델 만들기 방법

-UITableViewDataSource는 테이블 뷰의 셀에 사용되는 데이터를 관리하기 위해 채택하는 프로토콜이다. 기본적으로 테이블 뷰는 데이터를 보여주기만 하고 자체적으로 데이터를 관리할 수는 없다. 따라서 데이터를 관리하기 위해서는 UITableViewDataSource 프로토콜을 사용해야 한다.  

-data source object의 기능들 

1) 테이블의 섹션 수와 행 수를 알려준다. 

2) 테이블의 각 행마다 셀을 제공한다. 

3) 섹션의 header와 footer에 타이틀을 제공한다.

4. 사용자나 테이블의 데이터가 변경되었으면 업데이트 해준다.

 

-func tableView(_ tableView: UITableView, numberOfRowsInSection section : Int) -> int { return //반환시킬 코드 }

 

위의 메서드는 테이블 뷰의 section의 index를 가지고 해당 sections에 포함된 셀 수를 알려주는 메서드이다.

각 섹션에 표시할 행의 개수를 묻는 메서드이다. 

 

func tableView( _ tableView : UITableView, cellForRowAt indexpath : indexpath ) -> UITableVIewCell { code }

 

위의 메서드는 테이블 뷰에서 특정 index에 있는 셀을 알려준다.

특정 위치에 표시할 셀을 요청하는 메서드

 

-table view의 separator를 default로 변경시켜주면 행을 구분할 수 있게 된다.

 

-채팅 앱이기 때문에 각 cell과 사용자는 상호작용할 필요가 없다. 따라서 cell의 selection style를 none으로 변경하여 셀을 터치해도 아무런 효과가 일어나지 않게 한다. 

 

 

2. .xib 파일을 사용하여 테이블 뷰에서 셀 사용자 지정 

-내가 따로 cell 이미지와 cellcontroller를 통해서 cell의 이미지를 변경시킨다. 

 

-.xib 파일을 사용하여 만든 message cell을 우리가 만드는 테이블 뷰의 cell image로 사용하려면 chatviewcontroller에서 등록을 해야한다. 등록하는 방법은 viewdidroad에서

tableview.register( UINib( nibName :  K.cellNibName  , bundle : nil ) , forCellReuseIdentifier : K.cellIdentifier )      코드를 작성.

 

-등록한 후에 "특정 위치에 표시할 셀을 요청하는 메서드" 위치로 가서 cell을 message cell 클래스로 다운캐스팅 시켜주고, label의 텍스트를 변경시킬 수 있게 코드를 변경해준다. 

 

-우리가 긴 문자를 보낼 때 label의 라인이 1이라면 문자가 잘려서 보여지기 때문에 라인을 0으로 맞춰서 문자가 잘리지 않게 한다.

 

 

3. 스위프트 딥다이빙(타입 캐스팅)

-타입캐스팅은 인스턴스의 타입을 확인 하거나, 해당 인스턴스를 슈퍼 클래스나 하위 클래스로 캐스팅 하는 방법이다.

swift에서 타입 캐스팅은 ' is ' 나 ' as ' 로 구현하며, 타입 캐스팅을 이용하여 타입이 프로토콜에 적합한지 여부도 확인할 수 있다.

 

-is는 checking type이다. is는 타입을 체크하는 연산자로, 런타임 시점에 실제 체크가 이루어진다.

표현식이 type과 동일하거나, 표현식이 type의 서브 클래스인 경우 -> true

이외에는 -> false

 

let cell = UITableViewCell( )

 if cell is UITableViewCell { print( "The types match!" ) } 

위 코드를 보면 알 수 있듯이 ' is ' 를 통해 cell이 정말 UITableViewCell 타입인지 알아 볼 수 있다. 즉, ' is ' 는 type checking에 사용된다.

 

as!는 다운캐스팅에 사용된다. 수퍼클래스는 서브클래스에 있는 프로퍼티나 메서드를 사용할 수 없기 때문에 서브클래스로 다운 캐스팅하여 사용가능하게 만든다. 

-as?는 다운캐스팅이 가능한지 여부를 따질 때 사용된다. ex) if let animal as? fish {   } 

-as는 서브클래스를 다시 수퍼클래스로 업캐스팅할 때 사용된다. 

 

-func findNimo( from animals : [ Animal ] {                // Animal 유형의 배열을 받겠다. animals는 내부 프로퍼티

          for animal in animals{                                 

               if animal is Fish {                                  // 다운캐스팅을 위해 확인하는 코드 

                     print( animal.name )                       

                     let fish = animal as! Fish               //breatheUnderWater 메서드를 사용하기 위해서는 Fish를 상속

                     fish.beatheUnderWater( )                 받고 있어야 하기 때문에 as!를 통해 다운캐스팅
               }
         }
}

 

 

4. 데이터베이스 설정 및 복원에 데이터 저장

 

-이 단원에서는 채팅을 쳤을 때 누가 보냈는지, 어떤 메시지를 보냈는지 파이어베이스 데이터베이스에 저장하는 방법을 알 수 있다.

 

-먼저 파이어베이스 프로젝트에서 data base를 만든다.

-> cloud firestore 초기화를 위해 xcode 프로젝트의 appdelegate에서 let db = firesotre.firestore() 코드를  추가

-> message body와 message sender를 상수로 지정한다.

ex)

 if let messageBody = messageTextfield.text, messageSender = Auth.auth().currentUser?.email {   }

 

위의 코드에서 messageSender에 보낸 사람의 이메일을 저장해야 하는데, 이 정보는 firebase의 사용자 관리에 들어가보면 현재 로그인한  사용자의 정보를 가져올 수 있다. 

 

데이터를 추가하는 단계

ex)

db.collection( collection name을 지정한다. String 유형 )
.addDocument( data : [  data base로 보내 저장하려는 데이터를 배열 형식으로 지정한다. 우리는 메세지 센더와 바디를 보내기로 결정했다. ] )
{ ( error ) in if let e = error {  print( "데이터를 저장하는데 문제가 생겼다. " ) } 
else{ print( "데이터를 저장하는데 성공함." ) } }

 

전체 코드는

if let messageBody = messageTextfield.text, messageSender = Auth.auth().currentUser?.email {

       db.collection( K.Fstore.collectionName ).addDocument( data : [ K.Fstore.senderField : messageSender,

                                                                                                                    K.Fstore.bodyField : messageBody] ) {

       ( error ) in if let e = error {  print( "데이터를 저장하는데 문제가 생겼다. " ) } else{ print( "데이터를 저장하는데 성공함." ) } }  }

 

 

5. 복원에서 데이터 검색

-이 단원에서는 파이어베이스 프로젝트에서 cloud firestore에 message collection에 있는 데이터를 가져와서 xcode 프로젝트에서 읽어보는 방법을 알 수 있다. 

 

6. 복원에 대한 업데이트 수신 대기

-이전 단원에서 시뮬레이터를 돌려보면 실시간으로 텍스트 필드에 작성하여 보내는 메세지는 클라우드에 저장은 되지만, 뷰가 다시 로드되어야만 사용자의 눈에 업로드 된 메세지가 보였다. 이 문제를 해결하기 위해 계속 업데이트를 해주는 메서드를 사용한다.  

 

7. firestore에서 검색된 데이터를 정렬하는 방법.

-데이터베이스에서 검색하는 메세지를 정렬할 수 있도록 하는 방법을 배운다. 

-먼저 senderpressed 메서드에서 우리는 cloud firestore로 messageBody와 messageSender를 보냈었는데 한 가지 정보를 더 추가해서 보낸다. 바로 date 정보로. date().timeintervalSince1970의 정보를 보내서 메세지마다 시간 정보를 저장하게 한다. 

-> loadMessage 메서드에서 .order(by : K.Fstore.dateField) 코드를 추가하여 정보를 업데이트 할 때 시간의 순서대로 정보를 볼 수 있도록 만든다. 

 

8. 키보드를 관리하고, swift package manager를 사용하는 방법.

-이 단원에서는 텍스트필드를 눌렀을 때 우리가 어떤 메시지를 타이핑 하는지 확인할 수 있는 bar를 덮고 텍스트 필드가 올라오는 문제를 cocoapods이나 swift package manager를 통해 해결하는 방법을 알 수 있다. 

-cocoapods이나 swift package manager를 깔고, appdelegate에서 import IQKeyboardManagerSwift를 한다. 

-> 원하는 속성 및 기능을 찾아서 코드를 작성하면 끝! 

ex) IQKeyboardManager.shared.enable = true   //텍스트 필드가 올라오는 높이에 맞춰 bar도 같이 올라온다. 

      IQKeyboardManager.shared.enableAutoToolbar = false  //자동 완성 기능을 없애준다.

      IQKeyboardManager.shared.sholdResignOnTouchOutside = true //다른 화면을 터치하면 텍스트필드가 내려감. 

 

9. 마무리 터치 : UI및 UX개선사항

1. 발신자와 수신자를 구분하는 방법 : 

2. 최신 채팅 메세지를 보고 싶을 때 스크롤을 내려서 보지않고 자동으로 보이게끔 하는방법. 

3. navigationBar 조정하는 방법.

 

 

 

 

 

 

 

 

 

 

 

 

'UIKit' 카테고리의 다른 글

UICompositional Layout에 관하여  (0) 2023.08.21
CGPoint, CGSize, CGRect에 관하여  (0) 2023.01.12