3월 20일 TIL (TodoList)

이승원·2024년 3월 20일
1

TIL

목록 보기
48/75
post-thumbnail

Todolist (.cont)

  • 오늘은 Todolist을 어느정도 끝을 낸거 같다...
  • 추가하기 View 완성
  • Tag Collection View 추가
  • 상세페이지 보기
  • 추가하기 버튼 변경
  • TimePicker timezone 설정

추가하기 View 완성

  • 어제 사실 추가힉 View를 만들어 놓긴 했지만, 실질적으로 기능이 구현이 되어 있는건 아니었다.
  • 일단 어제 제일 큰 문제는 같은 Storyboard 에다가 두개의 다른 viewController를 생성해서 문제가 발생했다.
    • 이유는 잘 모르겠으나, 두개의 ViewController 사이가, segue 로 하든, delegate 로 하든 데이터가 전송도 안되고 받는것도 안됐다.
    • 결국 새로 Storyboard를 만들어서 했다.
    • 이렇게 하니깐 바로 된다... 너무 허무했지만, 뭐라도 배웠다는 것에 감사한다.
  • 그리고 어제는 Textviewplaceholder 가 없었는데, 오늘은 새로 추가 했다.
  • textView delegate 를 활용해서 Textview 가 수정중인지 아닌지을 확인해서 알 맞는 Action을 추가 했다. (아래 코드)
extension DetailsViewController : UITextViewDelegate {
    func textViewDidBeginEditing(_ textView: UITextView) {
        if textView.text == textViewPlaceHolder{
            textView.text = nil
            textView.textColor = .black
            textView.textContainerInset = UIEdgeInsets(top: 20, left: 20, bottom: 0, right: 20)
        }
    }
    
    func textViewDidEndEditing(_ textView: UITextView) {
        if textView.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            textView.text = textViewPlaceHolder
            textView.textColor = .lightGray
            textView.textContainerInset = UIEdgeInsets(top: (textView.bounds.height - textView.contentSize.height) / 2 - 10, left: 0, bottom: 0, right: 0)
        }
    }
}

memoTextView.delegate = self
  • 그리고 중간에 요소들을 감싸고 있는 테두리가 있는데, 저건 야매(?)로 만들었다. 원래는 따로 View 를 사용해서 해당 요소들을 안에 넣어서 관리를 해야할텐데. 이미 만들어 놓아서 다시 바꾸고 너무 시간이 올릴꺼 같아서 SubView 를 활용했다.
  • 사실 Subview를 사용을 해도 되는건지 잘 모르겠다. Subview란 현재 View에 말그대로 Subview를 추가해서, 그 위에 올리는거다.
  • 그래서 나는 view 하나를 생성해서, contraints를 원하는 사이즈에 맞게끔 설정한 다음에, backgroundColor.clear로 설정을 했는데, 처음에는 버튼들이 안 눌렸다. 상식적으로 생각해봐도 그위에 쌓는거니깐 안된다는걸 알았다. 그래서 찾아보니 SubView를 뒤에 위치할 수 있었다.
  • 그리고 Subview를 사용할때 주의 해야할 문제는, subview를 추가 한다음에 contraints 를 설정해줘야 한다.
		let backgroundView = UIView(frame: self.view.bounds)
        backgroundView.backgroundColor = .clear
        backgroundView.layer.cornerRadius = 20
        backgroundView.layer.borderWidth = 5
        backgroundView.layer.borderColor = UIColor.black.cgColor
        self.view.addSubview(backgroundView)

        // safe area를 고려하여 오토레이아웃 설정
        backgroundView.translatesAutoresizingMaskIntoConstraints = false
        backgroundView.topAnchor.constraint(equalTo: titleTextField.bottomAnchor, constant: 5).isActive = true
        backgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
        backgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10).isActive = true
        backgroundView.bottomAnchor.constraint(equalTo: memoTextView.topAnchor,constant: -5).isActive = true
        self.view.sendSubviewToBack(backgroundView)

Tag Collection View 추가

  • 아이폰 미리알림 앱을 보니깐 태그들을 정리 해놓을수가 있었다. 그래서 나도 그걸 따라서 만들어보자는 생각을 Tag 기능을 추가로 구현하게 되었다.
  • 처음에는 따로 View를 만들어서 Collection View 를 띄워서, 사용자가 선택하는 방식으로 진행하려고 했는데, 솔직히 자신이 없었고, hierichy 가 너무 깊어지는거 같아서, 사용자 측면에서 안좋을 꺼 같아서 다른 방식으로 표현을 하기로 했다.
  • 태그 Label 오른쪽에 CollectionView를 만들어서 태그를 보여주는 방식으로 하고, 추가할때는 Alert Controller를 사용하자는 방식으로 진행했다.
  • 기존 Todo 구조체에다가 Tag 배열을 만들고, 해당 배열에 tag 들을 문자열로 저장해서, 해당 배열을 돌면서 CollectionView를 구현했다.
  • CollectionView를 할때 제일 문제는 역시나 Cell 사이즈 조정인거 같다.
  • 처음에는 엄청 삽질을 했는데, 인터넷에서 찾아보니 글자크기에 따라서 cell 사이즈를 조정해주는 걸 구현한 분이 있어서 해당 코드를 따와서 내 코드에 맞게끔 구현했다.
  • 방법은 NSAttributedString를 사용해서 해당 길이를 폰트에 맞게 구한 다음에, 해당 길이를 이용해서 cell 사이즈를 유동적으로 바꾸는 것이다.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        var tag : String
        if currentTodo != nil {
            tag = (self.currentTodo?.tag[indexPath.row])!
        }else{
            tag = self.newTodo.tag[indexPath.row]
        }
        let attributes = [NSAttributedString.Key.font: UIFont(name: font, size: 14)]

        let tagSize = (tag as NSString).size(withAttributes: attributes as [NSAttributedString.Key: Any])
        return CGSize(width: tagSize.width + 20, height: 30)
    }
  • 그리고 태그를 클릭시에 삭제하는 것도 구현을 했다.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if isEnabled {
            if currentTodo != nil {
                currentTodo?.tag.remove(at: indexPath.row)
            }else{
                newTodo.tag.remove(at: indexPath.row)
            }
            self.tagCollectionView.reloadData()
        }
    }
  • 코드를보면 계속 isEnabled, currentTodo 이걸 확인하는데, 이건 바로 아래 부분에서 설명하겠다.

