Skip to content

Latest commit

Β 

History

History
184 lines (150 loc) Β· 9.75 KB

File metadata and controls

184 lines (150 loc) Β· 9.75 KB

이 글은 Bob the Developer 의 Protocol Oriented Programming View in Swift3 에 λŒ€ν•œ λ²ˆμ—­μž…λ‹ˆλ‹€.

Swift3μ—μ„œ Protocol Oriented Programming 으둜 λ§Œλ“  View

λ§Žμ€ 클래슀λ₯Ό λ§Œλ“€μ§€ μ•ŠμœΌλ©΄μ„œ button, label, imageView 듀을 μ‚΄μ•„ μ›€μ§μ΄κ²Œ ν•˜λŠ”(animate) 방법을 λ°°μ›λ‹ˆλ‹€.

POPλ₯Ό λ°°μš°λŠ” 것은 백과사전/λΈ”λ‘œκ·Έμ—μ„œ 보물을 μ°ΎλŠ” 것과 κ°™μŠ΅λ‹ˆλ‹€.

2017λ…„ 3μ›” 20일 μ΅œμ’… 갱신됨.

μ‹€μ²œμ΄ μ—†λŠ” 지식은 이빨이 μžˆμ§€λ§Œ 우유만 λ§ˆμ‹œλŠ” 것과 κ°™λ‹€λŠ” 말을 λ“€μ–΄ 보셨을 κ²λ‹ˆλ‹€.
μ—¬λŸ¬λΆ„μ€ "μ’‹μŠ΅λ‹ˆλ‹€. 이둠은 μΆ©λΆ„ν•©λ‹ˆλ‹€. μ•±μ—μ„œ μ–΄λ–»κ²Œ POPλ₯Ό μ‹œμž‘ν•  수 있죠?" πŸ€” 라고 λ¬ΌμœΌμ‹€ κ²λ‹ˆλ‹€.

μ €λŠ” μ—¬λŸ¬λΆ„μ΄ Completion Handlers λ₯Ό μΆ©λΆ„νžˆ μ΄ν•΄ν•˜κ³  있으며, Protocol 을 μ΄μš©ν•΄μ„œ 기초적인 κ΅¬ν˜„μ„ ν•˜μ‹€ 수 μžˆλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€. Β  λ§Œμ•½ 이런 것듀과 μΉœμˆ™ν•˜μ§€ μ•ŠμœΌμ‹œλ‹€λ©΄, μ•„λž˜μ˜ μ €μ˜ κΈ€λ“€κ³Ό λ™μ˜μƒλ“€μ„ 보고 μ˜€μ‹œκΈ°λ₯Ό μ •μ€‘νžˆ μš”μ²­λ“œλ¦½λ‹ˆλ‹€.

사전 ν•„μˆ˜ 사항:

Clojure κ±±μ • μ—†μ–΄μš” 파트 2:Completion Handlers (Medium)
Protocol Oriented Programming 에 λŒ€ν•œ μ†Œκ°œ(Medium)
Protocol Oriented Protocol μ‹œλ¦¬μ¦ˆ (YouTube )

배우게 될 것

μ—¬λŸ¬λΆ„μ€ UIButton, UILabel 그리고 UIImageView 와 같은 UI μ»΄ν¬λ„ŒνŠΈλ“€μ„ μ‚΄μ•„ μ›€μ§μ΄κ²Œ ν•˜κΈ°(animate) μœ„ν•΄μ„œ Protocol 을 μ‚¬μš©ν•˜λŠ” 방법을 배울 κ²λ‹ˆλ‹€. μ €λŠ” 전톡적인 방법듀 κ³Ό POP λ°©μ‹μ˜ 차이점을 λ³΄μ—¬λ“œλ¦΄ κ²λ‹ˆλ‹€.

UI

