포스트

FlashChat (8)

TextField 입력시 키보드가 가리는것 방지하기.

IQKeyboardManager를 사용해서 방지를 해보려 한다.

링크에 들어가면 관련 내용이 있다.

바로 이런 기능을 사용하는데 있어 도움을 준다.

1. 해당 라이브러리 추가하기.

이번엔 Package Manager를 이용해서 추가를 하려한다.

전에도 언급했지만, 해당 github repository에 들어갔을때 아래와 같은 파일이 없다면 지원이 되지 않는다.

물론 제작자가 보통은 설치하는 방법을 적어두기에 그걸 따르면 되긴 한다.

  1. File, Add Package~ 클릭

  2. 해당 깃 주소 복사.

  3. 해당 프로젝트를 확인후 설정. (POD X)

  4. 추가 확인.

2. 추가한 라이브러리 설정하기.

이 부분을 AppDelegate.swift 파일에 적용시켜 주면 된다/

3. 작동확인

확인 완료.

4. 부가적인 기능 설정 및 수정

링크 를 들어가면 관련 프로퍼티 설정이 있는데 AppDelegate.swift 안에서 설정을 해주면 된다.

수신자, 발신자 구분하기

현재는 나만 확인할수있는 1인 메신저 형식으로 되어있는데,

이제는 발신자와, 수신자를 구분해보도록 하자.

1. ImageView 추가. 하기

우선 Message.xib 파일로 가서 Right Image View를 복사해서 다시 그자리에 붙여넣긴한다.

그냥 클릭하고 Command + c / Command + v로 해결하자

그리고 제일 오른쪽에 있던 이미지를 왼쪽으로 붙여준다.

이렇게 해주면 된다.

그리고 outlet을 하나 만들어 주자.

leftImageView로 해주었다.

2. 함수를 수정하여 발신자/수신자 구분하기

다시 ChatVC로 돌아가서 cellForRowAt 관련 함수를 수정을 해줄것이다.

우선 메세지 내용을 담은 변수를 하나 만들어 준다.

let message = messages[indexPath.row]

그리고 발신자가 현재 로그인 된사람인지를 if조건으로 나타내고

여러 조건을 설정해준다.

1
2
3
4
5
6
7
if message.sender == Auth.auth().currentUser?.email {
            cell.leftImageView.isHidden = true
            cell.rightImageView.isHidden = false
            
            cell.messageBubble.backgroundColor = UIColor(named: K.BrandColors.lightPurple)
            cell.label.textColor = UIColor(named: K.BrandColors.purple)
        }

그리고 다른사람이 보냈을 경우를 생각하여 else에는 그와 반대로 작성해주자.

그리고 작동을 확인하면?

그리고 새로운 계정을 만들어서 들어가보면?

이렇게 다르게 표현이되는걸 볼 수 있다.

이상태에서 메세지를 보내보면?

잘 구분이 되는것을 볼 수 있다.

3. 추가될때 자동으로 아래로 스크롤 되게 하기.

값이 추가될때마다 loadMessages함수가 트리거 된다.

그러므로 이부분을 수정하면 되겠다.

우리는 tableView.scrollToRow 메서드를 사용할 것이다.

이 메서드를 사용하기전, IndexPath를 먼저 초기화 해준다.

IndexPath의 row에는 message 배열의 마지막 인덱스를 항상 가져와야하므로 message.count-1 을 해준다, section에는 현재 테이블이 하나만 있으므로 0을 해주면 된다.

참고하자.

테스트해보니 잘된다.

4. 내용 입력후 TextField 초기화 하기.

현재는 메세지를 보내면 textField에 내용이 그대로 담겨있다.

그래서 새로운 메세지를 보낼때마다 지워야한다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@IBAction func sendPressed(_ sender: UIButton) {
        
        if let messageBody = messageTextfield.text, let messageSender = Auth.auth().currentUser?.email {
            db.collection(K.FStore.collectionName).addDocument(data: [
                K.FStore.senderField : messageSender,
                K.FStore.bodyField : messageBody,
                K.FStore.dateField : Date().timeIntervalSince1970
                
            ]) { (error) in
                if let e = error {
                    print("There was an issue saving dat to firestore. \(e)")
                } else {
                    print("Successfully saved data")
                    self.messageTextfield.text = "" // new
                }
            }
        }
        
    }

해당부분만 추가해주면 된다 :)

이때 그냥 추가하는게 아니라

비동기 방식으로 처리하게 하여 메인 스레드에서 처리하게 해야한다.

즉 DispatchQueue를 사용해야한다.

1
2
3
DispatchQueue.main.async {
                        self.messageTextfield.text = ""
                    }

이렇게 해주자.

5. Navigation bar 디자인 변경

우선 StoryBoard 에서 Navigation Bar를 클릭하자

Inspector에서 Bar Tint의 색상을 변경하면

모든 Navigation Bar의 색이 변경이 된다.

Title에 관한건 아래 사진 을 참고하여 바꾸면 된다.

Back 버튼의 색상은 여기서 바꾼다.

6. 초기 화면의 Nav Bar 색상 비활성화.

RootVC인 WelcomeVC에 다음과 같이 적어주자

1
2
3
 override func viewWillAppear(_ animated: Bool) {
        navigationController?.isNavigationBarHidden = true
    }

하지만 문제는

다른 화면에서도 이렇게 되어버린다.

즉 우리가 해둔 설정이 계속 이어지게 되는것이다.

1
2
3
 override func viewWillDisappear(_ animated: Bool) {
        navigationController?.isNavigationBarHidden = false
    }

이렇게 반대속성을 바로 적어주면

다음 화면으로 넘어가면 Nav Bar가 다시 생기게 된다.

함수의 Docs내용을 잠깐 보면

super를 사용하라고 되어있다.

super.viewWillAppear(animated) 이걸 꼭 적어주자.

변경이 안될때 하는 방법

Xcode 13.0 이후부터 발생하는 문제라고 한다.

1. StoryBoard

2. viewDidLoad()에 설정

1
2
3
4
5
6
let appearance = UINavigationBarAppearance()
		appearance.configureWithTransparentBackground()
		appearance.backgroundColor = UIColor.systemBlue
		appearance.titleTextAttributes = [.foregroundColor: UIColor.white]
		navigationItem.standardAppearance = appearance
		navigationItem.scrollEdgeAppearance = appearance

ViewController LifeCycle

참고 자료를 한번 읽어 보는걸 추천한다.

1. viewDidLoad() 실행

  • 모든 IBOutlet, IBAction 등 뷰와 관련된 모든 개체가 연결되며 엑세스가 가능해진다.
  • 다만 viewDidLoad()는 뷰가 생성되었을때 딱 한번만 호출된다.

2. viewWillAppear() 실행

  • 화면에 뷰가 나타나기 직전에 호출된다.
    • 사용자는 아직까진 아무것도 볼 수 없다.
  • 특정 UI를 숨기거나, 보여주기엔 좋은 시점.
  • 위의 예시에선 Nav Bar를 숨기게 했다.

3. viewDidAppear() 실행

  • 유져가 화면을 볼 수 있게 된다.

4. viewWilldisappear() 실행

  • View가 사라지기 직전에 호출된다.
  • 애니메이션을 멈추고 UI모습을 바꾸고 싶다면 사용한다.
  • 위의 예시에선 Nav Bar를 숨겼던것을 다시 보이게했다.

5. viewDidDisappear() 실행

  • 이 시점에서는 이미 view는 사라졌다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.