ToDoList 앱 만들기 (2)

 

2024.03.19 - [◽️ Programming/T I L] - ToDoList 앱 만들기 (1)


오늘도 하루종일 ToDoList 만들기에만 모든 시간을 다 쏟았다.. 내일은 화면 이동 , 데이터 이동 관련 강의 좀 꼭 들어야 할 것 같다.

목표는 생성되어있는 Cell 을 애니메이션 효과를 넣어 삭제하는 것 까지 기능 구현을 완료하는게 목적이었는데

아직까지 해결되지 않은 문제 때문에 목표치를 달성하지 못했다..

내일은 꼭 해결방법을 얻어 원하는 목표치까지 달성 하고 강의까지 듣는 알찬 하루였음 좋겠다

어제는 UITableViewDataSource, UITableViewDelegate 를 활용하여 데이터 연결을 한 후 테이블 뷰에 원하는 셀을 띄우는 것 까지 완료하였다.

오늘은 버튼을 눌러 알럿을 띄우고 그 알럿 안에 텍스트 박스를 넣어 새로운 셀을 추가하는 기능과 Switch 버튼을 누르면 해당 일을 마친다는 뜻으로 취소선이 그어지는 기능까지 구현을 완료하였다.

하지만 새로운 셀을 추가했을 때 원래 있었던 셀의 Switch 값이 저장되지 않고 false로 돌아가 이것 때문에 골치가 아팠다..


알럿 컨트롤러 사용

먼저 버튼을 눌러 새로운 셀을 추가하는 기능에 대해서 기록하고자 한다.

먼저 버튼을 눌러 알럿을 띄워 보도록 하자.

@IBAction func addCellButtonTapped(_ sender: UIButton) {

	let alert = UIAlertController(title: "할 일을 추가해 주세요.", message: "", preferredStyle: .alert)
	alert.addTextField { (textField) in
	    textField.placeholder = "입력하세요"
	}
	
	let plusAction = UIAlertAction(title: "추가", style: .default) { [weak self] (_) in
	        guard let textField = alert.textFields?.first, let text = textField.text else { return }
	    let newTodo = Todo(id: self?.cellData.count ?? 0, title: text, isCompleted: false)
	        self?.cellData.append(newTodo)
	        self?.myTableView.reloadData()
	}
	
	let cancelAction = UIAlertAction(title: "취소", style: .cancel, handler: nil)
	
	alert.addAction(plusAction)
	alert.addAction(cancelAction)
	
	present(alert, animated: true, completion: nil)
}

사용자가 버튼을 누르면 메시지를 표시하고 사용자의 입력을 받는 알럿 창을 생성하는 코드를 작성하는 알럿컨트롤러를 사용한 후 alert 변수에 담아줬다.

let alert = UIAlertController(title: "할 일을 추가해 주세요.", message: "", preferredStyle: .alert)

이 중 preferredStyle 을 통해 알럿의 스타일을 두가지 중 선택할 수 있다.

알럿 내 텍스트필드 사용

그 다음 알럿 내 사용자가 텍스트필드를 통해 값을 입력할 수 있도록 기능을 넣어주었다.

alert.addTextField { (textField) in
	    textField.placeholder = "입력하세요"
	}

그 후 빈 박스안에 이용자가 텍스트를 넣을 수 있도록 placeholder를 사용하여 안내 사항을 넣어주었다.

알럿 내 확인/취소 버튼 기능 구현

텍스트 필드에 값을 입력한 다음 추가 버튼을 누르면 입력한 값이 세로운 셀이 되어 테이블 뷰에 올라갈 수 있도록 세팅했다.

let plusAction = UIAlertAction(title: "추가", style: .default) { [weak self] (_) in
        guard let textField = alert.textFields?.first,
			        let text = textField.text else { return }
    let newTodo = Todo(id: self?.cellData.count ?? 0, title: text, isCompleted: false)
        self?.cellData.append(newTodo)
        self?.myTableView.reloadData()
}

guard 문을 사용하여 텍스트 필드 값에 아무것도 넣어지지 않을 상황을 대비해 아무것도 적지 않아도 정상적으로 작동할 수 있도록 바인딩을 해주었다.

 

알럿 내 텍스트필드에 적힌 첫번째 값이 textField 상수에 들어가고 이 상수 안의 text가 text 상수에 저장 될 수 있도록 설정하였다.

그 후 새로운 리스트의 변수로 newTodo 를 설정하여 전날 struct 를 사용하여 설정했던 Todo 값을 불러와 title 명 내 저장된 상수 text 가 들어가도록 설정하고 스위치의 기본 값은 isCompleted 를 활용하여 false 로 정해주었다.

 

그 이후 셀 데이터에 새로운 셀이 추가되도록 .append 를 사용하여 넣어주고 테이블뷰의 값을 reloadDate() 하여 정상적으로 셀이 추가되도록 설정했다.

let cancelAction = UIAlertAction(title: "취소", style: .cancel, handler: nil)

 

알럿 내 취소를 누르면 다시 원래대로 알럿이 꺼지도록 설정했다.

alert.addAction(plusAction)
alert.addAction(cancelAction)

present(alert, animated: true, completion: nil)

 

그 후 구현한 기능을 .addAction() 하여 활성화 해준 후 알럿을 활성화시켜주는 present 메서드를 적용해주면 이렇게 알럿이 잘 구현되게 된다.


하지만 여기서 새로운 셀을 넣게되면 이전의 값이 남아있지 않고 다시 전으로 돌아가는 문제가 발생한다..

취소선은 남아있고 스위치만 문제인 것으로 보아.. 아마 reloadDate() 하는 과정에 isCompleted: false 이놈이 껴있어서 그런 것 같다..

여기까지 생각이 닿는데에도 정말 오래걸렸다.. 튜터님한테 어떻게 해결 할 수 있는지 물어봐야겠다..

 

일단 여기까지 버튼을 눌러 알럿 내 텍스트필드에 텍스트를 기재하고 그 기재한 텍스트가 리스트업이 되는 과정까지 구현할 수 있었다!

스위치 토글 시 title 취소선 생성

다음은 스위치 버튼을 누르면 Cell 내 취소선이 들어갈 수 있도록 기능 구현을 해줄 차례

cell.onSwitchToggle = { isOn in
    if isOn {
        let attributeString = NSMutableAttributedString(string: cell.cellLabel.text ?? "")
        attributeString.addAttribute(.strikethroughStyle, value: 2, range: NSMakeRange(0, attributeString.length))
        cell.cellLabel.attributedText = attributeString
    } else {
        let attributeString = NSMutableAttributedString(string: cell.cellLabel.text ?? "")
        attributeString.removeAttribute(.strikethroughStyle, range: NSMakeRange(0, attributeString.length))
        cell.cellLabel.attributedText = attributeString
    }
    
}

if문을 사용하여 isOn ( 현재 스위치의 값 ) 이 true 일때 취소선이 들어가게 설정하고 그렇지 않을 땐 취소선이 해제되는 식을 만들게 되었다.

해당 식은 외우거나 방식을 이해하는 것 보다 원래 정해져 있는 NSMutableAttributedString 형태로 판단하여 그냥 취소선을 사용해야할 때 동일한 방식으로 사용하면 되겠구나 정도로 이해하고 넘어가기로 했다.

중간에 해당하는 cellLabel 을 잘 변경하여 넣어주기만 하면 될 것 같다.

이렇게 작성한 후 스위치를 토글하면 이렇게 취소선이 나오게 된다!