[내일배움캠프] 260120 TIL - reduce, 코드베이스 ui

Bambu·2026년 1월 20일

내배캠 TIL

목록 보기
22/52

1. 모닝 스터디

1) reduce 활용

reduce 고차함수는 단순히 배열같은 컬렉션을 하나의 연산을 하여 결과값을 나타내는 용도로만 사용할 수 있다고 생각했다.

하지만 reduce 함수 내에 조건을 부여하여 단순한 사칙연산뿐만 아니라 원하는대로 마치 filter를 사용하는 것처럼 활용할 수 있다는 점을 알았다.

2. 코드베이스 UI 만들기

1) 초기 세팅

  1. 스토리보드 삭제
  2. info.plist에서 Storyboard Name 삭제
  3. 프로젝트 파일의 targets -> Build Settings -> main 검색하여 UIKit MainStoryboard File Base Name 항목 삭제
  4. SceneDelegate에 초기 화면 설정
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
	guard let windowScene = (scene as? UIWindowSceene) else { return }
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = ViewController() // 기본 VC 설정
    window.makeKeyAndVisible() // 활성화
    self.window = window
}

2) 실습 - 카운팅 앱 만들기

import UIKit
import SnapKit

class ViewController: UIViewController {

    private var num: Int = 0
    var countLabel = UILabel()
    
    var minusButton = UIButton()
    var plusButton = UIButton()
    var resetButton = UIButton()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setUI()
        setButtonAction()
    }

    func setUI() {
        setLabel()
        setButton()
        
        [countLabel, minusButton, plusButton, resetButton].forEach {
            view.addSubview($0)
        }
        
        countLabel.snp.makeConstraints {
            $0.width.equalTo(80)
            $0.center.equalToSuperview()
        }
        
        [minusButton, plusButton].forEach { (btn: UIButton) in
            btn.snp.makeConstraints {
                $0.width.equalTo(80)
                $0.height.equalTo(30)
                $0.centerY.equalTo(countLabel)
            }
        }
        
        minusButton.snp.makeConstraints {
            $0.trailing.equalTo(countLabel.snp.leading).offset(-32)
        }
        
        plusButton.snp.makeConstraints {
            $0.leading.equalTo(countLabel.snp.trailing).offset(32)
        }
        
        resetButton.snp.makeConstraints {
            $0.width.equalTo(80)
            $0.height.equalTo(30)
            
            $0.centerX.equalToSuperview()
            $0.top.equalTo(countLabel.snp.bottom).offset(32)
        }
    }
    
    func setLabel() {
        countLabel.text = "\(num)"
        countLabel.textColor = .white
        countLabel.font = .systemFont(ofSize: 45, weight: .bold)
        countLabel.textAlignment = .center
    }
    
    func setButton() {
        minusButton.setTitle("-", for: .normal)
        minusButton.backgroundColor = .red
        
        plusButton.setTitle("+", for: .normal)
        plusButton.backgroundColor = .blue
        
        resetButton.setTitle("초기화", for: .normal)
        resetButton.backgroundColor = .gray
        
        [minusButton, plusButton, resetButton].forEach {
            $0.titleLabel?.textColor = .white
            $0.layer.cornerRadius = 8
            $0.clipsToBounds = true
        }
    }
    
    func setButtonAction() {
        let minusNum = UIAction { [weak self] _ in
            self?.num -= 1
            self?.updateLabel()
        }
        let addNum = UIAction { [weak self] _ in
            self?.num += 1
            self?.updateLabel()
        }
        let reset = UIAction { [weak self] _ in
            self?.num = 0
            self?.updateLabel()
        }
        
        minusButton.addAction(minusNum, for: .touchUpInside)
        plusButton.addAction(addNum, for: .touchUpInside)
        resetButton.addAction(reset, for: .touchUpInside)
    }
    
    func updateLabel() {
        countLabel.text = "\(num)"
    }
}

→ SnapKit을 처음 활용해보았는데, offset 개념이 아직 익숙하지 않다.
사용하다보면 점차 익숙해지리라 믿는다!

그 부분 말고는 예전보다 작성해야할 코드가 줄어들어 유용한 것 같다.

3. 과제 피드백

1) 삼항 연산자 오류

야구게임 과제에서 게임 기록을 관리하는 RecordManageraddRound() 함수에 버그가 있었다.

기존 코드

func addRound() {
	record.round = record.attempts.isEmpty ? record.round : +1
    record.attempts.append(0)
}

삼항 연산자에서 false 부분에 +1로 표기하였는데, +=1의 동작을 생각하고 저렇게 작성하였으나 다시 보니 record.round = 1과 동일하였다.

그래서 3번째 게임부터는 정상적으로 기록이 되지 않고 2번째 기록에 시도횟수가 더해지고 있었다.

변경 코드

func addRound() {
	record.round = record.attempts.isEmpty ? record.round : record.round + 1
    record.attempts.append(0)
}

record.round를 증가시키는 식을 수정하자 정상적으로 작동하였다.

2) 종료하기 구현부

기존 코드

func start() {
	while true {
    	...
        
        switch selected {
        ...
        case .exit:
        	...
        	exit(0)
        }
    }
}

위 코드 이전에는 isExit 변수를 생성하여 그 변수로 게임의 종료를 결정했었는데, 과제 해설 영상을 보고 exit(0)라는 게 있구나~하면서 바꾸었었다.

하지만 튜터님께서 exit(0)는 프로그램을 강제 종료시키는 함수이기에 GameController에서 호출하기에는 해당 객체의 책임을 벗어나는 일일 수 있다고 조언해주셨다.

main.swift에서 호출해야 더 적절할 것 같다고 피드백주셨는데, 그렇다면 사실 main에서는 게임이 종료되더라도 다른 작업이 일어날 수 있으리라 생각하여 GameController가 게임을 끝내는 방식으로 수정하였다.

변경 코드

func start() {
	var isExit = false
    
    while !isExit {
    	...
        
        switch selected {
        ...
        case .exit:
        	...
            isExit = true
        }
    }
}

예전에 구현했듯이 isExit 변수를 통해 게임을 종료하도록 수정하였다.

profile
안녕하세요, iOS 개발을 공부하고 있는 Bambu입니다. (프로필: Swifticons)

0개의 댓글