좋은것: 할 일이 마무리되어 개발을 할 수 있음! 새롭게 배우는 게 너무 많아서 좋고 하나하나 될 때마다 눈이 트이는 기분이 듬.
나쁜것: 나 너무 느림... 배포 될 수 있을까..?
월간통계뷰, 입력화면뷰, 카드화면뷰 제작하고 연결하였고
지금은 API 연결을 시도 중에 있음...
첫번째로는 키보드가 올라올 때 뒤에 텍스트필드가 가려지니까 이걸 뷰를 강제로 올리게 하는 문제인데, 키보드를 동작하는 방식이 Notification을 사용하는 것과, 프로토콜만들어서 동작하게 하는 것과 델리게이트사용해서 하는 것이 있었고 또 찾아보니까 iOS 15.0부터 새로나온 방식이 있었지만 일단 우리 버전이 이거보다 낮아서 패스하고 먼저 프로토콜로 코드를 만들어서 했었다.
import UIKit
protocol KeyboardEvent where Self: UIViewController {
var transformView: UIView { get }
func setupKeyboardEvent()
}
extension KeyboardEvent where Self: UIViewController {
func setupKeyboardEvent() {
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification,
object: nil,
queue: OperationQueue.main) { [weak self] notification in
self?.keyboardWillAppear(notification)
}
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification,
object: nil,
queue: OperationQueue.main) { [weak self] notification in
self?.keyboardWillDisappear(notification)
}
}
func removeKeyboardObserver() {
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
private func keyboardWillAppear(_ sender: Notification) {
// keyboardFrame: 현재 동작하고 있는 이벤트에서 키보드의 frame을 받아옴
// currentTextField: 현재 응답을 받고있는 UITextField를 알아냅니다.
guard let keyboardFrame = sender.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue,
let currentTextField = UIResponder.currentResponder as? UITextField else { return }
// Y축으로 키보드의 상단 위치
let keyboardTopY = keyboardFrame.cgRectValue.origin.y
// 현재 선택한 텍스트 필드의 Frame 값
let convertedTextFieldFrame = transformView.convert(currentTextField.frame,
from: currentTextField.superview)
// Y축으로 현재 텍스트 필드의 하단 위치
let textFieldBottomY = convertedTextFieldFrame.origin.y + convertedTextFieldFrame.size.height
// Y축으로 텍스트필드 하단 위치가 키보드 상단 위치보다 클 때 (즉, 텍스트필드가 키보드에 가려질 때가 되겠죠!)
if textFieldBottomY > keyboardTopY {
let textFieldTopY = convertedTextFieldFrame.origin.y
// 노가다를 통해서 모든 기종에 적절한 크기를 설정함.
let newFrame = textFieldTopY - keyboardTopY/1.6
transformView.frame.origin.y -= newFrame
}
}
private func keyboardWillDisappear(_ sender: Notification) {
if transformView.frame.origin.y != 0 {
transformView.frame.origin.y = 0
}
}
}
다음과 같이 키보드 매니저형태로 코드를 작성하고 이를 뷰컨에서 채택하는 방식으로 하려했지만 바아로 실패하고 빠르게 Notification으로 그냥 뷰컨이 힘들든 말든 급하니 함수들로 박아넣었다...
그랬더니 문제가 텍스트필드를 누를 때 한번 더 올라가고 그 다음에 또 한번 올라가는 것이 아닌가... 그래서 !isKeyboardVisible이라는 불 값을 이용해서 처음 한 번 보이면 그 다음부턴 또 동작하지 못하게 하였고 그러니까 해결은 됐는데 보니까 키보드를 다시 내리게하는 동작을 넣지 않았어서 따로 Extenstion으로 빼서 hideKeyboard()로 만들어서 뷰컨에 넣어주었다.
두번째로 입력화면에서 위에 카테고리 버튼을 눌렀을 때 아래 이미지뷰의 사진이 변해야하는데 이게 뷰컨안에 뷰가 있고 또 그 뷰 안에 셀을 누르는거라서 어떻게 클로저를 전달하는지 몰랐어서 많은 고민을 했었다.
기존 IconButton으로 UIButton을 상속받는 친구를 따로 만들었었는데 이 친구에 원래 tap으로 클로저를 만들어놨지만 이걸 지우고 iconSelectedView에서 새로 tapIcon을 만들어 여기에 인자를 넣었다. icon인자를 통해서 뷰컨에서 인식할 수 있도록 onIconTapped라는 새 클로저를 또 뷰에서 만들어서 연결 연결지어 했더니 성공!
5개 아이콘 중에 하나만 border가 생기도록 하는 것도 바로 만들 수 있었다.
다음은 월간통계뷰에서 각 카테고리를 눌렀을 때 해당 카테고리에 맞는 상세 뷰가 뜨고 그 상세뷰에 UICollectionView로 해당 일자나 카테고리에 맞는 여러 내역을 보여주게 하려했는데 현재 잘 안되고 있다......
아쉬운 부분을 개선하기 위해서 일단 데모데이때까진 배포는 불가능하지만 절대 끝난게 아니라서 배포까지 계속 진행할 것같다.
찾았을 때 좋았던 레퍼런스들은 노션에 따로 정리를 해두고 있어서 배포가 끝나는대로 내가 이번에 앱을 만들면서 부족했던 부분들과 배운 점들을 다시 정리해서 또 블로그에 올려볼 예정이다.
일단 API연결에 이상이 없는지부터 보면서 각 data 바인딩과 연결이 잘 이어지는지를 봐야할 것같다. 그리고 담주엔 심사를 넣어보고싶다!!