demo 앱은 "우리 μ§‘ νŒŒν‹°μ— μ˜€μ‹  κ±Έ ν™˜μ˜ν•©λ‹ˆλ‹€."("Welcome to My House Party")라고 λΆˆλ¦½λ‹ˆλ‹€. μ €λŠ” 이앱을 μ œκ°€ μ—¬λŸ¬λΆ„μ„ 저희 μ§‘ νŒŒν‹°μ— μ΄ˆλŒ€ν–ˆλŠ”μ§€ μ•„λ‹Œμ§€λ₯Ό ν™•μΈν•˜κΈ° μœ„ν•΄μ„œ 이 앱을 λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€. μ—¬λŸ¬λΆ„μ€ μ΄ˆλŒ€ μ½”λ“œλ₯Ό μž…λ ₯ν•˜μ…”μ•Ό ν•©λ‹ˆλ‹€. 이 μ•±μ—λŠ” 둜직이 μ—†μŠ΅λ‹ˆλ‹€. λ§Œμ•½ μ—¬λŸ¬λΆ„μ΄ λ²„νŠΌμ„ λˆ„λ₯΄μ‹ λ‹€λ©΄, κ·ΈλŸΌμ—λ„ λΆˆκ΅¬ν•˜κ³  μ‚΄μ•„ 움직일(animate) κ²ƒμž…λ‹ˆλ‹€. μ›€μ§μ΄λŠ” 4개의 μ»΄ν¬λ„ŒνŠΈκ°€ μžˆμŠ΅λ‹ˆλ‹€. passcodeTextField, loginButton, errorMessageLabel 그리고 profileImageView.

두가지 μ• λ‹ˆλ©”μ΄μ…˜μ΄ μžˆμŠ΅λ‹ˆλ‹€.: 1.λΉ λ₯΄κ²Œ μ§„λ™ν•˜κΈ°(Buzzing) 2.νŠ€μ–΄λ‚˜μ˜€κΈ°(Poping(Flash))

μ™„μ„±λœ ν”„λ‘œμ νŠΈ

λ‚΄λ € λ†“λŠ” 것에 λŒ€ν•΄μ„œ κ±±μ •ν•˜μ§€ λ§ˆμ„Έμš”. λ‹Ήμž₯ 저와 ν•¨κ»˜ κ·Έλƒ₯ 물처럼 흐λ₯΄μ„Έμš”. λ§Œμ•½ μ—¬λŸ¬λΆ„μ΄ 참을성이 μ—†μœΌμ‹œλ‹€λ©΄, κ·Έλƒ₯ μŠ€ν¬λ‘€ν•˜κ³  μ†ŒμŠ€ μ½”λ“œλ₯Ό λ‹€μš΄λ‘œλ“œ λ°›μœΌμ‹œκ³  κ·Έλƒ₯ λ¬΄μ‹œν•˜μ‹€ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

λ’€λ‘œ λŒμ•„ κ°€ λ΄…μ‹œλ‹€.

μ‹€μ œ μ•±μ—μ„œμ˜ POP의 νž˜μ„ μ™„μ „νžˆ νŒŒμ•…ν•˜κΈ° μœ„ν•΄μ„œ, 정톡적인 방법과 λΉ„κ΅ν•΄λ΄…μ‹œλ‹€. μ—¬λŸ¬λΆ„μ΄ UIButton κ³Ό UILabel 을 μ‚΄μ•„ μ›€μ§ν•˜κ²Œ(animate) ν•˜κ³  μ‹Άλ‹€κ³  ν•©μ‹œλ‹€. 두 클래슀λ₯Ό μƒμ†ν•˜κ³  그것에 λ©”μ†Œλ“œλ₯Ό μΆ”κ°€ν•  μˆ˜λ„ μžˆμ„ κ²λ‹ˆλ‹€.