상세페이지 보기

  • 각각의 Todo의 정보가 있는데, 메인 페이지에선 실질적으로 확인할 수 가 없다. 따라서 상세페이지 보기를 만들려고 했는데, 또 새로 View를 만들기엔 아까워서, 추가하기 View를 활용해서 상세페이지 보기 View를 만들었다.
  • CurrentTodo : Todo? 를 이용해서, 만약에 Todo를 클릭해서 해당 View를 로드를 하면, CurrentTodo 에다가 해당 Todo를 저장한다, 만약에 그냥 추가하기 버튼으로 해당 view를 로드를 했다면, nil상태가 된다.
  • 즉 쉽게 말하면 CurrentTodo를 활용해서 현재 사용자가 보고 있는 View가 추가를 위함인지, 아니면 기존에 있는 Todo를 보기 위함인지 판단하기 위해서다.
  • 그리고 상세페이지에서는 모든 수정이 불가능하게끔, isEnable : Bool 를 이용해서, 모든 요소들의 상태를 제어한다. 만약 상세페이지에서 변경하기 버튼을 누르면, isEnable.toggle()을 호출하고, viewDidLoad()를 다시 호출한다.
  • 즉 하나의 View로, 상세페이지, Todo 변경, 새로운 Todo 추가까지 사용한것이다.
  • 위에 Navigation Title 도 변경해서 헷갈리지 않도록 구현했다.
  • 또한 사용자가 수정하는 페이지라는것을 알수 있도록 TextViewAllignment도 수정할때는 변경된다.

추가하기 버튼 변경

  • 기존에는 우측상단에 추가하기 버튼이 있었는데, 너무 안이뻐서 다양한 어플들을 찾아봤다. 미리 알림 같은 경우에는 Tab Bar 즉 화면 하단에 있는 거를 활용해서 추가하기 버튼을 만들고, 또 다른데에서는 그냥 우상단에 Navigation Bar Item을 활용해서도 했지만, 이쁘다는 생각이 안들어서 SubView를 해봤으니깐 또 해보자는 생각으로 TableView 위에다가 버튼을 만들기로 했다.
  • 이것도 마찬가지로 Button을 먼저 생성하고, customize 한다음에, subView에 추가를 하고, Contraint를 설정해줬다.
let button = UIButton(type: .system)
        button.setImage(UIImage(systemName: "plus"), for: .normal)
        button.contentVerticalAlignment = .fill
        button.contentHorizontalAlignment = .fill
        
        button.backgroundColor = .black
        button.tintColor = .white
        button.layer.cornerRadius = 40
        button.layer.borderColor = UIColor.black.cgColor
        button.layer.borderWidth = 5
        button.layer.masksToBounds = true
        view.addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false

        // 버튼의 leading, top 제약 추가
        button.trailingAnchor.constraint(equalTo: MyTableView.trailingAnchor, constant: -30).isActive = true
        button.bottomAnchor.constraint(equalTo: MyTableView.bottomAnchor, constant: -50).isActive = true
        // 버튼의 너비, 높이 제약 추가
        button.widthAnchor.constraint(equalToConstant: 80).isActive = true
        button.heightAnchor.constraint(equalToConstant: 80).isActive = true
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)


TimePicker locale 설정

  • TimePicker 에서 Date를 print해보면 실제 시간이 다르게 나온다. 그건 우리나라 시간이 아니라, 그 이유는 시간 기준이 UTC로 기본설정이 되어 있기 때문이다.
  • 그래서 수정을 했는데, 뭔가 또 꼬인것 같다.. 이건 내일로 미루자..!

이후 계획!

  • 각 태그, 혹은 시간 별로 section을 나눠서 보여주기? (카테고리)
  • cell이 펼쳐질수 있으면 조금 더 좋아보일꺼 같다..
  • 피드백을 받아보고! 수정할껀 수정하자.
profile
개발자 (진)

2개의 댓글

comment-user-thumbnail
2024년 3월 20일

오.. 뷰컨트롤러를 추가하고 계시군요! 오늘도 많이 배우고 갑니다 ㅎ

답글 달기
comment-user-thumbnail
2024년 3월 20일

여기가 과제맛집이네요 .. 배움의 공간

답글 달기