[Swift UI] View / Someμ΄λž€? / ContentView / Previews

2022. 6. 16. 18:05ㆍProgramming/Swift

 

[ κΉ¨μ•Œ κΆκΈˆμ¦λ“€ 🧐 ]

 

1) 컨텐츠 λ·°: 화면을 κ·Έλ¦¬λŠ” ꡬ쑰체

2) 프리뷰 : 프리뷰λ₯Ό κ·Έλ¦¬λŠ” ꡬ쑰체

 

 - text 밑에 .을 ν†΅ν•˜μ—¬ 속성듀을 λ‚˜μ—΄ν•˜λŠ” 것

 : modifier 라고 λΆ€λ₯Έλ‹€!

 ex) .font, .fontWeight, .padding λ“±λ“±

 

 

 

 


 

 

[ some 은 무엇인가 ? ]

 [ 좜처: https://babbab2.tistory.com/158 ]

 

 

someμ΄λΌλŠ” ν‚€μ›Œλ“œλŠ” Swift 5.1μ—μ„œ λ“±μž₯ν•œ μƒˆλ‘œμš΄ κΈ°λŠ₯으둜,

 ν•΄λ‹Ή ν‚€μ›Œλ“œκ°€ λ°˜ν™˜ νƒ€μž… μ•žμ— 뢙을 경우,

 ν•΄λ‹Ή λ°˜ν™˜ νƒ€μž…μ΄ 뢈투λͺ…ν•œ νƒ€μž…(Opaque Type)!

 : 뢈투λͺ…ν•œ νƒ€μž…μ΄λž€ -> "μ—­ μ œλ„€λ¦­ νƒ€μž…(reverse generic types)

 

 μœ„μ—μ„œ μ œλ„€λ¦­μ΄ ν•¨μˆ˜ "μ™ΈλΆ€"μ—μ„œ ν•΄λ‹Ή νƒ€μž…μ— λŒ€ν•΄ μ•Œ 수 μžˆλŠ” 반면,

 λΆˆνˆ¬λͺ…ν•œ νƒ€μž…μ˜ 경우, μ™ΈλΆ€μ—μ„œ ν•¨μˆ˜μ˜ λ°˜ν™˜ κ°’ μœ ν˜•μ„ μ •ν™•ν•˜κ²Œ μ•Œ 수 μ—†μŒ

 λ‹€λ§Œ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œλŠ” μ–΄λ–€ νƒ€μž…μ„ λ‹€λ£¨λŠ”μ§€ μ •ν™•νžˆ μ•Œκ³  있음

(그러게, μ •ν™•νžˆ λ°˜λŒ€λ„€..?)

 

 

 

 


 

 

 

 

 λͺ…ν™•ν•˜μ§€ μ•Šμ€ νƒ€μž…(associatedType or Self)이 ν”„λ‘œν† μ½œ 내에 μ •μ˜λ˜μ–΄ 있고,

 μ΄ ν”„λ‘œν† μ½œμ„ ν•¨μˆ˜(및 μ—°μ‚° ν”„λ‘œνΌν‹°)의 λ°˜ν™˜ νƒ€μž…μœΌλ‘œ κ°€μ§ˆ λ•Œ

 λ°˜ν™˜ νƒ€μž…μ„ "뢈투λͺ… νƒ€μž…"으둜 λ§Œλ“€μ–΄μ£ΌκΈ° μœ„ν•΄ μ‚¬μš©ν•˜κ³ ,

 : λ°˜ν™˜ κ°’ μœ ν˜•μ„ μ •ν™•ν•˜κ²Œ μ•Œ 수 μ—†λ‹€!

  

 someμ΄λΌλŠ” 것을 톡해 λ°˜ν™˜ νƒ€μž…μ„ "뢈투λͺ… νƒ€μž…"으둜 λ§Œλ“ λ‹¨ 것은,

 λ°˜ν™˜ νƒ€μž…μ΄ μ–΄λ–€ νƒ€μž…μΈμ§€ 컴파일러(및 ν•¨μˆ˜ μ™ΈλΆ€)λŠ” 1도 λͺ¨λ₯΄κ² μ§€λ§Œ

 ν•¨μˆ˜ 내뢀에선 μ–΄λ–€ νƒ€μž…μ„ λ°˜ν™˜ν•˜λŠ”μ§€ λͺ…ν™•νžˆ μ•Œκ³  있고, (λ‚΄λΆ€λŠ” μ•Œκ³ μžˆλ‹€!)

 λ”°λΌμ„œ λ‚΄ ν•¨μˆ˜λŠ” 정해진 "νŠΉμ • νƒ€μž…λ§Œ λ°˜ν™˜"λœλ‹€κ³  μ»΄νŒŒμΌλŸ¬μ—κ²Œ μ•Œλ €μ£ΌλŠ” κ²ƒμž„

 // ν›„.. μ–΄λ ΅λ‹€.. 머리 터진닀. .으 ㅏ아

  

 μœ„ μ˜ˆμ œμ—μ„œ "νŠΉμ • νƒ€μž…"은 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ–΄λ–»κ²Œ κ΅¬ν˜„ν•˜λƒμ— 따라 λ‹¬λΌμ§€κ² μ§€λ§Œ,

 GiftBox ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜κ³  μžˆλŠ” AppleGiftBox / CherryGiftBix 쀑 ν•˜λ‚˜κ°€ 될 κ²ƒμž„

 

 

 

 

 


 

 

 [ some 을 μ‚¬μš©ν•  λ•Œμ˜ 이점! ]

 

 

 μ—¬κΈ°μ„œ bodyλΌλŠ” 것은 ViewλΌλŠ” ν”„λ‘œν† μ½œμ— μ •μ˜λœ ν”„λ‘œνΌν‹°μΈλ°,

 μ΄ ν”„λ‘œνΌν‹°λŠ”μ—°μ‚° ν”„λ‘œνΌν‹°(Computed Property)둜

 μœ„ μ½”λ“œμ—μ„  TextλΌλŠ” 것을 return ν•˜κ³  μžˆλ‹€κ³  보면 됨

  

 μž, 근데 μœ„μ—μ„œ 배운 것을 ν† λŒ€λ‘œ ν•œλ‹€λ©΄

 some은 μ–Έμ œμ“΄λ‹€??

  

 λͺ…ν™•ν•˜μ§€ μ•Šμ€ νƒ€μž…(associatedType or Self)이 ν”„λ‘œν† μ½œ 내에 μ •μ˜λ˜μ–΄ 있고,

 μ΄ ν”„λ‘œν† μ½œμ„ λ°˜ν™˜ νƒ€μž…μœΌλ‘œ 가지고 싢을 λ•Œ μ“΄λ‹€!!!

  

 μ˜€ν™ 그럼 ViewλŠ” ν”„λ‘œν† μ½œμΌ 것이고!!! 속성 쀑 ν•˜λ‚˜λŠ” associatedtype(or Self)둜 μ„ μ–Έλ˜μ–΄ μžˆκ² λ„€!?

 

 

 

 

 

 

 // bodyκ°€ associatedtype 으둜 view (ν”„λ‘œν† μ½œ) 내뢀에 μ •μ˜λ˜μ–΄ 있음

 μ΄λ₯Ό λ°˜ν™˜ νƒ€μž…μœΌλ‘œ κ°–κ³  싢을 λ•Œ

 λͺ…ν™•ν•˜μ§€ μ•Šμ€ νƒ€μž…(associatedType or Self)이 ν”„λ‘œν† μ½œ 내에 μ •μ˜λ˜μ–΄ 있고,

 μ΄ ν”„λ‘œν† μ½œμ„ λ°˜ν™˜ νƒ€μž…μœΌλ‘œ 가지고 싢을 λ•Œ some을 μ“΄λ‹€! :)

 

 

 public protocol View {

     /// The type of view representing the body of this view.
     ///
     /// When you create a custom view, Swift infers this type from your
     /// implementation of the required ``View/body-swift.property`` property.
     
    associatedtype Body : View

     /// The content and behavior of the view.
     ///
     /// When you implement a custom view, you must implement a computed
     /// `body` property to provide the content for your view. Return a view
     /// that's composed of built-in views that SwiftUI provides, plus other
     /// composite views that you've already defined:
     ///
     ///     struct MyView: View {
     ///         var body: some View {
     ///             Text("Hello, World!")
     ///         }
     ///     }
     ///
     /// For more information about composing views and a view hierarchy,
     /// see <doc:Declaring-a-Custom-View>.
     @ViewBuilder var body: Self.Body { get }
 }

 

 

 

 


 

 

