Swift Result Builders:説明とコード例

翻訳は、コース「iOSDeveloper.Professional」のセットの一部として作成されました



オープンデモレッスン「CoreMLとCreateMLを使用したiOSでの機械学習:画像、テキスト、サウンド」に皆様をご招待します。このレッスンでは、次のことについて説明します



。1。ニューラルネットワークの主なアーキテクチャとモバイルデバイス用に最適化されたバージョン。

2. CoreML 3および4の可能性、iOSデバイスでのトレーニング。

3. CreateMLを使用し、Visionで使用する画像分類器のセルフトレーニング。

4.トレーニング済みモデルを使用してiOSでテキストとサウンドを操作します。






(result builders) Swift  — « ». Swift 5.4 Xcode 12.5 . function builders (« »). , , SwiftUI.





: , Swift, . UIKit, , .





?

- (DSL), . SwiftUI @ViewBuilder



, :





struct ContentView: View {
     var body: some View {
         // This is inside a result builder
         VStack {
             Text("Hello World!") // VStack and Text are 'build blocks'
         }
     }
 }
      
      



( VStack, Text



) View



. , « » View



«» View



. , .





View



SwiftUI, , body



@ViewBuilder



:





@ViewBuilder var body: Self.Body { get }
      
      



, .





, . :





var constraints: [NSLayoutConstraint] = [
     // Single constraint
     swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
 ]

 // Boolean check
 if alignLogoTop {
     constraints.append(swiftLeeLogo.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor))
 } else {
     constraints.append(swiftLeeLogo.centerYAnchor.constraint(equalTo: view.centerYAnchor))
 }

 // Unwrap an optional
 if let fixedLogoSize = fixedLogoSize {
     constraints.append(contentsOf: [
         swiftLeeLogo.widthAnchor.constraint(equalToConstant: fixedLogoSize.width),
         swiftLeeLogo.heightAnchor.constraint(equalToConstant: fixedLogoSize.height)
     ])
 }

 // Add a collection of constraints
 constraints.append(contentsOf: label.constraintsForAnchoringTo(boundsOf: view)) // Returns an array

 // Activate
 NSLayoutConstraint.activate(constraints)
      
      



, . .





 — . :





 @AutolayoutBuilder var constraints: [NSLayoutConstraint] {
     swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor) // Single constraint
     
     if alignLogoTop {
         swiftLeeLogo.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
     } else {
         swiftLeeLogo.centerYAnchor.constraint(equalTo: view.centerYAnchor) // Single constraint
     }
     
     if let fixedLogoSize = fixedLogoSize {
         swiftLeeLogo.widthAnchor.constraint(equalToConstant: fixedLogoSize.width)
         swiftLeeLogo.heightAnchor.constraint(equalToConstant: fixedLogoSize.height)
     }
     
     label.constraintsForAnchoringTo(boundsOf: view) // Returns an array
 } 
      
      



, ?





, .





AutolayoutBuilder



@resultBuilder



, :





@resultBuilder
 struct AutolayoutBuilder {     
     // .. Handle different cases, like unwrapping and collections 
 } 
      
      



« » , , . .





:





 @resultBuilder
 struct AutolayoutBuilder {
     
     static func buildBlock(_ components: NSLayoutConstraint...) -> [NSLayoutConstraint] {
         return components
     } 
 }
      
      



components (  ). , . , .





:





@AutolayoutBuilder var constraints: [NSLayoutConstraint] {
     // Single constraint
     swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
 } 
      
      



« »

. constraintsForAnchoringTo(boundsOf:)



, . , :





最初、カスタム結果ビルダーはコンポーネントのコレクションを処理できません。
.

:





Cannot pass array of type ‘[NSLayoutConstraint]’ as variadic arguments of type ‘NSLayoutConstraint’ — «[NSLayoutConstraint]» «NSLayoutConstraint»





, Swift . . , :





カスタム結果ビルダーを定義する際に使用できるメソッドのリスト。
.

, , , . , , .





, , NSLayoutConstraint



, :





 protocol LayoutGroup {
     var constraints: [NSLayoutConstraint] { get }
 }
 extension NSLayoutConstraint: LayoutGroup {
     var constraints: [NSLayoutConstraint] { [self] }
 }
 extension Array: LayoutGroup where Element == NSLayoutConstraint {
     var constraints: [NSLayoutConstraint] { self }
 } 
      
      



, . ,  — [NSLayoutConstraint



].





, LayoutGroup



:





 @resultBuilder
 struct AutolayoutBuilder {
     
     static func buildBlock(_ components: LayoutGroup...) -> [NSLayoutConstraint] {
         return components.flatMap { $0.constraints }
     }
 } 
      
      



flatMap



. , flatMap



compactMap



, compactMap flatMap: ?





, , « »:





@AutolayoutBuilder var constraints: [NSLayoutConstraint] {
     // Single constraint
     swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
     
     label.constraintsForAnchoringTo(boundsOf: view) // Returns an array
 } 
      
      



, , — . , .





buildOptional(..)



:





 @resultBuilder
 struct AutolayoutBuilder {
     
     static func buildBlock(_ components: LayoutGroup...) -> [NSLayoutConstraint] {
         return components.flatMap { $0.constraints }
     }
     
     static func buildOptional(_ component: [LayoutGroup]?) -> [NSLayoutConstraint] {
         return component?.flatMap { $0.constraints } ?? []
     }
 } 
      
      



, .





« »:





@AutolayoutBuilder var constraints: [NSLayoutConstraint] {
     // Single constraint
     swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
     
     label.constraintsForAnchoringTo(boundsOf: view) // Returns an array
     
     // Unwrapping an optional
     if let fixedLogoSize = fixedLogoSize {
         swiftLeeLogo.widthAnchor.constraint(equalToConstant: fixedLogoSize.width)
         swiftLeeLogo.heightAnchor.constraint(equalToConstant: fixedLogoSize.height)
     }
 } 
      
      



 — . . :





 @AutolayoutBuilder var constraints: [NSLayoutConstraint] {
     // Single constraint
     swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
     
     label.constraintsForAnchoringTo(boundsOf: view) // Returns an array
     
     // Unwrapping an optional
     if let fixedLogoSize = fixedLogoSize {
         swiftLeeLogo.widthAnchor.constraint(equalToConstant: fixedLogoSize.width)
         swiftLeeLogo.heightAnchor.constraint(equalToConstant: fixedLogoSize.height)
     }
     
     // Conditional check
     if alignLogoTop {
         // Handle either the first component:
         swiftLeeLogo.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
     } else {
         // Or the second component:
         swiftLeeLogo.centerYAnchor.constraint(equalTo: view.centerYAnchor)
     }
 } 
      
      



« »:





 @resultBuilder
 struct AutolayoutBuilder {     
     static func buildBlock(_ components: LayoutGroup...) -> [NSLayoutConstraint] {
         return components.flatMap { $0.constraints }
     }
     
     static func buildOptional(_ component: [LayoutGroup]?) -> [NSLayoutConstraint] {
         return component?.flatMap { $0.constraints } ?? []
     }
     
     static func buildEither(first component: [LayoutGroup]) -> [NSLayoutConstraint] {
         return component.flatMap { $0.constraints }
     }
 
     static func buildEither(second component: [LayoutGroup]) -> [NSLayoutConstraint] {
         return component.flatMap { $0.constraints }
     }
 } 
      
      



buildEither



LayoutGroup



.





, . !





. , .





 — . AutolayoutBuilder



.





, NSLayoutConstraint



, :





extension NSLayoutConstraint {
     /// Activate the layouts defined in the result builder parameter `constraints`.
     static func activate(@AutolayoutBuilder constraints: () -> [NSLayoutConstraint]) {
         activate(constraints())
     } 
      
      



:





NSLayoutConstraint.activate {
     // Single constraint
     swiftLeeLogo.centerXAnchor.constraint(equalTo: view.centerXAnchor)
     
     label.constraintsForAnchoringTo(boundsOf: view) // Returns an array
     
     // Unwrapping an optional
     if let fixedLogoSize = fixedLogoSize {
         swiftLeeLogo.widthAnchor.constraint(equalToConstant: fixedLogoSize.width)
         swiftLeeLogo.heightAnchor.constraint(equalToConstant: fixedLogoSize.height)
     }
     
     // Conditional check
     if alignLogoTop {
         // Handle either the first component:
         swiftLeeLogo.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
     } else {
         // Or the second component:
         swiftLeeLogo.centerYAnchor.constraint(equalTo: view.centerYAnchor)
     }
 } 
      
      



, , UIView



:





 protocol SubviewContaining { }
 extension UIView: SubviewContaining { }
 extension SubviewContaining where Self == UIView {
     
     /// Add a child subview and directly activate the given constraints.
     func addSubview<View: UIView>(_ view: View, @AutolayoutBuilder constraints: (Self, View) -> [NSLayoutConstraint]) {
         addSubview(view)
         NSLayoutConstraint.activate(constraints(self, view))
     }
 } 
      
      



:





 let containerView = UIView()
 containerView.addSubview(label) { containerView, label in
     
     if label.numberOfLines == 1 {
         // Conditional constraints
     }
     
     // Or just use an array:
     label.constraintsForAnchoringTo(boundsOf: containerView)
     
 } 
      
      



, UIView



. , label



.





?

, , : , ?





, , , . , , .





, , . « », ( ) .





, ( ).





 — Swift 5.4. - , . , , .






"iOS Developer. Professional"





«Machine Learning iOS CoreML CreateML: , , »








All Articles