포스트

단어장 프로젝트 (3)

3일차 시작

오늘은 휴일인데 게임 기본적인건 구현이 완료되어서 그래도 쉬는날이어도 하루에 하나는 해야하지 않을까 싶어서

간단하게 FlashCard쪽 UI를 디자인 해본다.

기본 틀은 비슷하게 가면서 안에 UILabel을 크게 하면 좋을듯 하다.

simulator_screenshot_51F190AC-C77C-46BC-AFF2-D54DCAD57623

일단 디자인은 완료…

특이점이라면

1
2
3
4
5
6
7
8
lazy var frameView: UIView = {
        let view = UIView()
        view.addSubview(wordLabel)
        view.addSubview(answerLabel)
        view.layer.borderWidth = 1
        view.layer.cornerRadius = 10
        return view
    }()

UIView를 써서 두 label을 안에 넣어줬다는 것이다.

기본 기능 구현

우선은 단어를 가져와야하므로 이전에 썼던 Generator를 그대로 이용한다.

1
2
3
private func generate() {
        wordList = dummyGenerator.makeDummy()
    }

그뒤에 이것도 사지선다형 게임과 비슷한데 UIupdate가 필요하므로 함수를 하나 만들고 그전에 했던것과 비슷하게 함수를 만들어준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private func updateUI () {
        if currentNumber > wordList.count - 1 {
            let alert = alertController.makeAlertWithCompletion(title: "마지막 단어입니다.", message: "다시 시작하시겠습니까?\n단어는 랜덤으로 다시 만들어집니다.") { [weak self] _ in
                self?.currentNumber = 0
                self?.generate()
            }
            self.present(alert, animated: true)
        } else {
            flashBodyView.wordLabel.text = wordList[currentNumber].words
            flashBodyView.answerLabel.isHidden = true
            flashBodyView.answerLabel.text = wordList[currentNumber].meaning
        }
        
    }

포인트는 항상 정답 레이블은 보이지 않는 상태가 되어야 한다. 그래서 hidden을 default로 잡아두었고,

마지막 페이지일때 다시 연습하게끔 유도를 하면 어떨까 싶어 Alert를 띄운다.

Alert역시 클래스로 만들어서 가져다 쓰는게 나을것으로 판단.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class AlertController {
    
    func makeAlertWithCompletion(title: String, message: String, completion: @escaping (UIAlertAction) -> Void) -> UIAlertController {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "확인", style: .default, handler: completion))
        alert.addAction(UIAlertAction(title: "취소", style: .cancel))
        return alert
    }
        
    func makeNormalAlert(title: String, message: String) -> UIAlertController {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "확인", style: .default))
        return alert
    }
}

다음과 같이 handler가 있고 없고의 함수로 나눠준다.

updateUI의 alertController가 바로 지금 위에 구현한 저녀석이다.

이젠 gesture를 만들어준다.

터치를 하면 단어뜻이나오고, swipe를 하면 다음 단어를 보이게 할생각이다.

1
2
3
4
5
6
7
8
private func addGesture () {
        let touchGesture = UITapGestureRecognizer(target: self, action: #selector(showAnswer))
        let swipeLeftGesture = UISwipeGestureRecognizer(target: self, action: #selector(showNext))
        let swipeRightGesture = UISwipeGestureRecognizer(target: self, action: #selector(showNext))
        swipeLeftGesture.direction = .left
        swipeRightGesture.direction = .right
        flashBodyView.gestureRecognizers = [touchGesture, swipeLeftGesture, swipeRightGesture]
    }

다음과 같이 구현해준다.

몰랐는데 swipeGesture의 경우엔 반드시 direction을 설정해 주어야 한다.

지금같은 경우엔 gesture가 여러개이므로 addGesture 보다는 gestureRecognizers를 사용하여 배열에 담아주는게 더 낫다.

그리고 selector의 함수들은 이렇게 적었따.

1
2
3
4
5
6
7
8
 @objc func showAnswer() {
        flashBodyView.answerLabel.isHidden = false
    }
    
@objc func showNext() {
        currentNumber += 1
        updateUI()
    }

아주 심플하다.

지금은 문제를 가져올때 20개를 가져오지만 나중엔 저것도 바꾸게끔 해야할듯하다.

실행하면?

잘된다.

May-15-2024 23-32-01

단어의 마지막에서 다음을 눌렀을때 마지막의 단어가 그대로 보이는 상태에서 다음 단어가 시작되는 문제가 있어 코드를 하나 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private func updateUI () {
        if currentNumber > wordList.count - 1 {
            let alert = alertController.makeAlertWithCompletion(title: "마지막 단어입니다.", message: "다시 시작하시겠습니까?\n단어는 랜덤으로 다시 만들어집니다.") { [weak self] _ in
                self?.generate()
                self?.currentNumber = 0
                self?.flashBodyView.wordLabel.text = self?.wordList[self!.currentNumber].words // added
            }
            self.present(alert, animated: true)
        } else {
            flashBodyView.wordLabel.text = wordList[currentNumber].words
            flashBodyView.answerLabel.isHidden = true
            flashBodyView.answerLabel.text = wordList[currentNumber].meaning
        }
    }

오늘은 여기까지.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.