Views
๐ ๋ทฐ๋ ์ฌ๊ฐํ์ ๊ณต๊ฐ์ ๋ํ๋
๋๋ค. ๊ณต๊ฐ์ ์ขํ ์์คํ
์ ์ํด ์ ์๋๊ณ ๊ทธ๋ ค์ง๋๋ค. ๊ทธ๋ฆฌ๊ณ ํฐ์น ์ด๋ฒคํธ๋ค์ ์ฒ๋ฆฌํ๋ ๊ธฐ๋ฅ์ ์ํํฉ๋๋ค.
๐ ๋ทฐ๋ ๊ณ์ธต์ ์ธ ํน์ง์ ๊ฐ๊ณ ์๋๋ฐ ํน์ ๋ทฐ๋ ํญ์ ํ๋์ superview๋ฅผ ๊ฐ๊ณ , subview๋ฅผ ๊ฐ๊ณ ์์ง ์๊ฑฐ๋ 1๊ฐ ์ด์ ๊ฐ์ง ์ ์์ต๋๋ค.
๐ ๋ทฐ๋ค์ด ๊ทธ๋ ค์ง๋ ์์๋ ์ต๊ทผ์ subview๋ก ์ถ๊ฐ๋ ๋ทฐ๊ฐ ๊ฐ์ฅ ์์ ๊ทธ๋ ค์ง๊ฒ ๋ฉ๋๋ค.
๐ ๋ทฐ๋ subview์ ๊ฒน์น์ง ์์ ๋ถ๋ถ์ ์๋ฅผ ์๋ ์์ต๋๋ค. ์๋ฅด์ง ์๋ ๊ฒ์ด ๊ธฐ๋ณธ์
๋๋ค. (์ฐธ๊ณ ํ ๋ฌธ์ฅ: A view can clip its subviews to its own bounds or not (the default is not to)).
๐ UIView๋ ๋ทฐ ๊ณ์ธต์ ๊ฐ์ฅ ์์ ์์ต๋๋ค. UIView์์ UIWindow๊ฐ ์๊ธด ํ๋ฐ UIWindow๋ ๋ณดํต iOS ์ฑ์์๋ ํ ๊ฐ์ด๊ณ ๊ธฐ๊ธฐ์ ์ธ๋ถ ํ๋ฉด์ ์ถ๋ ฅํ์ง ์๋ ์ด์ ๋ค๋ฃฐ ์ผ์ด ์์ต๋๋ค.
CS193P ๊ฐ์์์๋ UIWindow๋ฅผ ๋ค๋ฃจ์ง ์์ต๋๋ค.
UIView ์ด๊ธฐํ
UIView๋ฅผ ์ด๊ธฐํ ํ๋ ๋ฐฉ๋ฒ (๋ทฐ์๋ ๋ค์์ ์ธ๊ฐ์ง ์ด๊ธฐํ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.)
- init() ๐ UIView๊ฐ ์์๋ฐ์ UIResponder๊ฐ ์์๋ฐ์ NSObject์ init() ๋ฉ์๋๊ฐ ํธ์ถ๋๋ค
- init(frame: CGRect) ๐ ์ฝ๋๋ก ๋ทฐ๋ฅผ ๋ง๋ค ๋ ํธ์ถํ๋ ์ฉ๋
- init(coder: NSCoder) ๐ ์คํ ๋ฆฌ ๋ณด๋์์ ํธ์งํ๊ณ ์ฑ์ด ์คํ๋ ๋ ํธ์ถํ๋ ์ฉ๋
์ ์ด๊ธฐํ ๋ฉ์๋๋ค์ ํด๋์ค ์ธ์คํด์ค์ ์์ฑ ๊ฐ๋ค์ ์ค์ ํ๋ ์ญํ ์ ํฉ๋๋ค. Optional ์์ฑ ๊ฐ์ ์ค์ ํ์ง ์๊ณ nil๋ก ๋์ด๋ ์๊ด์์ง๋ง ๊ทธ ์ธ์ ์์ฑ ๊ฐ๋ค์ ํ์๋ก ์ค์ ํด์ผ ๋ฉ๋๋ค.
awakeFromNib()
์ด ๋ฉ์๋๋ ์ด๊ธฐํ ๋ฉ์๋๊ฐ ์๋์ง๋ง ์ด๊ธฐํ๊ฐ ๋๋ ์งํ์ ์คํ๋๋ ๋ฉ์๋์
๋๋ค. Only ์ธํฐํ์ด์ค ๋น๋ ํ์ผ์์ ๋์จ ๋ทฐ์์๋ง ์คํ๋๋ ๋ฉ์๋์
๋๋ค. ๊ทธ๋์ init(coder: NSCoder) ๊ฐ ์คํ๋ ํ์ ์คํ๋ฉ๋๋ค.
(๐ค TMI: NiB๋ "NeXTSTEP Interface Builder" ์ ์ฝ์์
๋๋ค.)
์ขํ ์์คํ ๊ตฌ์กฐ (Coordinate System Data Structures)
CG(Core Graphics)
CGFloat ๐ UIView์ ์ขํ ์์คํ ์์ ํญ์ Double์ด๋ Float์ด ์๋ CGFloat์ ์ฌ์ฉํด์ผ ๋ฉ๋๋ค.
let cgf = CGFloat(10.0)
CGPoint ๐ ๋ ๊ฐ์ CGFloat์ผ๋ก ์ด๋ฃจ์ด์ง struct์ด๊ณ x, y ๊ฐ์ ๊ฐ์ง๋๋ค.
var point = CGPoint(x: 37.0, y: 55.2)
point.y -= 30
point.x += 20.0
CGSize ๐ ๋๊ฐ์ CGFloat์ผ๋ก ์ด๋ฃจ์ด์ง struct ์ด๊ณ width, height ๊ฐ์ ๊ฐ์ง๋๋ค.
var size = CGSize(width: 100.0, height: 50.0)
size.width += 42.5
size.height += 75
CGRect ๐ ์ขํ์ ์ฌ์ด์ฆ ๋ฑ์ ์ฌ์ฉํด์ ์ฌ๊ฐํ์ ๋ํ๋ด๋ struct์ ๋๋ค. ์ด๊ธฐํ ๋ฐฉ๋ฒ์ ์๋ ์ฝ๋๋ฅผ ํฌํจํด์ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
struct CGRect {
var origin: CGPoint
var size: CGSize
}
let rect = CGRect(origin: aCGPoint, size: aCGSize)
๋ทฐ ์ขํ ์์คํ (View Coordinate System)
origin
์ขํ์ ์์ (0,0)์ ํด๋นํ๋ ์์น๋ ์ข์ธก ์๋จ์ด๊ณ x ๊ฐ์ด ์ฆ๊ฐํ๋ฉด ์ค๋ฅธ์ชฝ, y๊ฐ์ด ์ฆ๊ฐํ๋ฉด ์๋์ชฝ์ผ๋ก ๊ฐ๊ฒ ๋ฉ๋๋ค.
points
์ขํ๊ณ ๋จ์๋ points์
๋๋ค. ํฝ์
(pixel)์ด ์๋ ์ด์ ๋ ํฝ์
์ ๊ธฐ๊ธฐ์ ์คํฌ๋ฆฐ์ ๊ตฌ์ฑํ๋ ์์ ์ ์ธ๋ฐ ๊ฐ ๊ธฐ๊ธฐ์ ppi(Pixels Per Inch) ๊ฐ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์
๋๋ค. ๋ง์ฝ ๋ทฐ์ ์์น๋ ํฌ๊ธฐ๋ฅผ ํฝ์
๊ฐ์ผ๋ก ์ ์ํ๋ค๋ฉด ์์ดํฐ 12 pro(460 ppi) ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํด์ ๊ฐ๋ฐํ ์ฑ์ ์์ดํฐ 11(326 ppi)์์ ์คํํ์ ๋ ๋ทฐ์ ๋ณด์ด๋ ํฌ๊ธฐ๊ฐ ๋ฌ๋ผ์ง ๊ฒ๋๋ค.
bounds
UIView์๋ ์ง์ฌ๊ฐํ ์์ฑ์ ๋ํ๋ด๋ bounds ๋ณ์๊ฐ ์์ต๋๋ค. bounds๋ UIView๊ฐ ๊ทธ๋ ค์ง๋ ์ขํ๊ณ์ ์์ ๊ณผ ๋์ด ๋๋น๋ฅผ ์๋ ค์ฃผ๋ ๋ณ์์
๋๋ค.
var bounds: CGRect
Where is the UIView?
center ๋ณ์๊ฐ UIView์ ํด๋น ๋ทฐ์ superview์ ์ขํ๊ณ์ center ์ขํ๋ฅผ ๋ํ๋
๋๋ค.
frame ๋ณ์๋ superview ์ขํ๊ณ๋ฅผ ํฌํจํ๋ ์ง์ฌ๊ฐํ์ ๋ํ๋
๋๋ค.
var center: CGPoint
var frame: CGRect
bounds vs frame
bounds์ frame์ ํฌ๊ธฐ๋ ๊ฐ์ง ์์ต๋๋ค. ์๋์ฒ๋ผ View๊ฐ ํ์ ํ ๊ฒฝ์ฐ bounds์ ํฌ๊ธฐ๋ ๋ณํ์ง ์์ง๋ง frame์ ํฌ๊ธฐ๋ ๋ ์ปค์ง๊ฒ ๋ฉ๋๋ค.
Creating views
- ์คํ ๋ฆฌ๋ณด๋๋ฅผ ํ์ฉํ๋ ๋ฐฉ๋ฒ
(๊ฐ์์์๋ ์ด ๋ฐฉ๋ฒ์ ๋๋ถ๋ถ ํ์ฉํ๋ค๊ณ ํฉ๋๋ค.) - UIKit์ ํ์ฉํ ์ฝ๋๋ก ์์ฑํ๋ ๋ฐฉ๋ฒ
// Example
let labelRect = CGRect(x: 20, y: 20, width: 100, height: 50)
let label = UILabel(frame: labelRect) // UILabel is a subclass of UIView
label.text = “Hello”
view.addSubview(label)
Custom views
draw(_ rect: CGRect)๋ฅผ ์ฌ์ฉํด์ ์ปค์คํ
๋ทฐ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ํ์ง๋ง ์ง์ ํธ์ถํ์ง ์๊ณ ์๋์ ๋ ํจ์๋ฅผ ํตํด ๊ทธ๋ฆด ์ ์์ต๋๋ค.
- setNeedsDisplay()
- setNeedsDisplay(_ rect: CGRect)
Core Graphic Concept
- ๊ทธ๋ ค ๋ฃ์ ์ปจํ ์คํธ๊ฐ ์์ต๋๋ค(๋ค๋ฅธ ์ปจํ ์คํธ์๋ ์ธ์, ์คํ์คํฌ๋ฆฐ ๋ฒํผ ๋ฑ์ด ํฌํจ๋จ). UIGraphicsGetCurrentContext() ํจ์๋ ๊ทธ๋ฆฌ๊ธฐ(CGRect)์์ ์ฌ์ฉํ ์ ์๋ ์ปจํ ์คํธ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ๊ฒฝ๋ก ์์ฑ(out of lines, arcs ๋ฑ)
- ์์, ๊ธ๊ผด, ํ ์ค์ฒ, ๋ผ์ธ ํญ, ๋ผ์ธ์บก ๋ฑ๊ณผ ๊ฐ์ ๋๋ฉด ์์ฑ์ ์ค์ ํฉ๋๋ค
- ์์์ ๋ง๋ ๊ฒฝ๋ก๋ฅผ ์ง์ ๋ ์์ฑ์ผ๋ก ๊ฐ์กฐ ํ์ํ๊ฑฐ๋ ์ฑ์๋๋ค.
์ ์์์์ ๊ฒฝ๋ก์ ํด๋นํ๋ ๊ฒ์ด UIBezierPath ์ ๋๋ค. ์๋๋ UIBezierPath๋ฅผ ํ์ฉํด์ ์ผ๊ฐํ์ ๊ทธ๋ฆฌ๋ ๋ชจ์ต์ ๋๋ค.
let path = UIBezierPath()
path.move(to: CGPoint(80, 50))
path.addLine(to: CGPoint(140, 150))
path.addLine(to: CGPoint(10, 150))
path.close()
Drawing Text
- Character ๐ ๋ฌธ์
- String ๐ Character๋ก ์ด๋ฃจ์ด์ง ์ฝ๋ ์
- NSAttributedString ๐ ํ ์คํธ ์คํ์ผ, ํ์ดํผ๋งํฌ, ๋ฐ์ดํฐ ๋ฑ์ ์์ฑ์ ๊ฐ์ง ์ ์๋ ๋ฌธ์์ด ํด๋์ค
- NSMutableAttributedString ๐ NSAttributedString์ ์ปจํ ์ธ ๋ฅผ ๋ณํ์ํฌ ์ ์๋ ๋ฉ์๋๊ฐ ์ถ๊ฐ๋ ํด๋์ค
// NSAttributedString
let text = NSAttributedString(string: “hello”)
text.draw(at: aCGPoint)
let textSize: CGSize = text.size
// NSMutableAttributedString
let pizzaJoint = “café pesto”
var attrString = NSMutableAttributedString(string: pizzaJoint)
let firstWordRange = pizzaJoint.startIndex..<pizzaJoint.indexOf(“ “)!
let nsrange = NSRange(firstWordRange, in: pizzaJoint)
attrString.addAttribute(.strokeColor, value: UIColor.orange, range: nsrange)
Drawing Images
UIImageView ๋ฅผ ์ฌ์ฉํด์ ์ด๋ฏธ์ง๋ฅผ ๊ทธ๋ฆด ์ ์์ต๋๋ค. ์ด๋ฏธ์ง๋ ํ๋ก์ ํธ ๋ด์ Assets.xcassets ํ์ผ์ ์๋ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ๋ค ์ธ ์ ์์ต๋๋ค.
// Assets.xcassets ํ์ผ ์์
// "foo" ์ฌ์ง์ ์ฐพ์์ UIImage์ ๋ฃ์ด์ค๋๋ค
let image: UIImage? = UIImage(named: "foo")
์ฌ์ง์ ํด์๋๋ ๊ฐ ๊ธฐ๊ธฐ์ ํด์๋์ ๋ง์ถฐ์ ์กฐ์ ํ ์ ์์ต๋๋ค. 1x 2x 3x ์ด๋ฏธ์ง๋ฅผ ๋ฐ๋ก ์ค์ ํด์ค ์ ์๊ณ , 1๊ฐ์ ์ต์ ์๋ง ์ด๋ฏธ์ง๊ฐ ์ค์ ๋์ด์๋ค๋ฉด ๋๋จธ์ง ์ต์ ์ ํด๋น ์ด๋ฏธ์ง๊ฐ ์๋์ผ๋ก ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
Assets.xcassets ๋ง๊ณ ํ์ผ ์์คํ ์์ ์ง์ ๋ถ๋ฌ์ค๋ ๋ฐฉ๋ฒ๋ ์๊ณ , ์ด๋ฏธ์ง ๋ฐ์ดํฐ๋ฅผ ์ง์ ๋ฃ์ด์ฃผ๋ ๋ฐฉ๋ฒ๋ ์์ต๋๋ค. ํ์ง๋ง ์ด ๊ฐ์์์๋ ํ์ผ ์์คํ ์ ํตํ ์ด๋ฏธ์ง ์ฝ์ ์ ํ์ง ์์ต๋๋ค.
let image: UIImage? = UIImage(contentsOfFile: pathString)
let image: UIImage? = UIImage(data: aData) // raw jpg, png, tiff, etc. image data
Redraw on bounds change
iOS์์๋ ๋ทฐ์ ๊ฒฝ๊ณ๊ฐ ๋ฐ๋์์ ๋ ์๋ก ๋๋ก์ ํ์ง ์์ต๋๋ค. ๊ทธ๋์ ํ๋ฉด์ด ํ์ ๋๊ฑฐ๋ ๋ทฐ์ ์์์ ํฌ๊ธฐ๊ฐ ๋ณํ์ ๋ ๋ฐ๋ก ์ฒ๋ฆฌํด์ค์ผ ํฉ๋๋ค. contentMode ๋ณ์๋ฅผ ํ์ฉํด์ ์ฒ๋ฆฌ๋ฅผ ํด์ค ์ ์์ต๋๋ค.
var contentMode: UIViewContentMode
contentMode๋ ๋ทฐ๊ฐ ์ด๋ค ์ข
๋ฅ์ ์ปจํ
์ธต๋ฅผ ๊ฐ๊ณ ์๋์ง ๋ํ๋
๋๋ค. ๋ญ๊ฐ์ ธ๋ ๋๋์ง, ๊ฒฝ๊ณ๊ฐ ๋ฐ๋์์ ๋ ์๋ก ๋๋ก์์ ํ๋์ง ๋ฑ์ ์ ์ ์์ต๋๋ค.
- Don't scale the view ๐ ์๋ก ๋๋ก์ ํ์ง ์๊ณ ๋นํธ๋ง ์์ง์ ๋๋ค. (๊ฑฐ์ ์์ด๋ค๊ณ ํฉ๋๋ค.)
- Scale the bits of the view ๐ ๋นํธ๋ฅผ ๋์ด๊ฑฐ๋ ์ค์ฌ์ ์๋ก์ด ๊ฒฝ๊ณ์ ๋ง์ถฅ๋๋ค.
- Redraw by calling draw(CGRect) ๐ ๋ทฐ๋ฅผ ๋ค์ ๊ทธ๋ฆฝ๋๋ค.
Layout on bounds change
์๋ธ ๋ทฐ๊ฐ ์๋๋ฐ ๊ฒฝ๊ณ๊ฐ ๋ฐ๋์์ ๋๋ ๋ณดํต Autolayout constraints๋ฅผ ํ์ฉํ๊ฑฐ๋ layoutSubviews() ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ ํด์ ์ฌ์ฉํฉ๋๋ค. layoutSubviews() ๋ฉ์๋๋ฅผ ํ์ฉํ ๋ ๊ผญ super.layoutSubviews()๋ฅผ ์์ง ์๊ณ ๊ฐ์ด ์จ์ค์ผ ํฉ๋๋ค.
override func layoutSubviews() {
super.layoutSubviews()
// ์๋ธ ๋ทฐ์ ์์น๋ฅผ ์๋ก์ด ๊ฒฝ๊ณ๋ฅผ ๋ฐ๋ผ์ ์ฌ๋ฐฐ์น ํ๋ค.
}
์ฐธ๊ณ ์๋ฃ
'CS193P' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS] ์คํ ํฌ๋ CS193P 7๊ฐ (0) | 2021.09.01 |
---|---|
[iOS] ์คํ ํฌ๋ CS193P 6๊ฐ (0) | 2021.08.31 |
[iOS] ์คํ ํฌ๋ CS193P 5๊ฐ - 1 (0) | 2021.08.20 |
[iOS] ์คํ ํฌ๋ CS193P 4๊ฐ (0) | 2021.08.18 |
[iOS] ์คํ ํฌ๋ CS193P 3๊ฐ (0) | 2021.08.18 |