
구현 목표
- 스토리보드로 구현하기
증가버튼을 눌러 레이블의 값을 +1 하기감소버튼을 눌러 레이블의 값을 -1 하기Reset버튼을 눌러 레이블의 값을 초기화하기Push to change View버튼을 눌러 다른 뷰로 이동하기- 코드베이스로 구현하기
증가버튼을 눌러 레이블의 값을 +1 하기감소버튼을 눌러 레이블의 값을 -1 하기Reset버튼을 눌러 레이블의 값을 초기화하기
| 속성 | 요구사항 |
|---|---|
| 숫자 라벨 | Int 형. 0 부터 시작 |
| textColor | white |
| font | boldSystem 폰트. size = 45 |
| textAlignment | center |
| width | 80 |
| constraint | superView 와 center 가 갖게 설정. |
| 속성 | 요구사항 |
|---|---|
| backgroundColor | 감소 버튼은 red, 증가 버튼은 blue. |
| textColor | white |
| width | 80 |
| height | 30 |
| cornerRadius | 8 |
| constraint | centerY 는 모두 숫자 라벨과 같게 설정.감소 버튼은 라벨로부터 왼쪽으로 32 떨어지게 설정.증가 버튼은 라벨로부터 오른쪽으로 32 떨어지게 설정. |
스토리보드에서 카운터 앱을 만들기 위해 우선 조건에 맞도록 UI 요소들을 뷰에 배치해줬다.
우선 뷰의 background의 색을 black으로 설정해주고, label, button 등의 UI 요소들을 배치해 주었다.

한가지 과제와 다른 점은 네비게이션 컨트롤러를 사용하여 다른 뷰로 이동할 수 있도록 구현하였는데, 이는 코드베이스로 똑같은 코드를 작성하고 해당 뷰로 이동할 수 있도록 하기 위하여 네비게이션 컨트롤러를 구현하였다.
다음으로 배치를 마친 UI 요소들의 constraints를 설정해주었다.