class BuzzableButton: UIButton {
 func buzz() { // Animation Logic }
}
class BuzzableLabel: UIButton {
 func buzz() { // Animation Logic }
}

그럼, 둜그인 λ²„νŠΌμ— νƒ­ν•  λ•Œ μ§„λ™ν•˜κ²Œ("buzz") ν•©μ‹œλ‹€.

@IBOutlet wear var errorMessageLabel: BuzzableButton!
@IBOutlet wear var loginButton: BuzzableLabel!
@IBAction func didTapLoginButton(_ sender: UIButton) {
 errorMessageLabel.buzz()
 loginButton.buzz()
}

μš°λ¦¬κ°€ λ°˜λ³΅ν•˜κ³  μžˆλŠ” 것을 μ•Œ 수 μžˆμœΌμ‹  κ°€μš”? μ• λ‹ˆλ©”μ΄μ…˜ λ‘œμ§μ€ μ΅œμ†Œν•œ 5μ€„μž…λ‹ˆλ‹€. 그리고 extension 을 μ΄μš©ν•˜λŠ” "더 λ‚˜μ€" 방법이 μžˆμŠ΅λ‹ˆλ‹€. UILabel κ³Ό UIButton 은 UIView 에 μ†ν•˜κΈ° λ•Œλ¬Έμ—, λ‹€μŒμ„ μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

extension UIView {
 func buzz() { // Animation Logic }
}

κ·Έλž˜μ„œ, BuzzableButton κ³Ό BuzzableLabel λŠ” buzz λ₯Ό ν¬ν•¨ν•©λ‹ˆλ‹€. 이제, μš°λ¦¬λŠ” 더이상 λ°˜λ³΅ν•˜μ§€ μ•Šμ•„λ„ λ©λ‹ˆλ‹€.

class BuzzableButton: UIButton {}
class BuzzableLabel: UIButton {}
@IBOutlet wear var errorMessageLabel: BuzzableButton!
@IBOutlet wear var loginButton: BuzzableLabel!
@IBAction func didTapLoginButton(_ sender: UIButton) {
 errorMessageLabel.buzz()
 loginButton.buzz()
}

μ’‹μŠ΅λ‹ˆλ‹€. 그러면 POPλŠ” μ™œ? πŸ€”

λ³΄μ…¨λ˜ 것과 같이, "μœ νš¨ν•œ μ½”λ“œλ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”"("Please enter valid code πŸ˜‚") 라고 λ§ν•˜λŠ” errorMessageLabel 은 λ˜ν•œ μ• λ‹ˆλ©”μ΄μ…˜μ΄ ν•œκ°€μ§€ 더 μžˆμŠ΅λ‹ˆλ‹€. λ‚˜νƒ€λ‚¬λ‹€κ°€ μ‚¬λΌμ§‘λ‹ˆλ‹€. κ·Έλž˜μ„œ 전톡적인 λ°©λ²•μœΌλ‘œλŠ” μ–΄λ–»κ²Œ ν•˜λ‚˜μš”?

이것에 λŒ€ν•΄μ„œλŠ” 두가지 방법이 μžˆμŠ΅λ‹ˆλ‹€. λ¨Όμ €, λ‹€μ‹œ UIView 에 λ‹€λ₯Έ λ©”μ†Œλ“œλ₯Ό μΆ”κ°€ν•΄ μ£Όμ„Έμš”.

// Extend UIView
extension UIView {
 func buzz() { // Animation Logic }
 func pop() { // UILabel Animation Logic }
}

ν•˜μ§€λ§Œ, λ§Œμ•½ UIView에 λ©”μ†Œλ“œλ₯Ό μΆ”κ°€ν•˜λ©΄, pop λ©”μ†Œλ“œκ°€ UILabel λ₯Ό ν¬ν•¨ν•œ λ‹€λ₯Έ UIComponent듀에도 κ°€λŠ₯ν•˜κ²Œ 될 κ²λ‹ˆλ‹€. λΆˆν•„μš”ν•œ ν•¨μˆ˜λ₯Ό μƒμ†ν•˜κ²Œ λ©λ‹ˆλ‹€. 그리고 UIComponent듀이 기본적으둜 λΉ„λŒ€ν•΄μ§‘λ‹ˆλ‹€.

λ‘λ²ˆμ§Έ 방법은 UILabel 을 상속(Subclass)ν•˜λŠ” κ²λ‹ˆλ‹€.

// Subclass UILabel
class BuzzableLabel: UILabel {
 func pop() { // UILabel Animation Logic }  
}

잘 μž‘λ™ν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ, 이름을 λ³΄λŠ” κ²ƒλ§ŒμœΌλ‘œλ„ μ–΄λ–€ ν΄λž˜μŠ€μΈμ§€ μ•Œμˆ˜ μžˆλ„λ‘, class 이름을 BuzzablePoppableLabel 둜 λ°”κΎΈκ³  싢을 수 μžˆμŠ΅λ‹ˆλ‹€.

이제, label이 무엇을 ν•˜λŠ”μ§€ λͺ…ν™•νžˆ ν•˜κΈ° μœ„ν•΄μ„œ UILabel 에 λ©”μ†Œλ“œλ₯Ό ν•˜λ‚˜ 더 μΆ”κ°€ ν•˜κ³  μ‹Άλ‹€λ©΄, class 이름을 BuzzablePoppableFlashableDopeFancyLovelyLabel 같은 κ²ƒμœΌλ‘œ λ³€κ²½ν•΄μ•Ό 할지도 λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€. 이것 지속 κ°€λŠ₯ν•œ 방법이 μ•„λ‹™λ‹ˆλ‹€. λ¬Όλ‘ , λ„ˆλ¬΄ 멀리 κ°€κΈ΄ ν–ˆμŠ΅λ‹ˆλ‹€.

ν”„λ‘œν† μ½œ μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ°(Protocol Oriented Programming)

μ’‹μŠ΅λ‹ˆλ‹€. 상속(subclassing)은 μΆ©λΆ„ν•©λ‹ˆλ‹€. Protocol λΆ€ν„° λ§Œλ“€μ–΄ λ΄…μ‹œλ‹€. λΉ λ₯΄κ²Œ μ§„λ™ν•˜κΈ°(Buzzing) λ¨Όμ €.

μ• λ‹ˆλ©”μ΄μ…˜μ„ μœ„ν•œ μ½”λ“œλŠ” 쾌 κΈΈκ³  λͺ¨λ°”일 μ•±μ—μ„œ μ„ μ²œμ μœΌλ‘œ μ§€μ›λ˜λŠ” 것이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— λ„£μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

protocol Buzzable {}
extension Buzzable where Self: UIView {
 func buzz() { // Animation Logic}
}

그럼 이제, Buzzable protocol을 μ€€μˆ˜ν•˜λŠ”(conform) UIComponent듀은 μ—°κ΄€λœ buzz λ©”μ†Œλ“œλ₯Ό κ°€μ§€κ²Œ 될 κ²λ‹ˆλ‹€. extension κ³Ό λ‹€λ₯΄κ²Œ(extension UIView 둜 λ©”μ†Œλ“œλ₯Ό μΆ”κ°€ν•˜λŠ” κ²ƒκ³ΌλŠ” λ‹€λ₯΄κ²Œ) 이 protocol을 μ€€μˆ˜ν•˜λŠ”(conform) κ²ƒλ“€λ§Œ 이 λ©”μ†Œλ“œλ₯Ό κ°€μ§€κ²Œ 될 κ²λ‹ˆλ‹€. λ˜ν•œ, where Self: UIView λŠ” 이 protocol 이 <'UIView 둜 λΆ€ν„° μƒμ†λœ μ»΄ν¬λ„ŒνŠΈ' ν˜Ήμ€ 'UIView'>에 λŒ€ν•΄μ„œλ§Œ μ€€μˆ˜λ˜μ–΄μ•Ό(conformed)ν•œλ‹€λŠ” 것을 λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄μ„œ μ‚¬μš©ν•©λ‹ˆλ‹€.

자, κ·Έκ²λ‹ˆλ‹€. Buzzable 을 loginButton, passcodeTextField, errorMessageLabel 그리고 profileImageView 에 μ μš©ν•©μ‹œλ‹€. ν•˜μ§€λ§Œ, μž μ‹œλ§Œ κΈ°λ‹€λ¦¬μ„Έμš”. Poppable은 μ–΄λ–€κ°€μš”?

λ„€, λ˜‘κ°™μŠ΅λ‹ˆλ‹€.

protocol Poppable {}
extension Poppable where Self: UIView {
 func pop() { // Pop Animation Logic }
}

이제 ν˜„μ‹€λ‘œ λ§Œλ“€ μ‹œκ°„μž…λ‹ˆλ‹€.

class BuzzableTextField: UITextField, Buzzable {}
class BuzzableButton: UIButton, Buzzable {}
class BuzzableImageView: UIImageView, Buzzable {}
class BuzzablePoppableLabel: UILabel, Buzzable, Poppable {}

class LoginViewController: UIViewController {
  @IBOutlet weak var passcodTextField: BuzzableTextField!
  @IBOutlet weak var loginButton: BuzzableButton!
  @IBOutlet weak var errorMessageLabel: BuzzablePoppableLabel!
  @IBOutlet weak var profileImageView: BuzzableImageView!

  @IBAction func didTabLoginButton(_ sender: UIButton) {
    passcodTextField.buzz()
    loginButton.buzz()
    errorMessageLabel.buzz()
    errorMessageLabel.pop()
    profileImageView.buzz()
  }
}

POPμ—μ„œ 쒋은 점은 상속 없이도 λ‹€λ₯Έ UIComponent에 pop 을 μΆ”κ°€ν•  수 μžˆλ‹€λŠ” μ μž…λ‹ˆλ‹€.

class MyImageView: UIImageVIew, Buzzable, Poppable

이제, μ€€μˆ˜ν•˜λŠ” protocol듀에 κΈ°λ°˜ν•œ κ°€λŠ₯ν•œ λ©”μ†Œλ“œλ“€κ³Ό 클래슀λ₯Ό μ„€λͺ…ν•˜λŠ” 각각의 protocol 의 이름을 이미 μ•ŒκΈ° λ•Œλ¬Έμ—, class 이름이 μ’€ 더 μœ μ—°ν•΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

μš”μ•½

더이상 ν•„μš”μ—†λŠ” 상속(Subclass)

μœ μ—°ν•œ 클래슀 이름

Swift κ°œλ°œμžλ‘œμ„œ 따라 μž‘μ€ λŠλ‚Œ.

λ‹€μŒ 단계

이 글이 200개의 μ’‹μ•„μš”λ₯Ό λ°›κ³  μ—¬λŸ¬λΆ„μ΄ POPλ₯Ό UITableView 와 UICollectionView에 μ μš©ν•˜λŠ” 방법을 배우기λ₯Ό μ›ν•˜μ‹ λ‹€λ©΄, Mediumμ—μ„œ μ €λ₯Ό νŒ”λ‘œμš°ν•΄μ£Όμ„Έμš”!

μ΅œν›„ λ°œμ–Έ

μ—¬λŸ¬λΆ„μ΄ λ­”κ°€ μƒˆλ‘œμš΄ 것을 λ°°μš°μ…¨κΈ°λ₯Ό λ°”λžλ‹ˆλ‹€. κ·Έλ ‡λ‹€λ©΄, κΈμ •μ˜ ν‘œμ‹œλ‘œ ❀️ λ₯Ό νƒ­ν•΄μ£Όμ„Έμš”. 이 κ΅¬ν˜„μ΄ μœ μš©ν•˜μ…¨λ‹€λ©΄, μ „ μ„Έκ³„μ˜ iOS κ°œλ°œμžλ“€μ΄ Protocol Oriented View 듀을 ν•˜λ„λ‘ κ³΅μœ ν•΄μ£Όμ„Έμš”. Protocol Oriented View 듀은 μ½”λ“œλ₯Ό 더 κ°„κ²°ν•˜κ²Œ ν•˜λ©΄μ„œ, λͺ¨λ“ˆν™” ν•  수 있게 ν•©λ‹ˆλ‹€. ν† μš”μΌ λ°€ 8μ‹œ(λ―Έκ΅­ 동뢀 ν‘œμ€€μ‹œ)에 λ‹€μ‹œ λ΄μš”! 더 많이 배우고 μ‹Άκ³ , 더 많이 λ°›κ³  μ‹ΆμœΌμ‹œλ‹€λ©΄, μ—¬κΈ° μ €μ˜ 메일링 λ¦¬μŠ€νŠΈμ— κ°€μž…ν•˜μ„Έμš”.

μžλ£Œλ“€

μ†ŒμŠ€ μ½”λ“œ

iOS 개발자λ₯Ό μœ„ν•œ 자료 νŽ˜μ΄μ§€

κ°μ‚¬ν•©λ‹ˆλ‹€.