๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽ iOS/UI

[iOS/UI] ํŠน์ • ๋ถ€๋ถ„๋งŒ ํˆฌ๋ช…ํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ (feat. fillRule, evenOdd)

by Fomagran ๐Ÿ’ป 2022. 7. 31.
728x90
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š” Foma ์ž…๋‹ˆ๋‹ค!

์˜ค๋Š˜์€ ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ์ค‘์— ํŠน์ • ๋ถ€๋ถ„๋งŒ ํˆฌ๋ช…ํ•˜๊ฒŒ ํ•ด์„œ ๊ทธ ๋ถ€๋ถ„๋งŒ ๋ณด์ด๊ฒŒ ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋งŒ๋“œ๋Š” ๋ฒ•์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด ๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ฒŒ์š”~


Preview

 


Add a label

 

๋ฐฐ๊ฒฝ์— ๋ ˆ์ด๋ธ”์„ ํ•˜๋‚˜ ๋„ฃ์–ด ํˆฌ๋ช…ํ•œ์ง€ ์•„๋‹Œ์ง€ ํ™•์ธํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด ์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

        let label = UILabel(frame: CGRect(x: view.center.x - 100, y: view.center.y - 100, width: 200, height: 200))
        label.backgroundColor = .systemBlue
        label.textColor = .white
        label.font = UIFont.boldSystemFont(ofSize: 20)
        label.text = "Fomagran"
        label.textAlignment = .center
        label.layer.cornerRadius = 100
        label.layer.masksToBounds = true
        view.addSubview(label)

 

์•„๋ž˜์™€ ๊ฐ™์ด ๋ ˆ์ด๋ธ”์ด ์ถ”๊ฐ€๋  ๊ฑฐ์—์š”.

 


Add a backgroundView

 

๋ฐ˜ํˆฌ๋ช…ํ•œ ๋ฐฐ๊ฒฝ์ƒ‰์ด ๋  backgroundView๋ฅผ ์ถ”๊ฐ€ํ•ด ์ค๋‹ˆ๋‹ค.

 

        let backgroundView = UIView(frame: view.frame)
        backgroundView.backgroundColor = .black.withAlphaComponent(0.6)
        view.addSubview(backgroundView)

 

์•„๋ž˜์™€ ๊ฐ™์ด ๋ฐ˜ํˆฌ๋ช…ํ•œ ๋ทฐ๊ฐ€ ๋ ˆ์ด๋ธ” ์œ„๋ฅผ ๋ฎ๊ฒ ์ฃ ?

 


Set a maskLayer's path

 

์œ„์—์„œ ๋งŒ๋“  backgroundView์˜ mask๊ฐ€ ๋  CAShapeLayer๋ฅผ ๋งŒ๋“ค์–ด ์ค„๊ฑฐ์—์š”.

 

        let maskLayer = CAShapeLayer()

 

์œ„ ๋ ˆ์ด์–ด๋ฅผ ๋งŒ๋“  ์ด์œ ๋Š” ์ง์ ‘ UIBezierPath๋ฅผ ๊ทธ๋ ค ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

 

์ด 2๊ฐœ์˜ Path๋ฅผ ๊ทธ๋ ค์ค„๊ฑด๋ฐ์š”.

 

ํ•˜๋‚˜๋Š” backgroundView์™€ ๊ฐ™์€ ํฌ๊ธฐ์™€ ์œ„์น˜์— ์žˆ๋Š” backgroundPath๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ๊ณ ,

 

        let backgroundPath = UIBezierPath(rect: view.frame)

 

ํ•˜๋‚˜๋Š” ํˆฌ๋ช…ํ•œ ๋ถ€๋ถ„์˜ ๋ชจ์–‘์ด ๋  transparentPath๋ฅผ ๊ทธ๋ ค์ค„๊ฑฐ์—์š”.

 

(ํ˜น์‹œ EasierPath๋ฅผ ๋ชจ๋ฅด์‹œ๋Š” ๋ถ„๋“ค์€ ์—ฌ๊ธฐ ์—์„œ ํ™•์ธํ•ด ์ฃผ์„ธ์š”!)

 

        let transparentPath = EasierPath(view.center.x-50,view.center.y-100)
        transparentPath.right(100)
        transparentPath.down(200)
        transparentPath.left(100)
        transparentPath.up(200)

 

backgroundPath์— transparentPath๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ๊ณ , maskLayer์˜ path๋ฅผ backgroundPath๋กœ ์ง€์ •ํ•ด ์ค๋‹ˆ๋‹ค.

 

        backgroundPath.append(transparentPath.path)
        maskLayer.path = backgroundPath.cgPath

 