[정리]

 

 κ·ΈλŸΌ bodyλΌλŠ” μ—°μ‚° ν”„λ‘œνΌν‹°λŠ” ViewλΌλŠ” ν”„λ‘œν† μ½œ νƒ€μž…μ„ λ°˜ν™˜ν•˜μ§€λ§Œ

 ViewλΌλŠ” ν”„λ‘œν† μ½œ 내에 λͺ…ν™•ν•˜μ§€ μ•Šμ€ νƒ€μž…(body)이 μ •μ˜λ˜μ–΄ μžˆμœΌλ‹ˆ

 some을 톡해 뢈투λͺ… νƒ€μž…μ΄λΌκ³  λ°ν˜€μ€€ κ²ƒμ΄κ΅¬λ‚˜!

  

 λ”°λΌμ„œ body 내뢀에 λ‚΄κ°€ μž‘μ„±ν•˜λŠ” μ½”λ“œμ— 따라 리턴 νƒ€μž…μ΄ λ‹¬λΌμ§€κ² μ§€λ§Œ,

 View ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜λŠ” νƒ€μž…λ§Œ 리턴이 κ°€λŠ₯ν•˜κ² κ΅°!

 

 

 

 ( if text -> button )

 

 μ»΄νŒŒμΌλŸ¬(및 ν•¨μˆ˜ μ™ΈλΆ€)μ—μ„œλŠ” ViewλΌλŠ” ν”„λ‘œν† μ½œμ„ μ€€μˆ˜ν•˜λŠ” 객체가 λ‚˜μ˜¬ 것은 μ•Œμ§€λ§Œ,

 μ •ν™•νžˆ μ–΄λ–€ νƒ€μž…μ΄ λ‚˜μ˜¬μ§€λŠ” λͺ¨λ¦„

 λ‹€λ§Œ μœ„μ—μ„œ bodyλŠ” νŠΉμ • νƒ€μž…(ν˜„μž¬λŠ” λ‚΄κ°€ Textλ₯Ό 리턴 ν–ˆμœΌλ‹ˆ Text)만

 ν•­μƒ λ°˜ν™˜λœλ‹¨ 것을 μ•Œλ €μ£ΌλŠ” 것이 some(뢈투λͺ… νƒ€μž…)μž„

  

 μ—₯ κ°‘μžκΈ° κΈ°νšμžκ°€ λ‚΄λΆ€ λ””μžμΈμ„ Textκ°€ μ•„λ‹Œ λ²„νŠΌμœΌλ‘œ 바꿔달라넀?

 

 μ΄λ ‡κ²Œ textλ₯Ό Button으둜 λ°”κΎΈλ©΄ 컴파일러 및 ν•¨μˆ˜ 외뢀에선

 μ—¬μ „νžˆ μ •ν™•νžˆ μ–΄λ–€ νƒ€μž…μ΄ λ‚˜μ˜¬μ§€λŠ” λͺ¨λ¦„

 λ‹€λ§Œ μœ„μ—μ„œ bodyλŠ” νŠΉμ • νƒ€μž…(ν˜„μž¬λŠ” λ‚΄κ°€ Buttonλ₯Ό 리턴 ν–ˆμœΌλ‹ˆ Button)만

 ν•­μƒ λ°˜ν™˜λœλ‹¨ 것을 μ•Œλ €μ£ΌλŠ” 것이 some(뢈투λͺ… νƒ€μž…)μž„

 

 

 


 

 

