CS193P

[iOS] ์Šคํƒ ํฌ๋“œ CS193P 5๊ฐ• - 2

Beck 2021. 8. 20. 19:39

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)

CGRect ์ดˆ๊ธฐํ™” ๋ฐฉ๋ฒ•


 

๋ทฐ ์ขŒํ‘œ ์‹œ์Šคํ…œ (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์˜ ํฌ๊ธฐ๋Š” ๋” ์ปค์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

view๊ฐ€ ํšŒ์ „ํ•  ๋•Œ 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

  1. ๊ทธ๋ ค ๋„ฃ์„ ์ปจํ…์ŠคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(๋‹ค๋ฅธ ์ปจํ…์ŠคํŠธ์—๋Š” ์ธ์‡„, ์˜คํ”„์Šคํฌ๋ฆฐ ๋ฒ„ํผ ๋“ฑ์ด ํฌํ•จ๋จ). UIGraphicsGetCurrentContext() ํ•จ์ˆ˜๋Š” ๊ทธ๋ฆฌ๊ธฐ(CGRect)์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ปจํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ฒฝ๋กœ ์ƒ์„ฑ(out of lines, arcs ๋“ฑ)
  3. ์ƒ‰์ƒ, ๊ธ€๊ผด, ํ…์Šค์ฒ˜, ๋ผ์ธ ํญ, ๋ผ์ธ์บก ๋“ฑ๊ณผ ๊ฐ™์€ ๋„๋ฉด ์†์„ฑ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค
  4. ์œ„์—์„œ ๋งŒ๋“  ๊ฒฝ๋กœ๋ฅผ ์ง€์ •๋œ ์†์„ฑ์œผ๋กœ ๊ฐ•์กฐ ํ‘œ์‹œํ•˜๊ฑฐ๋‚˜ ์ฑ„์›๋‹ˆ๋‹ค.

์œ„ ์ˆœ์„œ์—์„œ ๊ฒฝ๋กœ์— ํ•ด๋‹นํ•˜๋Š” ๊ฒƒ์ด 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()
	// ์„œ๋ธŒ ๋ทฐ์˜ ์œ„์น˜๋ฅผ ์ƒˆ๋กœ์šด ๊ฒฝ๊ณ„๋ฅผ ๋”ฐ๋ผ์„œ ์žฌ๋ฐฐ์น˜ ํ•œ๋‹ค.
}

 

์ฐธ๊ณ ์ž๋ฃŒ