Tip-Calculator (2)
Warning 해결
현재 실행을 하게되면
1
2
3
4
5
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
이런식으로 Auto Layout에 대한 워닝이 발생한다.
에러가 발생하는 이유는 Vertical StackView 때문인데
여기안에 UIView를 하나 더 추가를 해줘야한다.
설명이 이해가 안가서 나중에 다시 알아봐야할거같다.
이렇게 UIView하나가 새로 생기면서 해결이 되긴 했다.
폰트 적용 틀 만들어두기.
지원버전은 사이트참고
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct ThemeFont {
// AvenirNext
static func regular(ofSize size: CGFloat) -> UIFont {
return UIFont(name: "AvenirNext-Regular", size: size) ?? .systemFont(ofSize: size)
}
static func bold(ofSize size: CGFloat) -> UIFont {
return UIFont(name: "AvenirNext-Bold", size: size) ?? .systemFont(ofSize: size)
}
static func demibold(ofSize size: CGFloat) -> UIFont {
return UIFont(name: "AvenirNext-Demibold", size: size) ?? .systemFont(ofSize: size)
}
}
LogoView 디자인
이건 완성된 코드하나도 될 것 같다.
이렇게 디자인 할 생각을 하지 못했는데 새로운 강의를 들으면서 제대로 배웠다.
구현할 View를 먼저 클래스 파일로 만들고 거기서 디자인을 한다.
이게 포인트다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
class LogoView: UIView {
private let imageView: UIImageView = {
let view = UIImageView(image: .init(named: "icCalculatorBW"))
view.contentMode = .scaleAspectFit
return view
}()
private let topLabel: UILabel = {
let label = UILabel()
let text = NSMutableAttributedString(string: "Mr TIP",attributes: [.font: ThemeFont.demibold(ofSize: 16)])
text.addAttributes([.font: ThemeFont.bold(ofSize: 24)], range: NSMakeRange(3, 3)) // TIP부분 더 강조
label.attributedText = text
return label
}()
private let bottomLabel: UILabel = {
LabelFactory.build(
text: "Calculator",
font: ThemeFont.demibold(ofSize: 20),
textAlignment: .left)
}()
private lazy var vStackView: UIStackView = {
let view = UIStackView(arrangedSubviews: [
topLabel,
bottomLabel
])
view.axis = .vertical
view.spacing = -4
return view
}()
private lazy var hStackView: UIStackView = {
let view = UIStackView(arrangedSubviews: [
imageView,
vStackView
])
view.axis = .horizontal
view.spacing = 8
view.alignment = .center
return view
}()
init () {
super.init(frame: .zero)
layout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func layout() {
addSubview(hStackView)
hStackView.snp.makeConstraints { make in
make.top.bottom.equalToSuperview()
make.centerX.equalToSuperview()
}
imageView.snp.makeConstraints { make in
make.height.equalTo(imageView.snp.width)
}
}
}
// LabelFactory
struct LabelFactory {
// 기본적인 틀을 구조화
static func build(
text: String?,
font: UIFont,
backgroundColor: UIColor = .clear,
textColor: UIColor = ThemeColor.text,
textAlignment: NSTextAlignment = .center) -> UILabel {
let label = UILabel()
label.text = text
label.font = font
label.backgroundColor = backgroundColor
label.textColor = textColor
label.textAlignment = textAlignment
return label
}
}
완성.
ResultView 추가
위와 상동
다만 하나 알아두면 좋을 것은
1
2
3
4
5
6
7
8
9
10
private lazy var hStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [
AmountView(),
UIView(), // 사이에 끼워줌.
AmountView()
])
stackView.axis = .horizontal
stackView.distribution = .fillEqually
return stackView
}()
이렇게 가운데에 UIView 를 끼워주고 3분할을 정확하게 해주었다는 것.
또 하나 배웠다.
shadow효과를 위한 extension 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
extension UIView {
func addShadow(offset: CGSize, color: UIColor, radius: CGFloat, opacity: Float) {
layer.cornerRadius = radius
layer.masksToBounds = false
layer.shadowOffset = offset
layer.shadowColor = color.cgColor
layer.shadowRadius = radius
layer.shadowOpacity = opacity
let backgroundCGColor = backgroundColor?.cgColor
backgroundColor = nil
layer.backgroundColor = backgroundCGColor
}
}
가운데 선과 아래 View 사이 패딩 추가
1
2
3
4
5
private func buildSpacerView(height: CGFloat) -> UIView {
let view = UIView()
view.heightAnchor.constraint(equalToConstant: height).isActive = true
return view
}
이렇게 하나 만들어주고
1
2
3
horizontalLineView,
buildSpacerView(height: 0),
hStackView
높이 0짜리를 하나 사이에 끼워 넣어주면서 패딩이 자연스럽게 된다.
완성
AmountView 디자인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class AmountView: UIView {
private let title: String
private let textAlignment: NSTextAlignment
private lazy var titleLabel: UILabel = {
LabelFactory.build(
text: title,
font: ThemeFont.regular(ofSize: 18),
textColor: ThemeColor.text,
textAlignment: textAlignment)
}()
private lazy var amountLabel: UILabel = {
let label = UILabel()
label.textAlignment = textAlignment
label.textColor = ThemeColor.primary
let text = NSMutableAttributedString(
string: "$0",
attributes: [
.font: ThemeFont.bold(ofSize: 24)
])
text.addAttributes([
.font: ThemeFont.bold(ofSize: 16)
], range: NSMakeRange(0, 1))
label.attributedText = text
return label
}()
private lazy var stackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [
titleLabel,
amountLabel
])
stackView.axis = .vertical
return stackView
}()
// custom Initializer
init(title: String, textAlignment: NSTextAlignment) {
self.title = title
self.textAlignment = textAlignment
super.init(frame: .zero)
layout()
}
//
// override init(frame: CGRect) {
// super.init(frame: frame)
// layout()
// }
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func layout() {
addSubview(stackView)
stackView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
}
처음에 AmountView를 같은걸 해놔서 똑같은 뷰가 두개가 되어있었는데,
이것을 Custom Initializer를 통해 text와 문자 배열을 하게 설정을 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
// custom Initializer
init(title: String, textAlignment: NSTextAlignment) {
self.title = title
self.textAlignment = textAlignment
super.init(frame: .zero)
layout()
}
// origin initializer -> Don't use this method
override init(frame: CGRect) {
super.init(frame: frame)
layout()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// resultview의 일부
private lazy var hStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [
AmountView( // modified
title: "Total Bill",
textAlignment: .left),
UIView(), // 사이에 끼워줌.
AmountView( // modified
title: "Total Tip",
textAlignment: .right)
])
stackView.axis = .horizontal
stackView.distribution = .fillEqually
return stackView
}()
뭔가 Code로 UIdesign 하는것에 신세계를 경험하게 된다.
너무 길어지니 파트2는 여기까지
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.