[ summary ]

 

 μ΄λ ‡κ²Œ 뢈투λͺ…ν•œ νƒ€μž…(some)을 μ‚¬μš©ν•  경우,

 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ λ‚΄κ°€ μ§œλŠ” μ½”λ“œμ— 따라 μ‹œμ‹œκ°κ° 리턴 νƒ€μž…μ΄ λ³€κ²½ λ˜μ—ˆμ§€λ§Œ (Text -> Button)

 μ΄κ±°μ— λŒ€ν•΄ λ”°λ‘œ λ‚΄κ°€ 리턴 νƒ€μž…μ„ 바꿔쀄 ν•„μš”κ°€ μ—†μŒ!!!

 

 λ§Œμ•½ some을 톡해 뢈투λͺ… νƒ€μž…μœΌλ‘œ μ„ μ–Έν•˜μ§€ μ•Šμ•˜λ‹€λ©΄

 λ§€λ²ˆ body의 νƒ€μž…μ„ μ €λ ‡κ²Œ λ‹€ λ”μ°ν•˜κ²Œ λͺ…λͺ…해쀬어야 ν–ˆμ„ κ±°μž„

 ν•œλ§ˆλ””λ‘œ λΆˆν•„μš”ν•œ νƒ€μž…μ— λŒ€ν•΄ μš°λ¦¬κ°€ μ•Œ ν•„μš”κ°€ μ—†μŒ! μ»΄νŒŒμΌλŸ¬κ°€ μ•Œμ•„μ„œ 함

 -> μ‰½κ²Œ ui μš”μ†Œλ“€μ„ κ΅¬μ„±ν•˜κΈ° μœ„ν•΄, μ‚¬μš©μ„±μ„ λ†’μ΄λŠ” 역할을 ν•˜λŠ” λ“― ν•˜λ‹€.

 

 

 

 

 

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        // previews : PreviewProvider ν”„λ‘œν† μ½œμ˜ ν•„μˆ˜ κ΅¬ν˜„ 사항
        // previews νƒ€μž… ν”„λ‘œνΌν‹°μ—μ„œ λ·° 생성
        
        ContentView()
        // μ–˜λ„ κ²°κ΅­ ν™ˆ λ·° μƒμ„±μœΌλ‘œ 이어지겠지?
    }
}
#endif

 

 

 

 public protocol PreviewProvider : _PreviewProvider {

     /// The type to preview.
     ///
     /// When you create a preview, Swift infers this type from your
     /// implementation of the required
     /// ``PreviewProvider/previews-swift.type.property`` property.
 
     associatedtype Previews : View

     /// A collection of views to preview.
     ///
     /// Implement a computed `previews` property to indicate the content to
     /// preview. Xcode generates a preview for each view that you list. You
     /// can apply ``View`` modifiers to the views, like you do
     /// when creating a custom view. For a preview, you can also use
     /// various preview-specific modifiers that customize the preview.
     /// For example, you can choose a specific device for the preview
     /// by adding the ``View/previewDevice(_:)`` modifier:
     ///
     ///     struct CircleImage_Previews: PreviewProvider {
     ///         static var previews: some View {
     ///             CircleImage()
     ///                 .previewDevice(PreviewDevice(rawValue: "iPad Pro (11-inch)"))
     ///         }
     ///     }
     ///
     /// For the full list of preview-specific modifiers,
     /// see <doc:Previews-in-Xcode>.
 
     @ViewBuilder static var previews: Self.Previews { get }

     /// The platform on which to run the provider.
     ///
     /// Xcode infers the platform for a preview based on the currently
     /// selected target. If you have a multiplatform target and want to
     /// suggest a particular target for a preview, implement the
     /// `platform` computed property to provide a hint,
     /// and specify one of the ``PreviewPlatform`` values:
     ///
     ///     struct CircleImage_Previews: PreviewProvider {
     ///         static var previews: some View {
     ///             CircleImage()
     ///         }
     ///
     ///         static var platform: PreviewPlatform? {
     ///             PreviewPlatform.tvOS
     ///         }
     ///     }
     ///
     /// Xcode ignores this value unless you have a multiplatform target.
     static var platform: PreviewPlatform? { get }
 }

 

 

 

 

 


  

 

 

 [ content view μ΄ν•΄ν•˜κΈ° ]

 [ 좜처: https://babbab2.tistory.com/159?category=829015 ]

 

 

 

 1) bodyλŠ” 단 ν•œκ°œμ˜ View만 λ°˜ν™˜ !

 : μ—¬λŸ¬κ°œμ˜ textλ₯Ό λ°°μΉ˜ν•˜κ³  싢을 땐, κΌ­ stack으둜 λ¬Άμ–΄μ€˜μ•Ό 함

 : 즉, μ—¬λŸ¬ 개의 뷰듀을 ν•˜λ‚˜μ˜ 뷰둜 κ°μ‹Έμ€˜μ„œ ν•˜λ‚˜μ˜ View둜 리턴해야 함!!!

 - μ‹€μ œ μœ„ μ½”λ“œμ—μ„œ body의 νƒ€μž…μ€ VStack<TupleView<Text,Text>>으둜

   bodyλŠ” VStackμ΄λΌλŠ” ν•˜λ‚˜μ˜ View둜 λ°˜ν™˜λ˜λŠ” κ²ƒμž„!

 - λ‹€λ§Œ 우린 μœ„μ˜ λ³΅μž‘ν•œ νƒ€μž…μ— λŒ€ν•΄ μ•Œ ν•„μš” μ—†κ³  λͺ…μ‹œν•  ν•„μš”λ„ μ—†λ‹€!

 -> bodyκ°€ some View 즉, 뢈투λͺ… νƒ€μž…μ„ λ¦¬ν„΄ν•˜λ‹ˆκΉŒ! ν•˜ν•˜

 

 

 2) ContentView에 λ³€μˆ˜λ‚˜ μƒμˆ˜λ₯Ό μΆ”κ°€ ?

 -> body μœ„μ—λ‹€κ°€ ν•΄μ£Όλ©΄ λœλ‹€!

 

 

 struct ContentView : View {
      var name: "Colli"
      var body: some View {
          Text("Hello")
      }
  }

  

 

 

 

 

 3) View의 생애주기λ₯Ό κ΄€λ¦¬ν•˜κ³  μ‹Άλ‹€λ©΄ ?

 

 κ·Έ.. UIKit으둜 κ°œλ°œν•  λ•Œ μ‚¬μš©ν•˜λŠ” View Controller의 생애주기 μžˆμž–μŒ?

  

 ViewDidAppear

 ViewDidDisappear

 ...

  

 λ“±λ“±.. 이런 κ±° μ–΄λ–»κ²Œ μ‚¬μš©ν•˜λƒλ©΄

  

 onAppear

 onDisappear

  

 λΌλŠ” modifierλ₯Ό μ΄μš©ν•˜λ©΄ 됨!! :)

 

 

  

  struct ContentView : View {
      var body: some View {
          Text("Hello")
          .onAppear {
              print("ν…μŠ€νŠΈκ°€ λ³΄μž…λ‹ˆλ‹€")
          }
      }
  }

 

  

  

 λ“±λ“± 이런 μ‹μœΌλ‘œ!

 

 

 +

 

 + 참고둜

 μœ„μ˜ body ν”„λ‘œνΌν‹°λŠ” Viewκ°€ μƒμ„±λ˜κ³  ν•œ 번만 λ§Œλ“€μ–΄μ§€λŠ” 게 μ•„λ‹ˆλΌ

 View의 Life Cycle λ™μ•ˆ ν•„μš”ν•  λ•Œλ§ˆλ‹€ μ—¬λŸ¬ λ²ˆμ”© μƒˆλ‘œ λ§Œλ“€μ–΄μ Έμ„œ 리턴됨

  

 κ·ΈλŸΌ μ„±λŠ₯에 λ¬Έμ œμžˆλŠ” κ±° μ•„λ‹Œκ°€μš”? μ‹Άκ² μ§€λ§Œ,

 SwiftUI에선 View μžμ²΄κ°€ ν΄λž˜μŠ€κ°€ μ•„λ‹Œ ꡬ쑰체둜 맀우맀우 κ°€λ²Όμ›Œ ok