마지막으로 각 UI 요소에 대한 값을 코드를 활용하여 설정해주었다.
class ViewController: UIViewController {
private var num: Int = 0
@IBOutlet weak var count: UILabel!
@IBOutlet weak var countUp: UIButton!
@IBAction func countUpAction(_ sender: Any) {
self.num += 1
self.count.text = String(self.num)
}
@IBOutlet weak var countDown: UIButton!
@IBAction func countDownAction(_ sender: Any) {
self.num -= 1
self.count.text = String(self.num)
}
@IBAction func transView(_ sender: Any) {
navigationController?.pushViewController(MyCounterView(), animated: true)
}
@IBAction func reset(_ sender: Any) {
self.num = 0
self.count.text = String(num)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.countUp.setTitle("증가", for: .normal)
self.countDown.setTitle("감소", for: .normal)
}
}
카운터앱을 만들기 위해 우선 필요한 UI 요소들을 정의하였다.
// 증가, 감소 버튼을 누를 때마다 값이 변화하는 카운터 값
private var count: Int = 0
private var countLabel = UILabel() // 카운트 값
private let upButton = UIButton() // 증가 버튼
private let downButton = UIButton() // 감소 버튼
private let resetButton = UIButton() // 리셋 버튼
다음으로 버튼을 눌렀을 때 사용될 액션 메소드를 정해주었다. 증가 버튼을 눌렀을 때는 self.count의 값이 증가하고 이를 self.countLabel의 text로 설정한다.
반대로 감소 버튼을 눌렀을 대는 self.count의 수를 감소 시키고, 이를 self.countLabel의 text로 설정한다.
리셋 버튼은 self.count의 값을 0으로 설정하고 이 값을 self.countLabel의 text로 설정한다.
// 증가 메소드
@objc private func countUp() {
self.count += 1
self.countLabel.text = String(self.count)
}
// 감소 메소드
@objc private func countDown() {
self.count -= 1
self.countLabel.text = String(self.count)
}
// 리셋 메소드
@objc private func reset() {
self.count = 0
self.countLabel.text = String(self.count)
}
마지막으로 각 UI에 대한 오토레이아웃이나 텍스트 값 등을 설정해준다.
private func setUIConfig() {
countLabel.text = String(self.count)
countLabel.font = UIFont.systemFont(ofSize: 45, weight: .bold)
countLabel.textColor = UIColor.white
countLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(countLabel)
upButton.setTitle("증가", for: .normal)
upButton.titleLabel?.textColor = UIColor.white
upButton.backgroundColor = UIColor.blue
upButton.layer.cornerRadius = 8
upButton.addTarget(self, action: #selector(countUp), for: .touchDown)
upButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(upButton)
downButton.setTitle("감소", for: .normal)
downButton.titleLabel?.textColor = UIColor.white
downButton.backgroundColor = UIColor.red
downButton.layer.cornerRadius = 8
downButton.addTarget(self, action: #selector(countDown), for: .touchDown)
downButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(downButton)
resetButton.setTitle("Reset", for: .normal)
resetButton.titleLabel?.textColor = UIColor.purple
resetButton.backgroundColor = UIColor.gray
resetButton.layer.cornerRadius = 15
resetButton.addTarget(self, action: #selector(reset), for: .touchDown)
resetButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(resetButton)
NSLayoutConstraint.activate([
countLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
countLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
upButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
upButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -32),
upButton.widthAnchor.constraint(equalToConstant: 80),
upButton.heightAnchor.constraint(equalToConstant: 30),
downButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
downButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 32),
downButton.widthAnchor.constraint(equalToConstant: 80),
downButton.heightAnchor.constraint(equalToConstant: 30),
resetButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
resetButton.topAnchor.constraint(equalTo: countLabel.bottomAnchor, constant: 30),
resetButton.widthAnchor.constraint(equalToConstant: 80),
resetButton.heightAnchor.constraint(equalToConstant: 30)
])
}
특별히 메소드를 만들지 않고 하나하나 값을 지정해줬는데... 중복되게 사용되는 코드들이 많았기 때문에 나중에는 메소드 등을 활용해서 코드를 줄여보는 것도 좋을 것 같다고 생각했다.

개념 정리
Doc Comments란 문서화를 위해 주석을 작성하는 방법이다. 마크업 방법을 사용하며, Quick Help를 통해 다른 소스파일의 내용을 확인할 수도 있고 다른 사람이 코드의 해석하기 쉽게 하기 위해 작성을 해야하는 것이다.
얼마전 Swift API Design Guideline을 읽은 후 변수나 메소드 등의 네이밍을 하는 방법에 대해 알았다. 그러나 나는 주석을 어떻게 달면 좋을지가 궁금했었는데... 마침 강의에서 문서 주석이라는 개념을 알려줘서 한번 찾아보게 되었다.
문서 주석을 작성하는 방법은 2가지가 있다.
첫 번째는 /// 을 사용하는 방법이다.
/// 문서 주석 작성하기
마치 일반적인 주석을 작성하는 것 같다. 하지만 문서 주석이기 때문에 일반적인 주석과는 확실히 다르다. 어떻게 다른지는 아래에서 조금 더 다뤄보고...
두 번째 방법은 /** */를 사용하는 방법이다.
/**
이 공간은 모두 문서 주석입니다.
*/
이것도 일반 주석을 작성하는 방법과 비슷하다.
일반 주석과 다른 점은 이제부터 나오는데 대표적으로 키워드를 사용할 수 있는 점이다.
문서 주석 키워드는 문서 주석을 작성할 때 특정 키워드를 통해 주석을 강조하고, Quick Help에 표현할 수 있도록 해준다.
게다가 단순히 긴 글을 쓰는 것이 아니라 키워드를 통해 섹션을 나눌 수 있다.
/// Sumarry
///
/// Discussion/Overview
///
/// - Parameters:
/// - [param]: [description]
/// - Returns: [description]
/// - Warning: [description]
/// - Author: [name]
/// - Version: [version number]
/// - Note: [note message]
/// - Tip: [tip message]
/// - Todo: [todo message]
위에서 Quick Help에 표현할 수 있도록 도와준다고 하였는데, 이것은 옵션키를 누른 채 특정 키워드를 선택하면 보여주는 정보창을 뜻한다.
| Quick Help 예시 |
|---|
![]() |
일반적으로 문서 주석에서 쓸 수 있는 키워드들은 아래와 같다.
| Safety Information |
|---|
| Precondition |
| Postcondition |
| Requires |
| Invariant |
| Complexity |
| Important |
| Warning |
| Metadata |
|---|
| Author |
| Authors |
| Copyright |
| Date |
| Since |
| Version |
| Notes |
|---|
| Attention |
| Bug |
| Experiment |
| Note |
| Remark |
| ToDo |
| Tip |
만약 나만의 키워드를 정의하고 싶다면
> Keyword: description을 사용하면 된다.
위에서 Discussion부분에 대해 설명했는데, 이 부분은 마크다운 문법을 적용할 수 있다.
즉, 코드는 물론이고 bold, italic 등 다양한 마크다운 문법을 사용하여 표현할 수 있는 것이다.


문서 주석을 활용하면서 백틱을 두번 쓰면 앱 내의 요소를 검색하여 참조할 수 있다. 메소드명이나 클래스명이 잘 기억나지 않아도 정확히 작성할 수 있다. 또 Documentation에서 바로가기가 연결되는 아주 유용한 기능이다.

문서 주석의 또다른 장점은 그 자체로 개발 문서가 된다는 것이다. Xcode의 Build Documentation 기능을 이용하면 마치 애플 공식문서처럼 개발 문서를 만들 수 있다.
Xcode > Product > Build Documentation를 클릭한다.


뭔가 멋있다...
또, 마크다운 문법에서 헤딩(#)을 사용하는 방법이 있는데, 헤딩을 사용해도 Quick Help에서는 보이지 않지만 Documentation에서는 헤딩이 적용된 모습을 확인할 수 있다.
Xcode는 문서화에 대해 다른 기능도 제공하는데, 문서 주석을 이용해서 빌드하는 것이 아니라 아예 새로운 페이지로 문서를 작성할 수도 있다.
Swift 파일을 만들 듯이
Xcode > File > New > File의 경로로 따라가 새로운 Documentation Catalog를 생성해준다.

그럼 아래와 같이 새로운 Documentation 폴더가 생성되고, 내부에 예제 md 파일이 생성된 모습을 볼 수 있다.

이 파일은 README 처럼 md 파일이기 때문에 당연히 마크다운 문법을 사용할 수 있고, 이 상태로 다시 빌드를 진행하면 여기서 만든 md 파일을 기준으로 Documentation이 다시 생성된다.

사진을 추가하고 싶다면 Resources 파일에 이미지를 삽입하고 md 파일에 아래처럼 코드를 입력하면 된다.
// [] - 이미지의 설명
// () - 이미지의 파일 이름과 확장자명

이렇게 문서 주석을 활용하면 다른 개발자가 봤을 때도 이해하기 쉽도록 만들 수 있고,
개별적으로 Documentation을 만들어 해당 앱에 대한 설명을 만들 수도 있다.
오늘은 새로 받은 강의를 모두 수강하고 남는 시간을 이용하여
과제와 문서 주석에 대해 공부를 진행해 보았다.
특히 문서 주석은 굉장히 재밌었는데, 아직 모르는 부분도 많아서 더 공부해보고 싶다고 생각했다.
기회가 되면 문서 주석을 어떻게 활용하면 좋을지 더 고민해 볼 생각이다.
문서 주석 저도 정리하려고 했던 내용인데 보기 편하고 깔끔하게 정리하셨네요 ,,, 편 -안 🌸