๊ทธ๋ฆฌ๊ณ  backgroundView์˜ ๋ ˆ์ด์–ด์˜ mask๋ฅผ maskLayer๋กœ ๋ฎ์–ด์ฃผ์„ธ์š”.

 

        backgroundView.layer.mask = maskLayer

 

๊ทธ๋ฆฌ๊ณ  ์‹คํ–‰์‹œ์ผœ ๋ณด๋ฉด? ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

์™œ๋ƒํ•˜๋ฉด backgroundPath์— transparenthPath๊ฐ€ ๊ฒน์ณ์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

 



Set a fillRule to evenOdd

 

์œ„์—์„œ backgroundPath์™€ transparentPath๊ฐ€ ๊ฒน์ณ์ ธ ์žˆ๋‹ค๊ณ  ํ–ˆ์ฃ ?

 

ํŠน์ • ๊ฒฝ๋กœ๊ฐ€ ๊ฒน์ณ์ง€๋Š” ๊ณณ์„ ์ œ์™ธํ•˜๊ณ  ์ƒ‰์ด ์ฑ„์›Œ์งˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ์š”.

 

๋ฐ”๋กœ fillRule์„ .evenOdd๋กœ ํ•ด์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

        maskLayer.path = backgroundPath.cgPath
        maskLayer.fillRule = .evenOdd
        backgroundView.layer.mask = maskLayer

 

๊ทธ๋ฆฌ๊ณ  ์‹คํ–‰ํ•ด ๋ณด๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๋ชจ์–‘๋งŒ ํˆฌ๋ช…ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 


What is a evenOdd?

 

๊ทธ๋ ‡๋‹ค๋ฉด fillRule์— evenOdd๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?

 

๊ณต์‹ ๋ฌธ์„œ์—” evenOdd๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค๋ช…ํ•˜๊ณ  ์žˆ์–ด์š”.

 

 

๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด์„ํ•˜๋ฉด ๊ฒน์น˜๋Š” ๋ถ€๋ถ„์˜ ์ด ์ˆ˜๋ฅผ ์„ธ๊ณ , ๋งŒ์•ฝ ๊ทธ ์ˆ˜๊ฐ€ ์ง์ˆ˜์ด๋ฉด ์™ธ๋ถ€๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ ์ด ์ˆ˜๊ฐ€ ํ™€์ˆ˜์ด๋ฉด ๋‚ด๋ถ€๋ฅผ ๋œปํ•˜๋ฉฐ ํ•ด๋‹น ์˜์—ญ์„ ์ฑ„์›Œ์•ผ ํ•˜๋Š” ๊ฒƒ์ธ๋ฐ์š”.

 

์ด๋ ‡๊ฒŒ ๋งํ•˜๋‹ˆ ์ข€ ์ดํ•ด๊ฐ€ ํž˜๋“œ์‹ค ๊ฒƒ ๊ฐ™์•„ ์‰ฝ๊ฒŒ ์„ค๋ช…๋“œ๋ฆฌ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด A,B๊ฐ€ ์žˆ๊ณ  ๊ฐ ์ง€์ ๋งˆ๋‹ค ๊ฒน์นœ ๋ถ€๋ถ„(1)์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

 

๋งŒ์•ฝ ๋‘ A,B ๊ตฌ๊ฐ„์ด ๊ฒน์นœ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฒน์นœ ๋ถ€๋ถ„์ด 2๊ฐ€ ๋˜๊ณ  ํ•ด๋‹น ๋ถ€๋ถ„์€ ์ง์ˆ˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

 

๊ณ ๋กœ ์ง์ˆ˜๊ฐ€ ๋œ ๋ถ€๋ถ„์€ ์™ธ๋ถ€ ์˜์—ญ์œผ๋กœ ์˜๋ฏธํ•˜์—ฌ ์ฑ„์šฐ์ง€ ์•Š์•„๋„ ๋˜๋Š” ๊ทœ์น™์„ ๋œปํ•˜๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

 


์˜ค๋Š˜์€ ์ด๋ ‡๊ฒŒ CAShapeLayer์˜ ์ฑ„์šฐ๊ธฐ ๊ทœ์น™(fillRule)์˜ oddEven์„ ์ด์šฉํ•˜์—ฌ ์›ํ•˜๋Š” ๋ถ€๋ถ„๋งŒ ํˆฌ๋ช…ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

 

ํ˜น์‹œ๋ผ๋„ ๊ถ๊ธˆํ•˜์‹  ์ ์ด๋‚˜ ํ‹€๋ฆฐ ์ ์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์„ธ์š”!

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€