- ๊ฐ์ธ ํ๋ก์ ํธ
- ํ๋ก์ ํธ ๊ธฐ๊ฐ: 2021.11.08 ~ 2021.11.19
- ํค์๋
- ํ๋ก์ ํธ ์๊ฐ
- ํ๋ก์ ํธ ์ฃผ์๊ธฐ๋ฅ
- UML
- Trouble Shooting
- ์๋กญ๊ฒ ์๊ฒ๋ ๊ฒ
- ๊ธฐ์ ์ ๋์
Generic
Element
map
filter
split
compactMap
FloatingPoint
Numeric
protocol
extension
attribute
replacingOccurrences
split vs components
Delegation pattern
TDD
Unit Test
UIStackView
UIScrollView
NumberFormatter
Auto Layout
layoutIfNeeded()
setNeedsLayout()
Main Run Loop
Update Cycle
viewDidLoad
viewWillLayoutSubviews
IBInspectable
UML
Array
LinkedList
Queue
Stack
์์ดํฐ์ ๊ธฐ๋ณธ ์ฑ์ธ ๊ณ์ฐ๊ธฐ ์ฑ๊ณผ ํก์ฌํ ๊ธฐ๋ฅ์ ๊ฐ์ง ์ฑ์ด์์. ๐ค
์ฌํํ UI ๋ฐ ๊ฐ๋จํ ๊ธฐ๋ฅ์ ํตํด ๊ณ์ฐ์ ํ ์ ์์ด์! ๐ช๐ป
๐งฎ ๋ง์ , ๋บ์ , ๊ณฑ์ , ๋๋์ ์ ํ ์ ์์ต๋๋ค!
๐ ๋ชจ๋ ์ด๊ธฐํ, ๋ถ๋ถ ์ด๊ธฐํ, ํ ๊ธ ๋ฒํผ์ ํตํด ํ์ฌ ๊ณ์ฐ์ํ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ด์.
โ๐ป ๊ณ์ฐ์ด ๋๋๊ณ , ์ด์ด์ ๊ณ์ฐํ ์ ์์ด์
-
์ํฉ
- ์คํฌ๋กค ๋ทฐ์ ์ฝํ ์ธ ๋ทฐ ์์ ์ ์ค์ ํ๋ ๋ฉ์๋๋ฅผ ํ์ฉํด๋ณด์๋ค.
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.height + scrollView.contentInset.bottom) scrollView.setContentOffset(bottomOffset, animated: false)
- ๊ทธ๋ฌ๋ ์คํฌ๋กค ๋ฐ๊ฐ ์๊ธธ๋ ์ฝ๊ฐ ์์ง์ด๋ฉด์ ์คํฌ๋กค์ด ์๋๋... ์ด์ํด๋ณด์ด๋ ์ ๋๋ฉ์ด์ ์ ์ทจํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
- ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด๋ณด๊ธฐ ์ํด์ 1์ฐจ์ ์ผ๋ก ๊ตฌ๊ธ๋ง์ ํตํด ์ฐพ์๋ณด์๊ณ , ์ฐพ๋๋ฐ ์ด๋ ค์์ด ์์ด 3๊ธฐ ์บ ํผ ์ ๋ฐฐ๋ถ๋ค์๊ฒ๋ ์ง๋ฌธํด๋ณด์์ง๋ง ํด๊ฒฐ๋ฐฉ๋ฒ์ ์ฐพ์ง ๋ชปํ๋ค.
-
์ด์
- 3๊ธฐ ์บ ํผ
์๋ฐ
์ ๋์์ผ๋ก LLDB๋ฅผ ํ์ฉํ์ฌ ์ฒ์ y์ขํ๊ฐ ์ด๋ค ๊ฐ์ผ๋ก ์ฐํ๋์ง ํ์ธํด๋ณด์์ผ๋, StackView๊ฐ ์ถ๊ฐ๋๊ณ ๋ ํ ์ ๋ฐ์ดํธ ๋์ด y๊ฐ ์ขํ๊ฐ ๊ณ์ฐ์ด ๋์ด์ผ ํ๋๋ฐ, ๋ฒํผ์ ๋๋ฅด๊ธฐ ์ด์ ์ y์ขํ๊ฐ ์ฐํ๋ ๊ฒ์ด ํ์ธ๋์๋ค. - ํ์ด๋จธ๋ ๋น๋๊ธฐ์ ์ผ๋ก ํด๋น ๋ถ๋ถ์ ํด๊ฒฐํด๋ณด๋ ค๊ณ ํด๋ณด์์ผ๋ ๋ฐ๋ง ๋ด๊ถ๋ดค์ง ์ ๋๋ก ๋ฐฐ์๋ณด์ง ์์ ์ง์์ด๋ผ ํด๊ฒฐํ๋๋ฐ ๋ง์ ์ด๋ ค์์ด ์์๋ค.
- ์ดํ ์ํฌํฐ์ฆ
Wody
์๊ฒ ์ง๋ฌธํด๋ณด์๊ณ ์ผ๋ง ์ง๋์ง ์์ ํด๊ฒฐ์ ํ ์ ์๊ฒ ๋์๋ค.
- 3๊ธฐ ์บ ํผ
-
์ ์์ ์ผ๋ก ํ๋จ์ผ๋ก ์๋ ์คํฌ๋กค์ด ๋๋ ๋ชจ์ต
-
layoutIfNeeded()
๋ผ๋ ๋ฉ์๋๋ฅผ ํ์ฉํ์ฌ ํด๊ฒฐํ๊ฒ ๋์๋ค. ์ด ๋ฉ์๋๋setNeedsLayout()
๊ณผ ๊ฐ์ด ์๋์ผ๋ก layoutSubviews๋ฅผ ์์ฝํ๋ ํ์์ด์ง๋ง ํด๋น ์์ฝ์ ๋ฐ๋ก ์คํ์ํค๋ ๋๊ธฐ์ ์ผ๋ก ์๋ํ๋ ๋ฉ์๋๋ค. update cycle์ด ์ฌ ๋ ๊น์ง ๊ธฐ๋ค๋ ค layoutSubviews๋ฅผ ํธ์ถ์ํค๋ ๊ฒ์ด ์๋๋ผ ๊ทธ ์ฆ์ layoutSubviews๋ฅผ ๋ฐ๋์ํค๋ ๋ฉ์๋๋ค. -
๋ง์ผ main run loop์์ ํ๋์ View๊ฐ setNeedsLayout์ ํธ์ถํ๊ณ ๊ทธ ๋ค์ layoutIfNeeded๋ฅผ ํธ์ถํ๋ค๋ฉด layoutIfNeeded๋ ๊ทธ ์ฆ์ View์ ๊ฐ์ด ์ฌ๊ณ์ฐ๋๊ณ ํ๋ฉด์ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ setNeedsLayout์ด ์์ฝํ layoutSubviews ๋ฉ์๋๋ update cycle์์ ๋ฐ์ํด์ผํ ๋ณ๊ฒฝ๋ ๊ฐ์ด ์กด์ฌํ์ง ์๊ธฐ ๋๋ฌธ์ ํธ์ถ๋์ง ์๋๋ค.
-
์ด๋ฌํ ๋์ ์๋ฆฌ๋ก
layoutIfNeeded()
๋ ๊ทธ ์ฆ์ ๊ฐ์ด ๋ณ๊ฒฝ๋์ด์ผ ํ๋ ์ ๋๋ฉ์ด์ ์์ ๋ง์ด ์ฌ์ฉ๋๋ค๊ณ ํ๋ค. -
ํด๊ฒฐ
- ๋ฐ๋ผ์ ์คํฌ๋กค๋ทฐ์ ์์ ์ ๋ํ ์ฝํ
์ธ ๋ทฐ์ ์คํ์
์ค์ ์ ํด์ฃผ๊ธฐ ์ ์
layoutIfNeeded()
๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ layout์ ์ ๋ฐ์ดํธ ํ๊ณ setContentOffset์ ์ค์ ํด์ฃผ์๋๋ ํด๋น ๋ฌธ์ ์ ๋ํด์ ํด๊ฒฐ๋์๋ค.
- ๋ฐ๋ผ์ ์คํฌ๋กค๋ทฐ์ ์์ ์ ๋ํ ์ฝํ
์ธ ๋ทฐ์ ์คํ์
์ค์ ์ ํด์ฃผ๊ธฐ ์ ์
-
์ํฉ
์คํ๋ทฐ > ์คํ๋ทฐ > ๋ ์ด๋ธ ๊ณ์ธต์ ๊ฐ์ง ๋ถ๋ถ์์ ๋ ์ด๋ธ์ ํ ์คํธ๋ฅผ ๊บผ๋ด๋ ค๋ฉดarrangedSubviews
๋ฅผ์ด์ค for๋ฌธ
์ ๋๋ฉด์ ๊ฐ์ ธ์์ผ ํ๋ ์ํฉ์ด ๋ง์์ ์๋ค์๋ค.extension UIStackView { var toString: String { var inputValues = [String]() self.arrangedSubviews.forEach{ view in let subview = view as? UIStackView subview?.arrangedSubviews.forEach{ view in let label = view as? UILabel guard let input = label?.text else { return } inputValues.append(input.replacingOccurrences(of: ",", with: "")) } } return inputValues.joined(separator: " ") } }
-
ํด๊ฒฐ๋ฐฉํฅ
๋ฆฌ๋ทฐ์ด ์๋ฆผ์๊ฒ ์กฐ์ธ์ ๊ตฌํด์์คํ๋ทฐ > ์ปค์คํ ๋ทฐ
๊ณ์ธต์ ๊ฐ์ง ์ ์๋๋ก ์ปค์คํ ๋ทฐ ๋ง๋ค๊ธฐ์ ๋์ ํด๋ณด์๋ค. -
๊ฒฐ๊ณผ
extension UIStackView { var toString: String { var inputValues = [String]() self.arrangedSubviews.forEach { view in guard let formualStackView = view as? FormulaStackView else { return } inputValues.append(contentsOf: formualStackView.element) } return inputValues.joined(separator: " ") } }
-
FormulaStackView
๋ผ๋ ์ปค์คํ ๋ทฐ๋ฅผ ๋ง๋ค์ด ์ค์ผ๋ก์จ ์ด์ค for๋ฌธ์ ๋๋ ๋ฌธ์ ๋ ํด๊ฒฐ์ด ๋์๊ณ , ViewController์์ ์คํ๋ทฐ ๋ด๋ถ์Label์ ์ถ๊ฐ
ํด์ฃผ๋ ๋ถ๋ถ๋ ์ปค์คํ ๋ทฐ ๋ด๋ถ์์ ํด๊ฒฐํ ์ ์๊ฒ๋์๋ค.
์ํฉ
๊ณ์ฐ๋ด์ญ์ด ์์ฌ์ ์คํฌ๋กค๋ฐ๊ฐ ์๊ธฐ๋ ๋ฌธ์ ๋ก ์คํฌ๋กค์ ์งํํ ์ ๊ธ์จ๊ฐ ๊ฐ๋ ค์ง๋ ๋ฌธ์ ๊ฐ ์์๋ค.ํด๊ฒฐ๋ฐฉํฅ
์คํฌ๋กค๋ฐ๋ฅผ ๊ฐ๋ฆด ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋์ง ๊ตฌ๊ธ๋ง์ ํตํด์ ์ฐพ์๋ณด์๋ค.๊ฒฐ๊ณผ
- ์ฐพ์๋ณด๋ ์ธํฐํ์ด์ค ๋น๋์์๋ ์ค์ ์ ํด์ค ์๋ ์๊ณ ์ฝ๋๋ก๋ ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์๋ค.
์ํฉ
์๋ฆผ์๊ฒ ๋ฒํผ์ ๋ฅ๊ธ๊ฒ ๋ง๋ค์ด๋ณด๋ ๋์ ๊ณผ์ ๋ฅผ ๋ฐ๊ฒ๋์ด ํด๊ฒฐํด๋ณด๊ธฐ๋ก ํ์๋ค.
์๋-1
์ฒ์์๋ ๋ฒํผ ์์ฒด๊ฐ ์ฝ๋๊ฐ ์๋ ์คํ ๋ฆฌ๋ณด๋์์ ์์ฑ๋ ๋ฒํผ์ด๋ผ์ ์ธํฐํ์ด์ค ๋น๋๋ก ํด๊ฒฐํด๋ณด๊ณ ์ ํ์๋ค.
extension UIView {
@IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}
}
- ๊ทธ๋ฌ๋ ์ด ๋ฐฉ๋ฒ์ผ๋ก๋ ๋ฒํผ์ cornerRadius๋ฅผ ์ง์ ๋์ ํด์ฃผ๋ ๋ฐฉ์(ํ๋์ฝ๋ฉ)์ด๊ธฐ ๋๋ฌธ์ ๋๋ฐ์ด์ค๊ฐ ๋ค๋ฅผ ๊ฒฝ์ฐ ๋ด๊ฐ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ธฐ์๋ ํ๋ค๋ค๊ณ ํ๋จ๋์๋ค. ๊ทธ๋์ ์ฝ๋๋ก ํด๋ณผ ์ ์๋ ๋ฐฉ๋ฒ์ ์ฐพ์ ํด๊ฒฐํด๋ณด์๋ค.
์๋-2
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
calculatorButtons.forEach { button in
button.layer.cornerRadius = button.layer.frame.size.width / 2
}
}
- ๋ฒํผ์ ๋๋น / 2๋ฅผ ํด์ cornerRadius๋ฅผ ์ค์ ํด์ค ์ฝ๋๋ค. ์ด๋
viewWillLayoutSubviews
๋ฉ์๋๋ฅผ ์จ์ค๋ค.
์๋-3, ๊ทธ๋ฆฌ๊ณ ํด๊ฒฐ
-
๋ฒํผ์ IBOutlet์ didSet์ ์ค ์๋ ์์์ง๋ง ์๋์ ๊ฐ์ ๋ฌธ์ ๋๋ฌธ์ ํด๋น ๋ฐฉ๋ฒ์ ๋ถ๊ฐ๋ฅ ํ๋ค.
-
๋๋ฒ๊น ์ ํด๋ณด๋
viewWillLayoutSubviews
๋ฉ์๋๊ฐ ํธ์ถ๋๋ ์์ ์ ๋ ์ด์์์ด ๊ฐฑ์ ๋์ด ๋ฒํผ์ ๋๋น๊ฐ ๋ฐ๋๊ณ ์์๋ค. (๋๋ฐ์ด์ค๋ ์์ดํฐ SE ๊ธฐ์ค์ด๋ค. SE ์ด์ ๋๋ฐ์ด์ค์์๋ ์๋ ๋ฌธ์ ์๋ค.) IBOutlet์ didSet์viewDidLoad๊ฐ ํธ์ถ๋๊ธฐ ์
์ ํธ์ถ๋๋ฏ๋ก ์ ์ ํ์ง ๋ชปํ ๋ฐฉ๋ฒ์ด์๋ค. -
๋ฐ๋ผ์ ์ต์ํ์ผ๋ก ์ ๊ฒ ํธ์ถ๋๋
updateViewConstraints
๋ฉ์๋๋ฅผ ํ์ฉํ์ฌ ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์๋ค.func setupButtons() { calculatorButtons.forEach { button in button.layoutIfNeeded() button.layer.cornerRadius = button.layer.bounds.width / 2 } } override func updateViewConstraints() { super.updateViewConstraints() setupButtons() }
-
updateViewConstraints์ ๋ฒํผ์ ํ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ์๊ณ , for๋ฌธ ๋ด๋ถ์์ ๋ฒํผ๋ง๋ค
layoutIfNeeded
๋ฅผ ํธ์ถํ์ฌ ๋ ์ด์์์ ๊ฐฑ์ ํ๊ณ ์ดํ cornerRadius ๊ฐ์ ๋์ ํด์ฃผ๊ณ ์๋ค. -
๋ ์ด์์์ ๊ฐฑ์ ํ๋ ์ด์ ๋ ๊ฐฑ์ ํ์ง ์์ผ๋ฉด ์ ๋๋ฒ๊น ์ ๋ฐ๊ฒฌํ์๋ ์ต์ข ๋ ์ด์์์ด ์๋๋ผ ์์๋ก ์กํ์๋ frame๊ฐ์ผ๋ก ๊ณ์ฐ์ ํ๊ธฐ ๋๋ฌธ์ ์๋์ฒ๋ผ ์ฐ๊ทธ๋ฌ์ง ์์ด ๋์จ๋ค.
๊ฒฐ๋ก
- viewDidLoad์์ frame์ฌ์ด์ฆ๊ฐ ์ ํํ์ง ์์ ์ ์๋ค. ํด๋น ํจ์๋ ๋ทฐ๋ ๋ก๋๋๋ค๊ณ ํ์ธํ ์ ์์ง๋ง, ๋ฐฐ์น๊ฐ ๋๋ค๊ณ ํ ์๋ ์๋ค. ๋ฐ๋ผ์ ์์ ๊ฐ์ ํ์์ viewDidLoad์์ ์์๋ก ์กํ๋ frame๊ฐ์ด
viewWillLayoutSubviews
๊ฐ ํธ์ถํ๋ฉด์ ํ์ ๋ทฐ๊ฐ ๋ฐฐ์น๋๊ณ ์ดํ ๊ฐ์ด ๋ณํ๋ค๊ณ ๋ณผ ์ ์๊ฒ ๋ค. ๋ฐ๋ผ์ ํ์๋ทฐ๊ฐ ๋ฐฐ์น๊ฐ ๋๊ณ ๋์ ๋ฒํผ์ ๋ ์ด์์์ ์ก์์ค์ผ ํด๊ฒฐ์ด ๊ฐ๋ฅํ๋ ๊ฒ์ด๋ค.
์ฌ๊ธฐ์ ์๋ฌธ์ ์ด ๋๋ ๊ฒ์ ๋ค๋ฅธ ๋๋ฐ์ด์ค๋ค์ ์๊ด์๋๋ฐ ์ SE์์๋ง ๋ฒํผ์ ํฌ๊ธฐ๊ฐ ์ค์ด๋๋ ๊ฒ์ผ๊น?
- 3๊ธฐ ์บ ํผ
์๋ฐ
์ ๋์์ผ๋ก ํด๋น ์๋ฌธ์ ์ ํ ์ ์์๋ค.
- HIG์์ ์ฅ์น๋ค์ ์น์๋ฅผ ํ์ธํด์ ์ธ๋ก๋ฅผ ๋ณด๋ฉด 200~300์ ๋ ์ฐจ์ด๊ฐ ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ์ฌ์ง์์๋ ๋ณผ ์ ์๋ฏ์ด ์ธ๋ก ํฌ๊ธฐ๊ฐ ์์ฒญ ์ฐจ์ด๋๋ค. ๋ฐ๋ผ์ ์์์ง ๋๋ฐ์ด์ค์ ์คํ ๋ ์ด์์์ ์ถฉ์กฑํ๊ธฐ ์ํด ๋ฒํผ์ ํฌ๊ธฐ๋ฅผ ์ค์ผ ์ ๋ฐ์ ์๋ค๋ ์ถ์ธก์ด ๊ฐ๋ฅํด์ก๋ค.
- ์ด๋ฌํ ์ฌ์ค์ ์ฆ๋ช ํด๋ผ ์๋ ์๋ค. ์ง์ ๋ ์ด์์์ ๋ค ๊ณ์ฐํ์ฌ ์น์์ ๋ง๋์ง ํ์ธํ ์๋ ์์ง๋ง... ๋์ค์ ์๋ํด๋ด์ผ๊ฒ ๋ค. ๐
์ํฉ
์๋ฃ๊ตฌ์กฐ๋ฅผ ๊ณต๋ถํ๋ค๊ฐ ์ ๋ค๋ฆญ์ ์ฌ์ฉํ ์์ ์ฝ๋๋ค์ ์ดํด๋ณด๋<T>
๋ก ์์ฑ๋์ด์๋ ๊ฒฝ์ฐ๊ฐ ์๊ณ ,<Element>
๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ ๋์ ์ฐจ์ด๊ฐ ๊ถ๊ธํด์ก๋ค.
์ด์
๊ณต์๋ฌธ์ Generic ๋ถ๋ถ์์Naming Type Parameters
๋ถ๋ถ์ ์ดํด๋ณด๋ ์ด๋ฆ์ด ์๋ ๊ฒ๊ณผ ์ด๋ฆ์ด ์๋ Element๋ ์ฐจ์ด๊ฐ ์์ง๋ง ํ๋ผ๋ฏธํฐ์ ํ์ ์ฌ์ด์ ๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์์๋ ๋ช ํํจ์ ์ฃผ๊ธฐ ์ํด ์ฌ์ฉํ๋ค๊ณ ํ๋ค. ๊ทธ๋ฌ๋ ๊ด๊ณ๊ฐ ์๋ ์ํฉ์์๋T
,ยU
,V
๋ฅผ ์ฃผ๋ก ์ฌ์ฉํ๋ค๊ณ ํ๋ค.ํด๊ฒฐ
Array์ ๋ง์ฐฌ๊ฐ์ง๋ก Queue๋ LinkedList๋ ์์๋ค์ด ์๋ก ๊ด๊ณ๊ฐ ์๋ค๊ณ ์๊ฐํ์ฌ, ํ์ ๋ด๋ถ์ ์ ๋ค๋ฆญ ํ์<T>
์ Element๋ผ๊ณ ๋ช ์ํด์ฃผ์๋ค.
์ํฉ
๋ฆฌ๋ทฐ์ด ์๋ฆผ์๊ฒ removeAll๊ณผ ๋น๋ฐฐ์ด์ ํ ๋นํ๋ ๊ฒ์ด ์ด๋ค ์ฐจ์ด๊ฐ ์๋๊ณ ์ง๋ฌธ์ ๋ฐ์๋๋ฐ ์ด๋ค ์ฐจ์ด๊ฐ ์๋์ง ๋ชจ๋ฅด๊ฒ ๋ค.์ด์
Swift github๋ฅผ ํตํด removeAll ๋์ ๋ฐฉ์์ ํ๋ฒ ์ดํด๋ณด๊ฒ ๋์๋ค.
ํด๊ฒฐ
์ดํด๋ณด๋ ํ๋ผ๋ฏธํฐ ๊ธฐ๋ณธ๊ฐ์ ๋ฐ๋ก ture๋ก ์ค์ ํด์ฃผ์ง ์๋๋ค๋ฉด ๋น Array๋ฅผ ์ด๊ธฐํํด์ฃผ๋ ๋์์ ํ๊ณ ์์๋ค. ๋ฐ๋ผ์ ๋น ๋ฐฐ์ด๊ณผ removeAll๋ ํฐ์ฐจ์ด๊ฐ ์๋ ๊ฒ์ผ๋ก ๊ฒฐ๋ก ์ด ๋ฌ๋ค.
์ํฉ
STEP 1์ ์งํํ ๋ ๋น ํ๋กํ ์ฝ์ ๊ตฌํํด๋๋ผ๋ ๋ถ๋ถ์์ ์ ์ดํด๊ฐ ๊ฐ์ง ์์๋ค.์ด์
์๊ณ ๋ณด๋ CalculateItem์Queue์์ ๋ค๋ฃจ๋ ์์
๊ฐ ์ค์ํด์ผํ๋ ํ๋กํ ์ฝ์ด์๋ค.ํด๊ฒฐ
STEP 2๋ฅผ ์งํํ๊ฒ ๋๋ฉด์ ํด๋น ํ๋กํ ์ฝ์ ์ญํ ์ ์ ์ดํดํ ์ ์์๊ณ , ๋๋ถ์ ๋น ํ๋กํ ์ฝ์ ์ฉ๋์ ๋ํด์ ์๊ฒ๋์๋ค.
-
์ํฉ
์๋ฆผ์๊ฒ ์ง๋ฌธ์ ๋ฐ์๋๋ฐ ๋ด๊ฐ ์๊ณ ์๋ ์ฐจ์ด์ ์ ๋ฐํํ์ ๋ฟ์ด์๋ค. -
์ด์
๋ฐํํ์ ๋ง๊ณ ๋ ๋ค๋ฅธ ์ฐจ์ด์ ๋ ์์๋๊ฒ ์๊ฐ๋์ ์ ๋ฆฌํด๋ณด์๋ค. -
ํด๊ฒฐ
-
import ์ฌ๋ถ
- split์ swift ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ํด์๋ค.
- components๋ Foundation ํ๋ ์์ํฌ์ ์ํด์์ด importํ์ฌ ์ฌ์ฉํ ์ ์๋ค.
-
ํ๋ผ๋ฏธํฐ
- split(separator: Character, maxSplits: Int = Int.max, omittingEmptySubsequences: Bool = true)
- components(separatedBy separator: String)
-
๊ณต๋ฐฑ์ผ๋ก ์ฒ๋ฆฌํ ๋์ ๋ค๋ฅธ ๊ฒฐ๊ณผ
let str = "My name is Sudhir " // trailing space str.split(separator: " ") // ["My", "name", "is", "Sudhir"] str.components(separatedBy: " ") // ["My", "name", "is", "Sudhir", ""] โ Additional empty string
๋๋ค ๋์ผํ ๊ฒฐ๊ณผ๊ฐ ๋์ค๊ฒ ํ๋ ค๋ฉด split์ ํ๋ผ๋ฏธํฐย
omittingEmptySubsequences
๋ฅผ false๋ก ์ต์ ์ ๋ฐ๋ก ์ค์ผ ๊ฐ๋ฅํ๋ค.str.split(separator: " ", omittingEmptySubsequences: false) // ["My", "name", "is", "Sudhir", ""]
-
๋ฐํํ์ ์ ์ฐจ์ด
- split -> [Substring]
- components -> [String]
-
์ฑ๋ฅ ์ฐจ์ด
๋ฐํํ์ ์์ ๋ณผ ์ ์๋ฏยsplit
์ ์๋ณธ ๋ฌธ์์ด์ ์ฐธ์กฐ(SubString)ํ๊ณ ์๊ธฐ ๋๋ฌธ์, ์ ๋ฌธ์์ด์ ํ ๋นํ์ง ์๋๋ค.๋ฐ๋ผ์ split์ด components๋ณด๋ค ์ฑ๋ฅ์ธก๋ฉด์์ ๋น ๋ฅด๋ค๊ณ ๋ณผ ์ ์๋ค.Substring์ด๋?์๋ณธ ๋ฌธ์์ด์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ๋ค.๊ฐ์ ์ฝ๊ธฐ๋ง ํ ๋๋ ์๋ณธ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ๊ณ , ๊ฐ์ ๋ณ๊ฒฝํ๋ ์์ ์๋ง ์๋ก์ด ๋ฉ๋ชจ๋ฆฌ๊ฐ ์์ฑ๋๋ค.
Substring์ ์ฃผ๋ก ๋ฌธ์์ด์ ์ฒ๋ฆฌํ ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ๊ธฐ ์ํด์ ์ฐ์ด๋ ํ์ ์ผ๋ก ์๊ณ ์๋ค!
- ๋ทฐ์ ๋ฐ์ด๋๊ฐ ์ต์ข ์ ์ผ๋ก ๊ฒฐ์ ๋๋ ์ต์ด ์์
- ์ ์ฝ์ด๋ ์คํ ๋ ์ด์์์ ์ฌ์ฉํ์ง ์์๋ค๋ฉด, ์๋ธ๋ทฐ์ ๋ ์ด์์์ ์ ๋ฐ์ดํธํ๊ธฐ ์ ํฉํ ์์ ์ด๋ค.
- ์ฌ๋ฌ๋ฒ ์ค๋ณต์ผ๋ก ํธ์ถ๋ ์ ์๋ค.
- ex) ๋ฉ์ธ๋ทฐ์ ์๋ธ๋ทฐ๊ฐ ๋ก๋๋๋ ๊ฒฝ์ฐ
- ๋ฉ์๋๋ฅผ ์์๋ณด๊ณ ์๋ฆผ์ ํผ๋๋ฐฑ์ ๋ฐ๊ณ ๋ค์ ๋๋ฒ๊น
์ ํด๋ณด๋
๋ฒํผ์ด ํด๋ฆญ์ด ๋๋ ์์
๋ง๋ค ํด๋น ๋ฉ์๋๊ฐ ํธ์ถ์ด ๋๊ณ ์์๋ค. cornerRadius๋ฅผ ์ก์์ฃผ๋ for๋ฌธ์ด ๋ฒํผ์ด ๋๋ฅผ๋๋ง๋ค ์คํ๋๊ณ ์์๋ ๊ฒ์ด๋ค. ์ฆ SubView์ ๋ ์ด์์์ ์ก์์ฃผ๊ธฐ์๋ ์ ์ ์น ๋ชปํ ๋ฉ์๋์๋ค.
- MVC ๊ตฌ์กฐ๋ก ์ธํด ๋ฑ๋ฑํด์ง ViewController๋ฅผ ๋ค์ด์ดํธ ์์ผ์ฃผ๊ธฐ ์ํด Delegate ํจํด์ ์ฌ์ฉํ๊ฒ ๋์์ต๋๋ค.
- ๋น์ฆ๋์ค ๋ก์ง ๋ถ๋ถ์ ๋ณ๋์ ํ์ ์ผ๋ก ๋ง๋ค์ด ์ฑ ์์ ๋๋์ด์ฃผ์ด ViewController์ ์ฝ๋ ๊ฐ๋ ์ฑ์ด ๋์์ง๊ณ , ์ญํ ๋ํ ๋ช ํํ ๋๋์ด์ก์ต๋๋ค.
[ํ์ต ๊ธฐ๋ก ํ์ ]
- STEP 1 : Queue ํ์ ๊ตฌํ
- STEP 2 : ๊ณ์ฐ ํ์ ๋ฐ ์ฃผ๋ณ ํ์ ๊ตฌํ
- STEP 3 : ๊ณ์ฐ๊ธฐ UI ์ฐ๋
- ์๋ฃ๊ตฌ์กฐ Queue ํ์ ์ ๊ตฌํํฉ๋๋ค.
- Queue๋ฅผ DoubleStack๊ณผ LinkedList๋ฅผ ์ด์ฉํ์ฌ ๋๊ฐ์ง๋ฅผ ๊ตฌํํด๋ณด์๋ค. ๋ฐฐ์ด๋ก๋ ๊ตฌํํ ์ ์์ง๋ง enqueue ์์ ์ด ์๊ฐ๋ณต์ก๋๊ฐ O(1)์ด ๊ฑธ๋ ค์ ๋นํจ์จ์ ์ด๋ค.
- Genericํ์ ์ ์ฌ์ฉํ ๋ Element๋ก ๋ช ์ํด์ฃผ์๋ค. ์ด์ ๋ T๋ก ๋ช ์ํด์ค ์๋ ์์ง๋ง ์ด๋ค ํ์ ์ด ๋ค์ด๊ฐ์ง ๋ช ํํ์ง ์๊ธฐ ๋๋ฌธ์ ์ข๋ ์ง๊ด์ ์ผ๋ก ๋ณด์ผ ์ ์๋๋ก ์์๋ผ๋ ๋ป์ ๋ด์ Element๋ฅผ ๋ช ์ํ๋ค.
- Queue๋ฅผ ๋ฐฐ์ด๋ก ๊ตฌํํด๋ ๊ด์ฐฎ์๊น?
- Array์ ์ ๋ค๋ฆญ ํ์ ์ ์ด์งธ์ Element์ผ๊น?
- removeAll๊ณผ ๋น ๋ฐฐ์ด์ ํ ๋นํ๋ ๊ฒ๊ณผ ์ฐจ์ด์ ์ด ๋ญ๊น?
์ํฉ
์๋ฃ๊ตฌ์กฐ๋ฅผ ๊ณต๋ถํ๋ค๊ฐ ์ ๋ค๋ฆญ์ ์ฌ์ฉํ ์์ ์ฝ๋๋ค์ ์ดํด๋ณด๋<T>
๋ก ์์ฑ๋์ด์๋ ๊ฒฝ์ฐ๊ฐ ์๊ณ ,<Element>
๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ ๋์ ์ฐจ์ด๊ฐ ๊ถ๊ธํด์ก๋ค.
์ด์
๊ณต์๋ฌธ์ Generic ๋ถ๋ถ์์Naming Type Parameters
๋ถ๋ถ์ ์ดํด๋ณด๋ ์ด๋ฆ์ด ์๋ ๊ฒ๊ณผ ์ด๋ฆ์ด ์๋ Element๋ ์ฐจ์ด๊ฐ ์์ง๋ง ํ๋ผ๋ฏธํฐ์ ํ์ ์ฌ์ด์ ๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์์๋ ๋ช ํํจ์ ์ฃผ๊ธฐ ์ํด ์ฌ์ฉํ๋ค๊ณ ํ๋ค. ๊ทธ๋ฌ๋ ๊ด๊ณ๊ฐ ์๋ ์ํฉ์์๋T
,ยU
,V
๋ฅผ ์ฃผ๋ก ์ฌ์ฉํ๋ค๊ณ ํ๋ค.ํด๊ฒฐ
Array์ ๋ง์ฐฌ๊ฐ์ง๋ก Queue๋ LinkedList๋ ์์๋ค์ด ์๋ก ๊ด๊ณ๊ฐ ์๋ค๊ณ ์๊ฐํ์ฌ, ํ์ ๋ด๋ถ์ ์ ๋ค๋ฆญ ํ์<T>
์ Element๋ผ๊ณ ๋ช ์ํด์ฃผ์๋ค.
์ํฉ
์๋ฆผ์๊ฒ removeAll๊ณผ ๋น๋ฐฐ์ด์ ํ ๋นํ๋ ๊ฒ์ด ์ด๋ค ์ฐจ์ด๊ฐ ์๋๊ณ ์ง๋ฌธ์ ๋ฐ์๋๋ฐ ์ด๋ค ์ฐจ์ด๊ฐ ์๋์ง ๋ชจ๋ฅด๊ฒ ๋ค.์ด์
Swift github๋ฅผ ํตํด removeAll ๋์ ๋ฐฉ์์ ํ๋ฒ ์ดํด๋ณด๊ฒ ๋์๋ค.
ํด๊ฒฐ
์ดํด๋ณด๋ ํ๋ผ๋ฏธํฐ ๊ธฐ๋ณธ๊ฐ์ ๋ฐ๋ก ture๋ก ์ค์ ํด์ฃผ์ง ์๋๋ค๋ฉด ๋น Array๋ฅผ ์ด๊ธฐํํด์ฃผ๋ ๋์์ ํ๊ณ ์์๋ค. ๋ฐ๋ผ์ ๋น ๋ฐฐ์ด๊ณผ removeAll๋ ํฐ์ฐจ์ด๊ฐ ์๋ ๊ฒ์ผ๋ก ๊ฒฐ๋ก ์ด ๋ฌ๋ค.
- Element์ ์ฉ๋
- ์๋ฃ๊ตฌ์กฐ (
Array
,LinkedList
,Queue
,Stack
) - ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ๋์ Big-O
- removeAll๊ณผ ๋น ๋ฐฐ์ด์ ํ ๋นํ๋ ๊ฒ์ ํฐ ์ฐจ์ด๊ฐ ์๋ค.
- ๋ถํ์ํ import ์ ๊ฑฐ
- ์ถ๊ฐ์ ์ผ๋ก attribute์ ๋ํด์ ๊ณต๋ถํด๋ณด๊ธฐ.
- ์งง์ return๋ฌธ์ด๋ผ๋ ์ค๋ฐ๊ฟ ํด์ฃผ๋ ๊ฒ์ด ๋๋ฒ๊น ์ ์ ์ฉํ๋ค.
- ๋ฉ์๋ ํ์ถํ๋ ๋ถ๋ถ์ ๋ณดํต if๋ณด๋ค๋ guard๋ฅผ ์ฃผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ์ ์ ํ ๊ฒ ๊ฐ๋ค.
- ๊ณ์ฐ ํ์ ์ ๊ตฌํํฉ๋๋ค.
์ด๋ฒ ์คํ ์งํ์ ์ํด ์ ์ ๊ณ ๋ฏผ์ ๋๋ ์ฃผ์ จ๋ ์บ ํผ๋ถ๋ค์๊ฒ ๊ฐ์ฌ์ ์ธ์ฌ๋ฅผ ๋๋ฆฝ๋๋ค.
- ์ฃผ์ด์ง UML์ ๋ณด๋ฉฐ ํ์ ์ด ์ด๋ค ์ญํ ์ ํ๋์ง ์ ์ถํ๋ฉด์ ์ ๋ฆฌํด๋ณด์๋ค.
- ์ฌ์ฉ์์ ์
๋ ฅ๊ฐ์ ๊ฒ์ฌํด์ ์ฐ์ฐ์์ ํผ์ฐ์ฐ์๋ฅผ ๋ด๋ Formula๋ฅผ ๋ง๋๋ ํ์
componentsByOperators
- input์ ๋ฐ์์ ์ซ์๋ง ๋ฝ์์ค๋ ๋ฉ์๋
parse
- ์ฌ์ฉ์ ์ ๋ ฅ์ ๋ฐ์์ Formula๋ฅผ ๋ฐํํ๋ ๋ฉ์๋
split(with:)
- target์ ๊ธฐ์ค์ผ๋ก ๋ฌธ์์ด์ ์๋ผ ๋ฐฐ์ด๋ก ๋ฐํํ๋ ๋ฉ์๋ ์์) "12 + 3.1" โ ["12", "+", "3.1"]
- ์ฐ์ฐ์ํ์ ํผ์ฐ์ฐ์ํ๋ฅผ ๋ด๊ณ , ๊ฒฐ๊ณผ(
result()
)๋ฅผ ๋ด๋ ํ์
- ์ฐ์ฐ์์ ๊ณ์ฐ ๋ฉ์๋๊ฐ ์๋ ํ์
- ์ฒซ๋ฒ์งธ๋ split์ ํ์ฅํ๋ค๋ ์๋ฏธ ์์ฒด๊ฐ
๊ธฐ์กด split๊ณผ์ ๊ธฐ๋ฅ์ด ๋ค๋ฅด๋ค๊ณ ์๊ฐ
์ด ๋ค์๋ค. ๊ทธ๋์target๊ณผ ํจ๊ป ์๋ฅด๋ ๊ฒ
์ธ๊ฐ? ๋ผ๋ ์๊ฐ์ด ๋ค์๋ค. ์ฐ์ฐ์์ Double ํ์ ์ผ๋ก ๋ณํํ ์ ์๋ ์ซ์๊ฐ ํจ๊ป ๋ฐฐ์ด๋ก ๋ฐํ๋์ด Formula๋ฅผ ๋ฐํํด์ฃผ๋ ๋ก์ง์ ์๊ฐํด๋ณด์๋ค. - ์์์ ์๊ฐํ ๋ก์ง์ผ๋ก ๋จผ์ ๋์๊ฐ๊ฒ๋ ๊ตฌํ์ ํด๋ณด์๋๋ target์ ์์ฐ๊ฒ ๋์๋ค. ๋จผ์ ๊ณ ๋ คํ๋ ๊ฒ์ ์ซ์, ์ฐ์ฐ์๊ฐ ์ฌ๋ฌ๊ฐ๊ฐ ๋ค์ด์จ๋ค๋ ๊ฐ์ ํ์ ๊ตฌํํ๊ธฐ ๋๋ฌธ์ด๋ค. target์ด ์์ฐ์ด๋ ๊ฒ์ด ๋๋ฌด ์ฐ์ฐํ์ฌ ์ฌ๋ฌ ์บ ํผ๋ถ๋ค๊ณผ ๊ฐ์ด ๊ณ ๋ฏผ์ ๋๋์ด๋ณด์๋ค.
- ๋ง์ ๊ณ ๋ฏผ๋ค ๋์ ๋ฒํผ์ ๋๋ฅผ ๋ ์ซ์์ ์ฐ์ฐ์๋ฅผ ๊ตฌ๋ถํ ์ ์๋
ํน์ ๋ฌธ์์ด์ ์์๋ก ๋ฃ์ด ๋ฌธ์์ด์ ๋ง๋ค ์ ์๊ฒ ๋ค๋ ์๊ฐ
์ ๊ณต์ ๋ฐ์๋ค. (chacha ๊ณ ๋ง์ต๋๋ค...๐ญ) ๊ทธ๋์ ์ฐ์ฐ์๋ฅผ ๋๋ฅผ ๋ ๋ง๋ค์ ๋ค๋ก ๊ณต๋ฐฑ์ด ์ถ๊ฐ๋๋ ๋ก์ง
์ด ๋ ์ฌ๋ผ์ ๊ทธ๋๋ก ์ฎ๊ฒจ์ ์์ฑํด๋ณด์๋ค. - ๊ทธ๋ฌ๋ Operator ํ์
์ด
Character
์ธ ๋ถ๋ถ๊ณผCaseIterable ํ๋กํ ์ฝ
์ ์ฑํํ ๊ฒ์ ๋ณด์์ ๋ ์ด๊ฒ์ split์ ํ ๋ ์ฌ์ฉํ์ง ์์๊น? ๋ผ๋ ์๋ฌธ์ด ๋ ์๊ฒผ๋ค. ์ฌ์ค ๊ณต๋ฐฑ์ ์ถ๊ฐํด์ ์๋ผ์ค ์๋ ์๊ฒ ์ง๋งํ๋์ฝ๋ฉ
์ด๋ผ๋ ์๊ฐ์ด ๋จผ์ ๋ค์๋ค. ์ดํ Operator์ rawValue๋ฅผ ์ด์ฉํ์ฌ split์ ๊ตฌํํด๋ณผ๊น ๊ณ ๋ฏผํด๋ณด์์ง๋ง.. ์ผ๋จ target์ ํ์ ์ด ๋ฐฐ์ด์ด ์๋ ๋ถ๋ถ๊ณผ allcases๋ฅผ ์ฌ์ฉํด์ rawValue๋ฅผ ๋ฝ์์ฌ ์ ์๋ ์ ๋๋ฌธ์ ํด๋น ์๋ฌธ์ ์ ํด๊ฒฐํ์ง ๋ชปํ์๋ค.
- ์๋๋ dequeue๋ฅผ ํ ๋ nil์ด ๋ฐํ ๋๊ฒ๋ ๊ตฌํ์ ํ์์๋๋ฐ, ์ผ์ผํ ์ต์
๋ ๋ฐ์ธ๋ฉ ์ฒ๋ฆฌ ํด์ฃผ๋ฉด ์ง์ ๋ถํด์ง๊ฒ ๋ค๋ ์๊ฐ์ด ๋ค์ด์ ํด๋น ๋ก์ง์ ์๋ฌ๋ฅผ ๋์ง๋ ๋ก์ง์ผ๋ก ๋ฐ๊พธ์ด์ฃผ์๋ค. ์ดํ์๋ ๊ณ์ ์ฝ๋๊ฐ ๋๋ฝ๋ค๊ณ ๋๊ปด์ ธ์ ๋ค์ ๊ณ ๋ฏผํด๋ณด๋ค๊ฐ...
nil์ด ๋ฐํํ๊ฒ๋ ์ฌ์์
์ ํด์ฃผ๊ณresult
๋ถ๋ถ์ ์๋ก ์์ฑํด๋ณด์๋ค.
- ์ฒ์์๋ compactMap์ ๋ก์ง์ ์ฐธ๊ณ ํ์ฌ
filter
์map
์ ์ด์ฉํ์ฌ nil ์ฒดํฌ๋ฅผ ํ์ฌ ๋ณํํด์ฃผ์์๋๋ฐ, ๊ทธ๋ด ํ์ ์์ดcompactMap
์ ์ฌ์ฉํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค? ๋ผ๋ ์๊ฐ์ด ๋ค์ด์ ์์ ํด์ฃผ์๋ค.
- STEP 1์์ ๊ตฌํํด์ค ๋์๋ ์ด๋์ ๋ผ์ด์ ๋ฅผ ๊ตฌํํด์ฃผ์ง ์์์๋๋ฐ, STEP 2๋ฅผ ๊ตฌํํ๋ค๋ณด๋ ์ด๋์ ๋ผ์ด์ ๋ฅผ ํตํ ์ด๊ธฐํ๋ฅผ ํด์ฃผ์ด์ผ ํ๋ ์๊ฐ์ด ์ค๊ฒ๋์ด ์ด๋์ ๋ผ์ด์ ๋ฅผ ๋ชจ๋ ๊ตฌํํด์ฃผ์๋ค.
- split(with:) ๋ฉ์๋์ ์ญํ ์ด ์ ํํ ๋ญ๊น?
- dequeue์ ์ต์ ๋๋ฐ์ธ๋ฉ vs ์๋ฌํธ๋ค๋ง
- NaN์ ์ด๋ค ์์ ์ ๋ฐ์ํ๋ ๊ฑธ๊น?
componentsByOperators
๋ฉ์๋๋ช ์ด ๋์ฌ๊ฐ ์๋ ๊ฒ ๊ฐ๋ค. ์ ์ ํ ๊ฑธ๊น?
์ํฉ
STEP 1์ ์งํํ ๋ ๋น ํ๋กํ ์ฝ์ ๊ตฌํํด๋๋ผ๋ ๋ถ๋ถ์์ ์ ์ดํด๊ฐ ๊ฐ์ง ์์๋ค.์ด์
์๊ณ ๋ณด๋ CalculateItem์Queue์์ ๋ค๋ฃจ๋ ์์
๊ฐ ์ค์ํด์ผํ๋ ํ๋กํ ์ฝ์ด์๋ค.ํด๊ฒฐ
STEP 2๋ฅผ ์งํํ๊ฒ ๋๋ฉด์ ํด๋น ํ๋กํ ์ฝ์ ์ญํ ์ ์ ์ดํดํ ์ ์์๊ณ , ๋๋ถ์ ๋น ํ๋กํ ์ฝ์ ์ฉ๋์ ๋ํด์ ์๊ฒ๋์๋ค.
์ํฉ
STEP 2์์ ์ฃผ์ด์ก๋ UML์ ๋ํ ์๋ฌธ์ด ์๊ฒผ๋ค. ์ ๋ด๋ถ์ ์ผ๋ก ์ฐ๊ฒฐ๋์ด์๋ ํ์ ๋ผ๋ฆฌ๋ ํ์ดํ ํ์๊ฐ ์์๊น?์ด์
์ด๋ฌํ ๊ถ๊ธ์ ์ ์ค๋๋๋ฌด์๊ฒ ์ง์ ์ง๋ฌธํด๋ณด์๋ค.ํด๊ฒฐ
ํด๋์ค ๋ค์ด์ด๊ทธ๋จ์ ํ๋ฉด์ ์ผ๋ก ๋๋ฌ๋ ๊ด๊ณ๋ง ๋ํ๋ด๊ธฐ ๋๋ฌธ์ ๋ด๋ถ ๊ตฌํ์ ๋ํด์๋ ํ์ดํ๊ฐ ์์ ์๋ ์๋ค.
์ํฉ
๋ฆฌ๋ทฐ์ด ์๋ฆผ์๊ฒ ๋ฐ์ ํผ๋๋ฐฑ์ ๊ณ ๋ฏผํด๋ณด๋ค๊ฐ ๋ฉ์๋๋ช ์ด ์ด์ํ๋ค๋ ์๋ฌธ์ ์ด ์๊ฒจ UML์ ์์ฑํ๋ ์ค๋๋๋ฌด์๊ฒ ์ง๋ฌธํด๋ณด์๋ค.์ด์
์บ ํผ๋ค๊ณผ ์ด์ผ๊ธฐ๋ฅผ ๋๋์ด๋ดค๋๋ฐ, ๋ฉ์๋๋ช ์ ๋์ฌ๊ฐ ํฌํจ๋์ด์์ง ์์๋ค. ์ ์ถํ ๊ธฐ๋ฅ์ผ๋ก๋ split๊ณผ ๊ฐ์ ๋์์ ํ๋ ๋ฉ์๋ ๊ฐ์๋ฐ, Int.random ๊ฐ์ ๋งฅ๋ฝ์ผ๋ก get์ ์๋ตํ ๊ฒฝ์ฐ์ธ๊ฑธ๊น?ํด๊ฒฐ
ํด๋น ๋ถ๋ถ์ ์ค๋๋๋ฌด์๊ฒ ์ง์ ๋ฌผ์ด๋ณด์๊ณ , ์ ๋ด์ฉ๊ณผ ๊ฐ์ ๋งฅ๋ฝ์ผ๋ก ๋์ฌ๊ฐ ์๋ ๋ค์ด๋ฐ์ ํ ๊ฒ์ด ๋ง๋ค๊ณ ๋ต๋ณ๋ฐ์๋ค. Swift๋ ์ฌ์ด๋ ์ดํํธ ์์ด ๊ฐ์ ๋ฆฌํดํ๋ ๋ฉ์๋์ get์ ๋ถ์ด๋ ๊ฒ์ ์ง์ํ๋ ํธ์ด๋ค. ๋ํ์ ์ผ๋ก ์ฝ์ฝ์ํฐ์น ํ๋ ์์ํฌ์์ get, fetch, request๋ก ์์ํ๋ ๋ฉ์๋๋ ์ ๋ถ completion handler๋ฅผ ๋ฐ๋ ๋น๋๊ธฐ ์์ ๋ฟ์ด๋ค.
-
์ํฉ
์๋ฆผ์๊ฒ ์ง๋ฌธ์ ๋ฐ์๋๋ฐ ๋ด๊ฐ ์๊ณ ์๋ ์ฐจ์ด์ ์ ๋ฐํํ์ ๋ฟ์ด์๋ค. -
์ด์
๋ฐํํ์ ๋ง๊ณ ๋ ๋ค๋ฅธ ์ฐจ์ด์ ๋ ์์๋๊ฒ ์๊ฐ๋์ ์ ๋ฆฌํด๋ณด์๋ค. -
ํด๊ฒฐ
- split์ swift ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ํด์๋ค.
- components๋ Foundation ํ๋ ์์ํฌ์ ์ํด์์ด importํ์ฌ ์ฌ์ฉํ ์ ์๋ค.
- split(separator: Character, maxSplits: Int = Int.max, omittingEmptySubsequences: Bool = true)
- components(separatedBy separator: String)
let str = "My name is Sudhir " // trailing space str.split(separator: " ") // ["My", "name", "is", "Sudhir"] str.components(separatedBy: " ") // ["My", "name", "is", "Sudhir", ""] โ Additional empty string
๋๋ค ๋์ผํ ๊ฒฐ๊ณผ๊ฐ ๋์ค๊ฒ ํ๋ ค๋ฉด split์ ํ๋ผ๋ฏธํฐย
omittingEmptySubsequences
๋ฅผ false๋ก ์ต์ ์ ๋ฐ๋ก ์ค์ผ ๊ฐ๋ฅํ๋ค.str.split(separator: " ", omittingEmptySubsequences: false) // ["My", "name", "is", "Sudhir", ""]
- split -> [Substring]
- components -> [String]
๋ฐํํ์ ์์ ๋ณผ ์ ์๋ฏย
split
์ ์๋ณธ ๋ฌธ์์ด์ ์ฐธ์กฐ(SubString)ํ๊ณ ์๊ธฐ ๋๋ฌธ์, ์ ๋ฌธ์์ด์ ํ ๋นํ์ง ์๋๋ค.๋ฐ๋ผ์ split์ด components๋ณด๋ค ์ฑ๋ฅ์ธก๋ฉด์์ ๋น ๋ฅด๋ค๊ณ ๋ณผ ์ ์๋ค.Substring์ด๋?์๋ณธ ๋ฌธ์์ด์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ๋ค.๊ฐ์ ์ฝ๊ธฐ๋ง ํ ๋๋ ์๋ณธ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ๊ณ , ๊ฐ์ ๋ณ๊ฒฝํ๋ ์์ ์๋ง ์๋ก์ด ๋ฉ๋ชจ๋ฆฌ๊ฐ ์์ฑ๋๋ค.
Substring์ ์ฃผ๋ก ๋ฌธ์์ด์ ์ฒ๋ฆฌํ ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ๊ธฐ ์ํด์ ์ฐ์ด๋ ํ์ ์ผ๋ก ์๊ณ ์๋ค!
- ๋น ํ๋กํ ์ฝ์ ํ์ฉํ๋ ๋ฐฉ๋ฒ
- ๊ณ ์ฐจํจ์์ ๋์ ๋ฐฉ์
- UML ํด๋์ค ๋ค์ด์ด๊ทธ๋จ
- NaN
- ๋ฉ์๋๋ช ์ get ์ฌ์ฉ์ ์ฌ๋ฐ๋ฅธ ์ํฉ์ ํ๋ ๋ฐฉ๋ฒ
- split๊ณผ components์ ์ฐจ์ด์
- ๋์ณค๋ ๋ชจํธํ ๋ถ๋ถ์ ์๋ฌ๋ฅผ ๋์ง๋๋ก ๊ฐ์ ํ์๋ค.
- split๊ณผ components์ ์ฐจ์ด์ ์ ์ ์ ์์๋ค.
- ๋ฉ์๋๋ช ์ get์ ์ธ์ ์ฌ์ฉํ ์ ์๋์ง ์๊ฒ ๋์๋ค.
- ์์ ๊ตฌํํ Model์ UI์ ์ฐ๋ํฉ๋๋ค.
- ์คํฌ๋กค ๋ทฐ์ ์ฝํ
์ธ ์คํ์
์ค์ ์ ๋ ์ด์์์ ๋ฐ๋ก ์
๋ฐ์ดํธ ํ ์ ์๋๋ก ํ์๋ค. ์ด์ ๋ ๋ ์ด์์ ์
๋ฐ์ดํธ๊ฐ ์์ฝ์ด ๋์ด์๋ ์ํ์์ y๊ฐ ์ขํ๋ฅผ ๊ณ์ฐํ์ฌ ์คํ์
์ค์ ์ ํ๊ฒ๋๋ค๋ฉด ์
๋ฐ์ดํธ ์ด์ ์ ๋ ์ด์์์ผ๋ก y๊ฐ์ผ๋ก ๊ณ์ฐํ๊ธฐ ๋๋ฌธ์
layoutIfNeeded()
๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๋ ์ด์์ ์ ๋ฐ์ดํธ๊ฐ ํ์ํ์๋ค. - ๊ณ์ฐ์์ ์คํ๋ทฐ์ ์ถ๊ฐํ ๋ ์์ฑ๊ฐ์ ์ด๋ป๊ฒ ์ค์ ํด์ค์ผํ๋์ง ๊ณ ๋ฏผํด๋ณด์๋ค. ๊ธฐ์กด ์คํ ๋ฆฌ๋ณด๋์ ์ค์ ๋์ด์๋ ์คํ๋ทฐ์ ์์ฑ๊ฐ๊ณผ ๋์ผํ๋๋ก ๊ตฌํํด๋ณด์๋ค.
- ํ๋ก์ ํธ ์๊ตฌ์ฌํญ ์ธ ์ถ๊ฐ ์ค๊ณํ ๋ถ๋ถ
- ๊ณ์ฐ์ด ๋๋๊ณ ๋ ํ์ ์ํฉ
- ์คํ๋ทฐ์ ์๋กญ๊ฒ ์ ๋ฐ์ดํธํ์ฌ ์ด์ด์ ๊ณ์ฐํ ์ ์๋๋ก ์ถ๊ฐ ์ค๊ณ
- NaN์ด ๋ฐ์ํ๊ณ ๋ ํ์ ์ํฉ
- AC, CE ๋ฒํผ์ ๋๋ฅธ ํ ๊ณ์ฐ์ ํ ์ ์๋๋ก ์ค๊ณ
- ์ฒซ๋ฒ์งธ ๊ณ์ฐ์์ด ์ฌ๋ผ๊ฐ ๋์ ์ํฉ
- ํผ์ฐ์ฐ์๋ง ์ฌ๋ผ๊ฐ ์ ์๋๋ก ์ค๊ณ
- ๊ณ์ฐ์ด ๋๋๊ณ ๋ ํ์ ์ํฉ
- ๊ณ์ฐ์ด ๋๋๊ณ ๋์ ์ถ๊ฐ์ ์ผ๋ก ๋ฐ์ํ ์ ์๋ ์์ธ ํธ๋ค๋ง
- '=' ์ฐ์ฐ์๋ฅผ ํด๋ฆญ ์
์ฐ์ฐ์๋ฒํผ
ํน์AC, CE ๋ฒํผ
์ ์ ์ธํ๊ณ ๋๋จธ์ง ๋ฒํผ๋ค์ ๋์ํ์ง ์๋๋ก ๊ตฌ์ฑ - NumberFormatter๋ก ์ธํด ์ผํ๊ฐ ์ถ๊ฐ๋์ด์๋ ๋ฌธ์์ด์
replacingOccurrences
๋ฅผ ์ด์ฉํ์ฌ ์ ๊ฑฐํ๋ ๋ฉ์๋๋ฅผ ๊ตฌํ - ๊ณ์ฐ์ด ๋์๋์ง ์๋์๋์ง ์ํ๋ฅผ ๋ํ๋ด๋ ํ๋กํผํฐ(
hasCalculated
)๋ฅผ ์ถ๊ฐํ์ฌ ๋ค์ํ๊ฒ ํ์ฉ.
- '=' ์ฐ์ฐ์๋ฅผ ํด๋ฆญ ์
- ์ฝ๋ ๋ด๋ถ ๊ฐ๋
์ฑ์ ์ํด ๊ณ ๋ฏผํ๋ ๊ฒ
- ViewController๋ฅผ extension์ ํ์ฉํ์ฌ ๋ถ๋ฆฌํด๋ณด์๋ค. ์ฃผ์์์ฝ์ด
// MARK:
๋ ๊ฐ์ด ํ์ฉํด๋ณด์๋ค. - ๊ณ์ ์ต์
๋ ๋ฐ์ธ๋ฉ ์ฒ๋ฆฌ๊ฐ ํ์ํ
Label.text
๋ ์ฐ์ฐํ๋กํผํฐ๋ฅผ ํ์ฉํ์ฌ ์ฝ๋ ๋ด๋ถ๋ฅผ ๊ฐ์ ํด๋ณด์๋ค. - ๊ฐ๋
์ฑ์ ์ํด
+=
์ฐ์ฐ์ ์ฌ์ฉ์ ํ์ง์์๋ค. ํ์ด์ ์ฐ๋๊ฒ ์ข๋ ๊ฐ๋ ์ฑ์ด ์ข์ ๋๊ฐ ์๋ค๋ ์๊ฐ์ด ๋ค์๋ค. - StackView ๋ด๋ถ์ ์๋ UILabel์ text๋ฅผ joinedํ๋ ๋ฉ์๋๋ฅผ UIStackView๋ฅผ extensionํ์ฌ ํ๋กํผํฐ(toString)๋ก ๋ง๋ค์ด์ฃผ์๋ค.
์ฌ์ฉํ๋ฉด
stackView.toString
์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์ ์ข๋ ์ง๊ด์ ์ผ ์ ์๋๋ก ๊ตฌํํด์ฃผ์๋ค. - ์ค๋ณต, ๋ฐ๋ณต๋๋ ๋ถ๋ถ์ ๋ฉ์๋๋ก ๋ถ๋ฆฌํด์ฃผ๋ ๋ฆฌํฉํ ๋ง์ ์งํํ๋ค.
- ์กฐ๊ฑด๋ฌธ์ ๋ณ์๋ก ๋ง๋ค์ด์ฃผ์ด ๋ฉ์๋ ๋ด๋ถ ๊ฐ๋ ์ฑ์ ํฅ์์์ผฐ๋ค.
- ViewController๋ฅผ extension์ ํ์ฉํ์ฌ ๋ถ๋ฆฌํด๋ณด์๋ค. ์ฃผ์์์ฝ์ด
- Stack View์ subview๋ค์ ๊บผ๋ด์ ์ฌ์ฉํ ๋ ๋ฐฉ๋ฒ์ ๋ฐ๋ณต๋ฌธ ๋ฐ์ ์๋๊ฑธ๊น?
- NumberFormatter์๋ string์ผ๋ก ๋ณํํด์ฃผ๋ ๋ฉ์๋๋ ์์ง๋ง NSNumber๋ก ๋ณํํด์ฃผ๋ ๋ฉ์๋๋ ์๋๋ฐ.. ๊ผญ ์ฌ์ฉํด์ผํ ๊น?
-
์ํฉ
- ์คํฌ๋กค ๋ทฐ์ ์ฝํ ์ธ ๋ทฐ ์์ ์ ์ค์ ํ๋ ๋ฉ์๋๋ฅผ ํ์ฉํด๋ณด์๋ค.
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.height + scrollView.contentInset.bottom) scrollView.setContentOffset(bottomOffset, animated: false)
- ๊ทธ๋ฌ๋ ์คํฌ๋กค ๋ฐ๊ฐ ์๊ธธ๋ ์ฝ๊ฐ ์์ง์ด๋ฉด์ ์คํฌ๋กค์ด ์๋๋... ์ด์ํด๋ณด์ด๋ ์ ๋๋ฉ์ด์ ์ ์ทจํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
- ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด๋ณด๊ธฐ ์ํด์ 1์ฐจ์ ์ผ๋ก ๊ตฌ๊ธ๋ง์ ํตํด ์ฐพ์๋ณด์๊ณ , ์ฐพ๋๋ฐ ์ด๋ ค์์ด ์์ด 3๊ธฐ ์บ ํผ ์ ๋ฐฐ๋ถ๋ค์๊ฒ๋ ์ง๋ฌธํด๋ณด์์ง๋ง ํด๊ฒฐ๋ฐฉ๋ฒ์ ์ฐพ์ง ๋ชปํ๋ค.
-
์ด์
- 3๊ธฐ ์บ ํผ
์๋ฐ
์ ๋์์ผ๋ก LLDB๋ฅผ ํ์ฉํ์ฌ ์ฒ์ y์ขํ๊ฐ ์ด๋ค ๊ฐ์ผ๋ก ์ฐํ๋์ง ํ์ธํด๋ณด์์ผ๋, StackView๊ฐ ์ถ๊ฐ๋๊ณ ๋ ํ ์ ๋ฐ์ดํธ ๋์ด y๊ฐ ์ขํ๊ฐ ๊ณ์ฐ์ด ๋์ด์ผ ํ๋๋ฐ, ๋ฒํผ์ ๋๋ฅด๊ธฐ ์ด์ ์ y์ขํ๊ฐ ์ฐํ๋ ๊ฒ์ด ํ์ธ๋์๋ค. - ํ์ด๋จธ๋ ๋น๋๊ธฐ์ ์ผ๋ก ํด๋น ๋ถ๋ถ์ ํด๊ฒฐํด๋ณด๋ ค๊ณ ํด๋ณด์์ผ๋ ๋ฐ๋ง ๋ด๊ถ๋ดค์ง ์ ๋๋ก ๋ฐฐ์๋ณด์ง ์์ ์ง์์ด๋ผ ํด๊ฒฐํ๋๋ฐ ๋ง์ ์ด๋ ค์์ด ์์๋ค.
- ์ดํ ์ํฌํฐ์ฆ
Wody
์๊ฒ ์ง๋ฌธํด๋ณด์๊ณ ์ผ๋ง ์ง๋์ง ์์ ํด๊ฒฐ์ ํ ์ ์๊ฒ ๋์๋ค.
- 3๊ธฐ ์บ ํผ
-
์ ์์ ์ผ๋ก ํ๋จ์ผ๋ก ์๋ ์คํฌ๋กค์ด ๋๋ ๋ชจ์ต
layoutIfNeeded()
๋ผ๋ ๋ฉ์๋๋ฅผ ํ์ฉํ์ฌ ํด๊ฒฐํ๊ฒ ๋์๋ค. (๋์์ ์ฃผ์ ๊ฐwody์๊ฒ ๊ฐ์ฌ์ ์ธ์ฌ๋ฅผ ๋๋ฆฝ๋๋ค.
) ์ด ๋ฉ์๋๋setNeedsLayout()
๊ณผ ๊ฐ์ด ์๋์ผ๋ก layoutSubviews๋ฅผ ์์ฝํ๋ ํ์์ด์ง๋ง ํด๋น ์์ฝ์ ๋ฐ๋ก ์คํ์ํค๋ ๋๊ธฐ์ ์ผ๋ก ์๋ํ๋ ๋ฉ์๋๋ค. update cycle์ด ์ฌ ๋ ๊น์ง ๊ธฐ๋ค๋ ค layoutSubviews๋ฅผ ํธ์ถ์ํค๋ ๊ฒ์ด ์๋๋ผ ๊ทธ ์ฆ์ layoutSubviews๋ฅผ ๋ฐ๋์ํค๋ ๋ฉ์๋๋ค.- ๋ง์ผ main run loop์์ ํ๋์ View๊ฐ setNeedsLayout์ ํธ์ถํ๊ณ ๊ทธ ๋ค์ layoutIfNeeded๋ฅผ ํธ์ถํ๋ค๋ฉด layoutIfNeeded๋ ๊ทธ ์ฆ์ View์ ๊ฐ์ด ์ฌ๊ณ์ฐ๋๊ณ ํ๋ฉด์ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ setNeedsLayout์ด ์์ฝํ layoutSubviews ๋ฉ์๋๋ update cycle์์ ๋ฐ์ํด์ผํ ๋ณ๊ฒฝ๋ ๊ฐ์ด ์กด์ฌํ์ง ์๊ธฐ ๋๋ฌธ์ ํธ์ถ๋์ง ์๋๋ค.
- ์ด๋ฌํ ๋์ ์๋ฆฌ๋ก
layoutIfNeeded()
๋ ๊ทธ ์ฆ์ ๊ฐ์ด ๋ณ๊ฒฝ๋์ด์ผ ํ๋ ์ ๋๋ฉ์ด์ ์์ ๋ง์ด ์ฌ์ฉ๋๋ค๊ณ ํ๋ค. ํด๊ฒฐ
- ๋ฐ๋ผ์ ์คํฌ๋กค๋ทฐ์ ์์ ์ ๋ํ ์ฝํ
์ธ ๋ทฐ์ ์คํ์
์ค์ ์ ํด์ฃผ๊ธฐ ์ ์
layoutIfNeeded()
๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ layout์ ์ ๋ฐ์ดํธ ํ๊ณ setContentOffset์ ์ค์ ํด์ฃผ์๋๋ ํด๋น ๋ฌธ์ ์ ๋ํด์ ํด๊ฒฐ๋์๋ค.
- ๋ฐ๋ผ์ ์คํฌ๋กค๋ทฐ์ ์์ ์ ๋ํ ์ฝํ
์ธ ๋ทฐ์ ์คํ์
์ค์ ์ ํด์ฃผ๊ธฐ ์ ์
-
์ํฉ
์คํ๋ทฐ > ์คํ๋ทฐ > ๋ ์ด๋ธ ๊ณ์ธต์ ๊ฐ์ง ๋ถ๋ถ์์ ๋ ์ด๋ธ์ ํ ์คํธ๋ฅผ ๊บผ๋ด๋ ค๋ฉดarrangedSubviews
๋ฅผ์ด์ค for๋ฌธ
์ ๋๋ฉด์ ๊ฐ์ ธ์์ผ ํ๋ ์ํฉ์ด ๋ง์์ ์๋ค์๋ค.extension UIStackView { var toString: String { var inputValues = [String]() self.arrangedSubviews.forEach{ view in let subview = view as? UIStackView subview?.arrangedSubviews.forEach{ view in let label = view as? UILabel guard let input = label?.text else { return } inputValues.append(input.replacingOccurrences(of: ",", with: "")) } } return inputValues.joined(separator: " ") } }
-
ํด๊ฒฐ๋ฐฉํฅ
๋ฆฌ๋ทฐ์ด์ธ ์๋ฆผ์๊ฒ ์กฐ์ธ์ ๊ตฌํด์์คํ๋ทฐ > ์ปค์คํ ๋ทฐ
๊ณ์ธต์ ๊ฐ์ง ์ ์๋๋ก ์ปค์คํ ๋ทฐ ๋ง๋ค๊ธฐ์ ๋์ ํด๋ณด์๋ค. -
๊ฒฐ๊ณผ
extension UIStackView { var toString: String { var inputValues = [String]() self.arrangedSubviews.forEach { view in guard let formualStackView = view as? FormulaStackView else { return } inputValues.append(contentsOf: formualStackView.element) } return inputValues.joined(separator: " ") } }
-
FormulaStackView
๋ผ๋ ์ปค์คํ ๋ทฐ๋ฅผ ๋ง๋ค์ด ์ค์ผ๋ก์จ ์ด์ค for๋ฌธ์ ๋๋ ๋ฌธ์ ๋ ํด๊ฒฐ์ด ๋์๊ณ , ViewController์์ ์คํ๋ทฐ ๋ด๋ถ์Label์ ์ถ๊ฐ
ํด์ฃผ๋ ๋ถ๋ถ๋ ์ปค์คํ ๋ทฐ ๋ด๋ถ์์ ํด๊ฒฐํ ์ ์๊ฒ๋์๋ค.
์ํฉ
๊ณ์ฐ๋ด์ญ์ด ์์ฌ์ ์คํฌ๋กค๋ฐ๊ฐ ์๊ธฐ๋ ๋ฌธ์ ๋ก ์คํฌ๋กค์ ์งํํ ์ ๊ธ์จ๊ฐ ๊ฐ๋ ค์ง๋ ๋ฌธ์ ๊ฐ ์์๋ค.ํด๊ฒฐ๋ฐฉํฅ
์คํฌ๋กค๋ฐ๋ฅผ ๊ฐ๋ฆด ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋์ง ๊ตฌ๊ธ๋ง์ ํตํด์ ์ฐพ์๋ณด์๋ค.๊ฒฐ๊ณผ
- ์ฐพ์๋ณด๋ ์ธํฐํ์ด์ค ๋น๋์์๋ ์ค์ ์ ํด์ค ์๋ ์๊ณ ์ฝ๋๋ก๋ ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์๋ค.
์ํฉ
์๋ฆผ์๊ฒ ๋ฒํผ์ ๋ฅ๊ธ๊ฒ ๋ง๋ค์ด๋ณด๋ ๋์ ๊ณผ์ ๋ฅผ ๋ฐ๊ฒ๋์ด ํด๊ฒฐํด๋ณด๊ธฐ๋ก ํ์๋ค.
์๋-1
์ฒ์์๋ ๋ฒํผ ์์ฒด๊ฐ ์ฝ๋๊ฐ ์๋ ์คํ ๋ฆฌ๋ณด๋์์ ์์ฑ๋ ๋ฒํผ์ด๋ผ์ ์ธํฐํ์ด์ค ๋น๋๋ก ํด๊ฒฐํด๋ณด๊ณ ์ ํ์๋ค.
extension UIView {
@IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}
}
- ๊ทธ๋ฌ๋ ์ด ๋ฐฉ๋ฒ์ผ๋ก๋ ๋ฒํผ์ cornerRadius๋ฅผ ์ง์ ๋์ ํด์ฃผ๋ ๋ฐฉ์์ด๊ธฐ ๋๋ฌธ์ ๋๋ฐ์ด์ค๊ฐ ๋ค๋ฅผ ๊ฒฝ์ฐ ๋ด๊ฐ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ธฐ์๋ ํ๋ค๋ค๊ณ ํ๋จ๋์๋ค. ๊ทธ๋์ ์ฝ๋๋ก ํด๋ณผ ์ ์๋ ๋ฐฉ๋ฒ์ ์ฐพ์ ํด๊ฒฐํด๋ณด์๋ค.
์๋-2
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
calculatorButtons.forEach { button in
button.layer.cornerRadius = button.layer.frame.size.width / 2
}
}
- ๋ฒํผ์ ๋๋น / 2๋ฅผ ํด์ cornerRadius๋ฅผ ์ค์ ํด์ค ์ฝ๋๋ค. ์ด๋
viewWillLayoutSubviews
๋ฉ์๋๋ฅผ ์จ์ค๋ค.
- ๋ทฐ์ ๋ฐ์ด๋๊ฐ ์ต์ข ์ ์ผ๋ก ๊ฒฐ์ ๋๋ ์ต์ด ์์
- ์ ์ฝ์ด๋ ์คํ ๋ ์ด์์์ ์ฌ์ฉํ์ง ์์๋ค๋ฉด, ์๋ธ๋ทฐ์ ๋ ์ด์์์ ์ ๋ฐ์ดํธํ๊ธฐ ์ ํฉํ ์์ ์ด๋ค.
- ์ฌ๋ฌ๋ฒ ์ค๋ณต์ผ๋ก ํธ์ถ๋ ์ ์๋ค.
- ๋ฉ์ธ๋ทฐ์ ์๋ธ๋ทฐ๊ฐ ๋ก๋๋๋ ๊ฒฝ์ฐ
- ๋ฉ์๋๋ฅผ ์์๋ณด๊ณ ์๋ฆผ์ ํผ๋๋ฐฑ์ ๋ฐ๊ณ ๋ค์ ๋๋ฒ๊น
์ ํด๋ณด๋
๋ฒํผ์ด ํด๋ฆญ์ด ๋๋ ์์
๋ง๋ค ํด๋น ๋ฉ์๋๊ฐ ํธ์ถ์ด ๋๊ณ ์์๋ค. cornerRadius๋ฅผ ์ก์์ฃผ๋ for๋ฌธ์ด ๋ฒํผ์ด ๋๋ฅผ๋๋ง๋ค ์คํ๋๊ณ ์์๋ ๊ฒ์ด๋ค. ์ฆ SubView์ ๋ ์ด์์์ ์ก์์ฃผ๊ธฐ์๋ ์ ์ ์น ๋ชปํ ๋ฉ์๋์๋ค.
์๋-3, ๊ทธ๋ฆฌ๊ณ ํด๊ฒฐ
-
๋ฒํผ์ IBOutlet์ didSet์ ์ค ์๋ ์์์ง๋ง ์๋์ ๊ฐ์ ๋ฌธ์ ๋๋ฌธ์ ํด๋น ๋ฐฉ๋ฒ์ ๋ถ๊ฐ๋ฅ ํ๋ค.
-
๋๋ฒ๊น ์ ํด๋ณด๋
viewWillLayoutSubviews
๋ฉ์๋๊ฐ ํธ์ถ๋๋ ์์ ์ ๋ ์ด์์์ด ๊ฐฑ์ ๋์ด ๋ฒํผ์ ๋๋น๊ฐ ๋ฐ๋๊ณ ์์๋ค. (๋๋ฐ์ด์ค๋ ์์ดํฐ SE ๊ธฐ์ค์ด๋ค. SE ์ด์ ๋๋ฐ์ด์ค์์๋ ์๋ ๋ฌธ์ ์๋ค.) IBOutlet์ didSet์viewDidLoad๊ฐ ํธ์ถ๋๊ธฐ ์
์ ํธ์ถ๋๋ฏ๋ก ์ ์ ํ์ง ๋ชปํ ๋ฐฉ๋ฒ์ด์๋ค. -
๋ฐ๋ผ์ ์ต์ํ์ผ๋ก ์ ๊ฒ ํธ์ถ๋๋
updateViewConstraints
๋ฉ์๋๋ฅผ ํ์ฉํ์ฌ ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์๋ค.func setupButtons() { calculatorButtons.forEach { button in button.layoutIfNeeded() button.layer.cornerRadius = button.layer.bounds.width / 2 } } override func updateViewConstraints() { super.updateViewConstraints() setupButtons() }
-
updateViewConstraints์ ๋ฒํผ์ ํ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ์๊ณ , for๋ฌธ ๋ด๋ถ์์ ๋ฒํผ๋ง๋ค
layoutIfNeeded
๋ฅผ ํธ์ถํ์ฌ ๋ ์ด์์์ ๊ฐฑ์ ํ๊ณ ์ดํ cornerRadius ๊ฐ์ ๋์ ํด์ฃผ๊ณ ์๋ค. -
๋ ์ด์์์ ๊ฐฑ์ ํ๋ ์ด์ ๋ ๊ฐฑ์ ํ์ง ์์ผ๋ฉด ์ ๋๋ฒ๊น ์ ๋ฐ๊ฒฌํ์๋ ์ต์ข ๋ ์ด์์์ด ์๋๋ผ ์์๋ก ์กํ์๋ frame๊ฐ์ผ๋ก ๊ณ์ฐ์ ํ๊ธฐ ๋๋ฌธ์ ์๋์ฒ๋ผ ์ฐ๊ทธ๋ฌ์ง ์์ด ๋์จ๋ค.
๊ฒฐ๋ก
- viewDidLoad์์ frame์ฌ์ด์ฆ๊ฐ ์ ํํ์ง ์์ ์ ์๋ค. ํด๋น ํจ์๋ ๋ทฐ๋ ๋ก๋๋๋ค๊ณ ํ์ธํ ์ ์์ง๋ง, ๋ฐฐ์น๊ฐ ๋๋ค๊ณ ํ ์๋ ์๋ค. ๋ฐ๋ผ์ ์์ ๊ฐ์ ํ์์ viewDidLoad์์ ์์๋ก ์กํ๋ frame๊ฐ์ด
viewWillLayoutSubviews
๊ฐ ํธ์ถํ๋ฉด์ ํ์ ๋ทฐ๊ฐ ๋ฐฐ์น๋๊ณ ์ดํ ๊ฐ์ด ๋ณํ๋ค๊ณ ๋ณผ ์ ์๊ฒ ๋ค. ๋ฐ๋ผ์ ํ์๋ทฐ๊ฐ ๋ฐฐ์น๊ฐ ๋๊ณ ๋์ ๋ฒํผ์ ๋ ์ด์์์ ์ก์์ค์ผ ํด๊ฒฐ์ด ๊ฐ๋ฅํ๋ ๊ฒ์ด๋ค.
์ฌ๊ธฐ์ ์๋ฌธ์ ์ด ๋๋ ๊ฒ์ ๋ค๋ฅธ ๋๋ฐ์ด์ค๋ค์ ์๊ด์๋๋ฐ ์ SE์์๋ง ๋ฒํผ์ ํฌ๊ธฐ๊ฐ ์ค์ด๋๋ ๊ฒ์ผ๊น?
- 3๊ธฐ ์บ ํผ
์๋ฐ
์ ๋์์ผ๋ก ํด๋น ์๋ฌธ์ ์ ํ ์ ์์๋ค.
- HIG์์ ์ฅ์น๋ค์ ์น์๋ฅผ ํ์ธํด์ ์ธ๋ก๋ฅผ ๋ณด๋ฉด 200~300์ ๋ ์ฐจ์ด๊ฐ ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ์ฌ์ง์์๋ ๋ณผ ์ ์๋ฏ์ด ์ธ๋ก ํฌ๊ธฐ๊ฐ ์์ฒญ ์ฐจ์ด๋๋ค. ๋ฐ๋ผ์ ์์์ง ๋๋ฐ์ด์ค์ ์คํ ๋ ์ด์์์ ์ถฉ์กฑํ๊ธฐ ์ํด ๋ฒํผ์ ํฌ๊ธฐ๋ฅผ ์ค์ผ ์ ๋ฐ์ ์๋ค๋ ์ถ์ธก์ด ๊ฐ๋ฅํด์ก๋ค.
- ์ด๋ฌํ ์ฌ์ค์ ์ฆ๋ช ํด๋ผ ์๋ ์๋ค. ์ง์ ๋ ์ด์์์ ๋ค ๊ณ์ฐํ์ฌ ์น์์ ๋ง๋์ง ํ์ธํ ์๋ ์์ง๋ง... ๋์ค์ ์๋ํด๋ด์ผ๊ฒ ๋ค. ๐
- didSet์ผ๋ก UI ์์๋ค์ ๋ ์ด์์์ ์ก์์ฃผ๋๊ฑด ๋ถ์์ฐ์ค๋ฝ๋ค. ์คํ๋ ค ์ง๊ธ์ฒ๋ผ view๊ฐ ๋ฐฐ์น๋ ํ ๋ ์ด์์์ ์ก์์ค ๊ฒ์ด ์์ฐ์ค๋ฝ๊ณ ์ข์ ๋ฐฉ๋ฒ์ด๋ค.
- ๊ทธ๋ฆฌ๊ณ UI ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋ ํด๋ก์ ๋ก ์ ์ธํ๋ ๋ฐฉ๋ฒ์ด ์๊ณ , ์ธ์คํด์ค๋ก ์ ์ธ ์ดํ ๊ฐ์ ๋ณ๊ฒฝํด์ค ์๋ ์๋ค.
- ์ ์ธ ์ดํ ๊ฐ์ ๋ณ๊ฒฝํด์ฃผ๋ ๋ฐฉ๋ฒ์ ๋ฌธ๋งฅ์ ๋ถ์์ฐ์ค๋ฌ์ธ ์ ์์ผ๋ฏ๋ก ์ง์ํ๋๊ฒ ์ข์ ๊ฒ ๊ฐ๋ค๋ ์๊ฒฌ.
- let์ผ๋ก ์ ์ธํ ๊ฐ์ ๋ณ๊ฒฝํด์ฃผ๋ ๊ฑฐ๋๊น ๋ถ์์ฐ์ค๋ฝ๋ค๋ ๋ฌ์์ค!
- ์ ์ด์ ํด๋ก์ ๋ก ์ ์ธํ์ฌ ์์์ ์์ฑ๋ค์ ์ค์ ํด์ฃผ๊ณ ๊ทธ๋๋ก ์ญ ์ฌ์ฉํ๋๊ฒ ๋ ์์ฐ์ค๋ฝ๋ค!
- ์ฝ๋๋ก UI๋ฅผ ๊ทธ๋ ค๋ณด๋ ๋ฐฉ๋ฒ
Stack View
- ์ฝ๋๋ก Stack View์ layout์ ์ก๋ ๋ฐฉ๋ฒ
Scroll View
- ์คํฌ๋กค ๋ฐ ์์ ๋ ๋ฐฉ๋ฒ
layoutIfNeeded()
ํ์ฉNumberFormatter
LLDB
super.viewDidLoad()
protocol LocalizedError
์ฉ๋@IBInspectable
viewWillLayoutSubviews()
- ์ปค์คํ
๋ทฐ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ (only Code)
init(frame:)
์ยinit(coder:)
์ ์ฐจ์ด์
View Life Cycle
์ ๋ํ ๊น์ ์ดํดframe
๊ณผbounds
์ ์ฐจ์ด์ IBOutlet
์didSet
์ ์ธ์ trigger
๋๋์ง?
- ๋์ผํ return์ ํ๋ guard๋ฌธ์ ํฉ์ณ์ ๊ฐ์
- ์คํฌ๋กค๋ฐ ๋๋ฌธ์ ๊ฐ๋ ค์ง๋ ๋ฌธ์ ํด๊ฒฐ
- ์ฃผ์์์น์ ์ค๋ฐ๊ฟ์ผ๋ก ์ฝ๋ ๋ด๋ถ ๊ฐ๋ ์ฑ ๊ฐ์
- ์ค๋ณต๋๋ ๋ถ๋ถ ๋ฉ์๋๋ก ๋ถ๋ฆฌํ์ฌ ๊ฐ์
- toggle ์ฌ์ฉ์ผ๋ก ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๋ ๋ถ๋ถ์ ์ง์ ๋์ ํด์ฃผ๋ ๋ฐฉ์์ผ๋ก ๊ฐ์
- LocalizedError ํ๋กํ ์ฝ์ ํ์ฉํ์ฌ description์ ์ข ๋ ์ง๊ด์ ์ผ๋ก ํ์ธํ ์ ์๊ฒ ๊ฐ์
- ์ปค์คํ ๋ทฐ๋ฅผ ๋ง๋ค์ด์ ViewController ๋ด๋ถ ์ฝ๋ ๊ฐ์