- 개발 일자 : 2022. 1. 19
이건 좀 써둬야겠다고 생각이 드는 것이 한 번씩 있는데 요 알람 앱을 만들면서 좀 더 그런 생각이 많이 들었다
간단한 것들 중에서도 처음 해보는 방식이거나 생각해봐야 할 것들이 끊임없이 있더라
(느닷없이 왼쪽 엄지 손가락 관절이 아픈데,, 왜지)
암튼 생각 정리가 필요해서 오늘부터 적기 시작..!
이전 날짜도 중요한 건 적어둬야지
알람 사운드 옵션 화면 추가
- 스토리보드에 사운드 옵션 선택을 위한 화면(AlarmSoundVC) 추가
- 번외로 셀 선택했을 때 deselect 하는 코드를 tableView(didDeselectRowAt:) 메서드에 넣고 있었다는 걸 깨닫고 tableView(didSelectRowAt:) 메서드로 변경해줌
- AlarmSoundVC 에 사운드 목록을 표시할 테이블 뷰를 추가해주었음
import UIKit
class AlarmSoundViewController: UIViewController {
@IBOutlet weak var alarmSoundTableView: UITableView!
private var soundList = [
"Alarm Clock",
"Maple Leaf Rag"
]
override func viewDidLoad() {
super.viewDidLoad()
alarmSoundTableView.delegate = self
alarmSoundTableView.dataSource = self
}
}
extension AlarmSoundViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return soundList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "AlarmSoundTableViewCell", for: indexPath)
var content = cell.defaultContentConfiguration()
content.text = soundList[indexPath.row]
cell.contentConfiguration = content
return cell
}
}
선택한 알람 사운드 전달하기
AlarmDetailVC
- 알람 추가 / 편집 화면에서 이전에는 시간만 전달을 했었는데 옵션 기능을 추가함에 따라 알람 객체를 넘기는 것으로 수정함
- AlarmListVC → AlarmDetailVC 로 알람 정보를 전달할 때도 마찬가지
- 따라서 AlarmManager 에 데이터를 전달할 때도 시간 문자열 값이 아닌 Alarm 객체를 넘기도록 전체적으로 수정함
- 알람 목록에서 상세 화면으로 넘어올 때 시간 값을 전달해줬었는데 주고 받는 데이터를 알람 객체로 바꾸면서 여러 부분의 코드에서 시간 값에 대해 Date 타입과 String 타입의 변환이 자주 일어나게 되어 번거로워 짐
→ Alarm 구조체에 저장되는 시간 타입을 Date 로 변경 후 연산 프로퍼티를 사용하여 displayTime 을 문자열 타입으로 정의함
- 스토리보드 상에서 AlarmDetailVC 에서 AlarmSoundVC 로 연결되는 segue 를 추가했고
- 해당 segue 를 실행하게 되면 현재 지정되어 있는 사운드 인덱스 값을 전달함
- AlarmOptionSelecting 타입의 delegate 에 자신을 지정함
→ AlarmOptionSelecting 을 채택하게 됨
→ AlarmSoundVC 에서 선택된 사운드 정보를 받아오기 위함
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "AlarmSoundSegue" {
let alarmSoundVC = segue.destination as? AlarmSoundViewController
alarmSoundVC?.delegate = self
alarmSoundVC?.selectedSoundIndexPath = alarm.soundIndexPath
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
switch indexPath.row {
case 2:
self.performSegue(withIdentifier: "AlarmSoundSegue", sender: nil)
default:
break
}
}
- 또한 AlarmSoundVC 에서 특정 사운드를 선택하고 상세 화면으로 돌아오게 되면 채택한 AlarmOptionSelecting 의 alarmSoundSelected() 함수가 실행되는데
- 이 때 선택된 사운드의 인덱스 값을 받아오게 되고 선택한 값에 따라서 상세 화면의 사운드 옵션 셀의 디테일 값을 설정하게 됨
extension AlarmDetailViewController: AlarmOptionSelecting {
func alarmSoundSelected(indexPath: IndexPath) {
alarm.soundIndexPath = indexPath
alarmOptions[0][2].content = alarmManager.getSoundTitle(at: indexPath)
let indexPath = IndexPath(row: 2, section: 0)
alarmOptionTableView.reloadRows(at: [indexPath], with: .automatic)
}
}
AlarmManager
- 해당 알람의 사운드 정보를 저장하기 위한 IndexPath 프로퍼티를 추가함
- 처음에 사운드 목록에 대한 정보를 AlarmSoundVC 에서 관리한다고 생각하고 사운드 제목이랑 선택 여부?? 같은걸 저장하는 구조체를 갖고 그에 대한 사운드 목록을 만들었었는데 뭔가 좀 이상하다는 생각이 들어서 (타이틀은 고정 상수 값이고 선택 여부는 알람 마다 다른데??)
- 생각해보니 사운드 타이틀 목록은 다른 곳에서도 쓰이기 때문에 AlarmManager 로 옮겼고 (이와 관련해서 필요한 기능이 많아지면 SoundManager 같은걸 만들어야 하나 고민) 각 알람에서 어떤 사운드가 선택되었는지는 알람이 관리하는 게 맞기 때문에 위에 언급한 것과 같이 알람 구조체에 사운드 정보를 가져올 수 있는 soundIndexPath 프로퍼티를 추가함
- 현재 Sound 구조체도 있고 soundList 가 Sound 목록을 갖게 되는데 title 정보 외에 필요한 정보가 없다면 문자열 타입으로 변경할 수도 있음
- indexPath 를 사용해서 사운드 제목을 가져오는 메소드 및 사운드 리스트 항목 개수를 반환하는 함수 및 프로퍼티를 추가함
AlarmSoundVC
- 화면에서 특정 사운드를 선택하고 화면을 종료했을 때 선택된 사운드 정보를 전달하기 위한 AlarmOptionSeleting 프로토콜을 추가
- 선택된 사운드 정보를 갖기 위한 selectedSoundIndexPath 프로퍼티가 추가됨
- 해당 화면에는 저장 버튼이 아닌 뒤로가기 버튼만 있기 때문에 화면이 사라지기 전에(viewWillDisappear 메소드에서) 위임자(delegate)의 alarmSoundSelected 함수를 실행함
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
delegate?.alarmSoundSelected(indexPath: selectedSoundIndexPath)
}
- 이건 번외로 사운드 옵션을 선택한 체크 마크를 하나만 유지하기 위해 어떻게 해야할지 찾아보다가 처음 사용했던 방식이 다음과 같고
참고. ios - UITableView Checkmark ONLY ONE Row at a Time - Stack Overflow
이 때, 스토리보드 상에서 AlarmSoundCell 의 Selection 속성이 None 으로 되어 있는 것이 좋음
→ 그렇지 않으면 선택된 셀이 하이라이트 되기 때문에 일반적으로 tableView(didSelectRowAt:) 메소드가 실행되었을 때 deselectRow() 메소드를 실행해주는데 여기서 이 메소드를 실행하면 tableView(didDeselectRowAt:) 메소드가 실행이 안되었음 (체크 해제가 안됨)
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
- 이후에 선택된 사운드 인덱스 정보를 갖고 있으면 된다는 것을 깨닫고 다음과 같이 수정하였음
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
if selectedSoundIndexPath == indexPath {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
...
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedSoundIndexPath = indexPath
tableView.reloadData()
}
'# iOS | Swift > --- Project' 카테고리의 다른 글
[Alarm] #+3. 알람 레이블 화면 추가 (0) | 2022.02.25 |
---|---|
[Alarm] 1. 기본 알람 목록 및 추가화면 구현, AlarmManager, 삭제 기능 추가 (0) | 2022.02.25 |
[Alarm] #+2. 상세 화면에서 알람 삭제 기능 및 알람 시간 텍스트 표시 수정 (0) | 2022.02.03 |
[Alarm] #+1. 알람 편집 모드 구현 (0) | 2022.02.03 |
[Alarm] #. 설정한 시간에 알람이 울리도록 구현 (0) | 2022.01.26 |