SwiftUI рдХрд╛ рдЬрд╛рджреВ рдпрд╛ рдлрдВрдХреНрд╢рди рдмрд┐рд▓реНрдбрд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ


рдХреНрдпрд╛ рдЖрдкрдиреЗ VStack рдореЗрдВ 10 рд╕реЗ рдЕрдзрд┐рдХ рджреГрд╢реНрдп рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рд╣реИ?


 var body: some View { VStack { Text("Placeholder1") Text("Placeholder2") // ...    3  10 . . . Text("Placeholder11") } } 

рдореИрдВрдиреЗ рдХреЛрд╢рд┐рд╢ рдХреА - рдпрд╣ рд╕рдВрдХрд▓рди рдирд╣реАрдВ рд╣реИред рд╣рд╛рдВ, рдореИрдВ рднреА рдкрд╣рд▓реЗ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рдерд╛ рдФрд░ рд╕реНрд╡рд┐рдлреНрдЯ рдлреЛрд░рдо рдФрд░ рдЧреАрдереВрдм рдХреЗ рдЕрдзреНрдпрдпрди рдореЗрдВ рдбреВрдм рдЧрдпрд╛ред рдореЗрд░реЗ рдЕрдзреНрдпрдпрди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдерд╛ - "рдпрд╣ рдЕрднреА рднреА ┬п\_(уГД)_/┬п my ┬п\_(уГД)_/┬п рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ"ред рд▓реЗрдХрд┐рди рд░реБрдХрд┐рдП, рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпреЛрдВред


рдлрдВрдХреНрд╢рди рдмрд┐рд▓реНрдбрд░


рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдЖрдорддреМрд░ рдкрд░ рдХреИрд╕реЗ рдЙрдкрд▓рдмреНрдз рд╣реЛрддреЗ рд╣реИрдВред рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЕрд╕рд╛рдорд╛рдиреНрдп рддрддреНрд╡реЛрдВ рдХреА рдРрд╕реА рдШреЛрд╖рдгрд╛рддреНрдордХ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЖрдзрд╛рд░ рдлрдВрдХреНрд╢рди рдмрд┐рд▓реНрдбрд░ рддрдВрддреНрд░ рд╣реИред
рд╕реНрд╡рд┐рдлреНрдЯ-рдЗрд╡реЛрд▓реНрдпреВрд╢рди рдореЗрдВ рдЬреАрдердм рдкрд░ рдЬреЙрди рдореИрдХреЙрд▓ рдФрд░ рдбрдЧ рдЧреНрд░реЗрдЧрд░ рдХрд╛ рдПрдХ рдкреНрд░рд╕реНрддрд╛рд╡ рд╣реИ - рдлрдВрдХреНрд╢рди рдмрд┐рд▓реНрдбрд░реЛрдВ (рдкреНрд░рд╕реНрддрд╛рд╡: рдПрд╕рдИ-рдПрдХреНрд╕рдПрдХреНрд╕рдПрдХреНрд╕рдПрдХреНрд╕) , рдЬрд┐рд╕рдореЗрдВ рд╡реЗ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдХрд┐рд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣реЗ рдереЗ, рдлрдВрдХреНрд╢рдирд▓ рдмрд┐рд▓реНрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рдХреНрдпреЛрдВ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдпрд╣ рдХреНрдпрд╛ рдерд╛ред рдПрдХред


рддреЛ рдпрд╣ рдХреНрдпрд╛ рд╣реИ?


рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдЗрд╕рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ - рдпрд╣ рдПрдХ рдРрд╕рд╛ рддрдВрддреНрд░ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рддрд░реНрдХреЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдПрдХ рдЦрдЬрд╛рдиреЗ рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рдХреБрдЫ рд╕рд╛рдордЧреНрд░реА, рдФрд░ рдЗрд╕ рд╕рдм рд╕реЗ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИред
рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд╛ рдЙрджреНрдзрд░рдг : SE-XXXX :


рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рдиреЗрд╕реНрдЯреЗрдб рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпрд╛рдБ рдЬреИрд╕реЗ рдЕрдЧрд░ рдФрд░ рд╕реНрд╡рд┐рдЪ, рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдкрд░рд┐рдгрд╛рдо рдореЗрдВ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬреЛ рд╡рд░реНрддрдорд╛рди рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд░рд┐рдЯрд░реНрди рдорд╛рди рдмрди рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ "рдмрд┐рд▓реНрдб" рдлрд╝рдВрдХреНрд╢рди рдмрд┐рд▓реНрдбрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рдХрд╕реНрдЯрдо рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИред

рдореВрд▓
рдореВрд▓ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдмрдпрд╛рдиреЛрдВ рдХреЗ рдПрдХ рдЦрдВрдб рдХреЗ "рдЙрдкреЗрдХреНрд╖рд┐рдд" рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ - рдЬрд┐рдирдореЗрдВ рдиреЗрдлреЗрдбрд╕реНрд╡рд┐рдЪрд╕реНрдЯреИрдЯреЗрдореЗрдВрдЯреНрд╕ рдХреЗ рдирд┐рдХрд╛рдп рдЬреИрд╕реЗ рдирд┐рд╣рд┐рдд рд╕реНрдерд╛рди рд╢рд╛рдорд┐рд▓ рд╣реИрдВ - рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╣реА рдкрд░рд┐рдгрд╛рдо рдорд╛рди рдореЗрдВ рдмрдирд╛рддреЗ рд╣реИрдВ рдЬреЛ рд╡рд░реНрддрдорд╛рди рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдмрди рдЬрд╛рддрд╛ рд╣реИред рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдЗрд╕ рд╕рдВрдЧреНрд░рд╣ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЙрд╕реЗ рдПрдлрд┐рд▓реНрдЯ рдмрд┐рд▓реНрдбрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдПрдХ рдирдП рдкреНрд░рдХрд╛рд░ рдХрд╛ рдХрд╕реНрдЯрдо-рд╡рд┐рд╢реЗрд╖рддрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ;

рдЗрд╕ рддрд░рд╣ рдХрд╛ рдПрдХ рддрдВрддреНрд░ рдЖрдкрдХреЛ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╡рд┐рд░рд╛рдо рдЪрд┐рд╣реНрдиреЛрдВ рдХреЗ рдмрд┐рдирд╛, рдШреЛрд╖рдгрд╛рддреНрдордХ рд╡реГрдХреНрд╖ рдЬреИрд╕рд╛ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:


 let myBody = body { let chapter = spellOutChapter ? "Chapter" : "" div { if useChapterTitles { h1(chapter + "1. Loomings.") } p { "Call me Ishmael. Some years ago" } p { "There is now your insular city" } } } 

рдпрд╣ рдирдИ @_functionBuilder рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реИред рдпрд╣ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреБрдЫ рдмрд┐рд▓реНрдбрд░ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреА рд╣реИ, рдпрд╣ рдПрдХ рд╕рдВрд░рдЪрдирд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред рдпрд╣ рдмрд┐рд▓реНрдбрд░ рдХрдИ рд╡рд┐рд╢рд┐рд╖реНрдЯ рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕ рдмрд┐рд▓реНрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ, рд╕реНрд╡рдпрдВ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдиреАрдЪреЗ рдореИрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдХреЛрдб рдХреЛ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред


рдпрд╣ рдХреНрдпреЛрдВ рд╣реИ?


рдЗрд╕рд▓рд┐рдП Apple рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдбреЛрдореЗрди-рд╡рд┐рд╢рд┐рд╖реНрдЯ рднрд╛рд╖рд╛ DSL рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИред
рдЬреЙрди рдореИрдХрдХреЙрд▓ рдФрд░ рдбрдЧ рдЧреНрд░реЗрдЧрд░ рдмрддрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рдХреЛрдб рдХреЛ рдкрдврд╝рдирд╛ рдФрд░ рд▓рд┐рдЦрдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ - рдпрд╣ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддрд╛ рд╣реИ, рдЗрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдмрдирд╛рддрд╛ рд╣реИ рдФрд░, рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдХреЛрдб рдЕрдзрд┐рдХ рд╕рдорд░реНрдерд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕реА рд╕рдордп, рд╡реЗ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЙрдирдХрд╛ рд╕рдорд╛рдзрд╛рди рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдбреАрдПрд╕рдПрд▓ рдирд╣реАрдВ рд╣реИред
рдпрд╣ рд╕рдорд╛рдзрд╛рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реЗрдЯ рдкрд░ рдХреЗрдВрджреНрд░рд┐рдд рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд░реИрдЦрд┐рдХ рдФрд░ рдкреЗрдбрд╝ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдЬреИрд╕реЗ рдХрд┐ XML, JSON, рд╡реНрдпреВ рдкрджрд╛рдиреБрдХреНрд░рдо, рдЖрджрд┐ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред


рдЗрд╕рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░реЗрдВ?


рдЖрдк рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдлрдВрдХреНрд╢рди рдмрд┐рд▓реНрдбрд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдореЗрд░реЗ рд▓рд┐рдП рдпрд╣ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рдерд╛ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдПрдХ рдмрд┐рд▓реНрдбрд░ рдХреЗ рдПрдХ рдЖрджрд┐рдо рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдЬреЛ рддрд╛рд░ рдХреЛ рд╕рдорд╛рдкреНтАНрдд рдХрд░рддрд╛ рд╣реИред


 // 1.  Builder @_functionBuilder struct MyBuilder { static func buildBlock(_ atrs: String...) -> String { return atrs.reduce("", + ) } } 

 // 2.          func stringsReduce(@MyBuilder block: () -> String) -> String { return block() } 

 // 3.     let result = stringsReduce { "1" "2" } print(result) // "12" 

рд╣реБрдб рдХреЗ рддрд╣рдд, рдпрд╣ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛:


 let result = stringsReduce { return MyBuilder.build("1", "2") } 

рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдмрд┐рд▓реНрдбрд░ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд╛рдореЛрдВ рдХреЗ рд╕рд╛рде рдФрд░ рдЗрд╕ рд╕реВрдЪреА рд╕реЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдмрд┐рд▓реНрдХреБрд▓ рд╕реНрдерд┐рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрдк рдХреЗрд╡рд▓ рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдкреНрд░рдХрд╛рд░ рдФрд░ рдирд╛рдо рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред


 static func buildBlock(_ <*atrs*>: <*String*>...) -> <*String*> 

рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд┐рдзрд┐ рдирд╛рдо рдмрд┐рд▓реНрдбрд░ рдореЗрдВ рдЦреЛрдЬрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд╕рдВрдХрд▓рди рдЪрд░рдг рдореЗрдВ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдФрд░ рдпрджрд┐ рд╡рд┐рдзрд┐ рдирд╣реАрдВ рдорд┐рд▓реА рд╣реИ, рддреЛ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рд╣реЛрдЧреАред
рдФрд░ рдпрд╣ рдЬрд╛рджреВ рд╣реИред рдЬрдм рдЖрдк рдмрд┐рд▓реНрдбрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рдВрдХрд▓рдХ рдЖрдкрдХреЛ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрддрд╛рдПрдЧрд╛ред рдпрд╣ рдЙрдкрд▓рдмреНрдз рддрд░реАрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдХрд╣реЗрдЧрд╛, рдпрд╣ рдПрдХ рд╕реНрд╡рдд: рдкреВрд░реНрдг рдХреЗ рд╕рд╛рде рдорджрдж рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдХреЗрд╡рд▓ рдЬрдм рдЖрдк рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ рдЗрд╕ рдмрд┐рд▓реНрдбрд░ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рддреЛ рдХреНрдпрд╛ рдЖрдкрдХреЛ рдПрдХ рдЕрдкреНрд░рддреНрдпрдХреНрд╖ рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИред
рдЕрдм рддрдХ, рдореИрдВрдиреЗ рдЬреЛ рдПрдХрдорд╛рддреНрд░ рд╕рдорд╛рдзрд╛рди рдкрд╛рдпрд╛ рд╣реИ, рд╡рд╣ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╣реИред
рддреЛ рд╣рдореЗрдВ рдЕрдиреНрдп рддрд░реАрдХреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЪреЗрдХ рдХреЗ рд╕рд╛рде рдРрд╕реЗ рдХреЛрдб рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдирд╛


 stringsReduce { if .random() { //   Bool "one string" } else { "another one" } "fixed string" } 

рдЗрд╕ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд┐рд▓реНрдбрд░ рдХреЛ buildEither(first:/second:) рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ


 static func buildEither(first: String) -> String { return first } static func buildEither(second: String) -> String { return second } 

рд╕рд╛рдореБрджрд╛рдпрд┐рдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛


рдордЬреЗрджрд╛рд░ рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдЕрднреА рд╕реНрд╡рд┐рдлреНрдЯ 5.1 рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рдпрд╛рдиреА рдЗрд╕ рдлреАрдЪрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдкреБрд▓ рдХрд╛ рдЕрдиреБрд░реЛрдз рдЕрднреА рддрдХ рдирд╣реАрдВ рдбрд╛рд▓рд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рдРрдкреНрдкрд▓ рдиреЗ рдкрд╣рд▓реЗ рд╣реА рдЗрд╕реЗ Xcode 11 рдмреАрдЯрд╛ рдореЗрдВ рдЬреЛрдбрд╝ рджрд┐рдпрд╛ рд╣реИред рдФрд░ рдлрдВрдХреНрд╢рди рдмрд┐рд▓реНрдбрд░реЛрдВ тЖТ рдкрд┐рдХреНрд╕ тЖТ рд╕реНрд╡рд┐рдлреНрдЯ рдлрд╝реЛрд░рдо рдореЗрдВ, рдЖрдк рдЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдкрд░ рд╕рдореБрджрд╛рдп рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред


ViewBuilder


рдЕрдм VStack рд╡рд╛рдкрд╕ VStack рдФрд░ рдЗрд╕рдХреЗ VStack (рд╕рдВрд░реЗрдЦрдг: рд░рд┐рдХреНрддрд┐: рд╕рд╛рдордЧреНрд░реА :) рдХреЗ рдкреНрд░рд▓реЗрдЦрди рджреЗрдЦреЗрдВред
рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:


 init(alignment: HorizontalAlignment = .center, spacing: ? = nil, @ViewBuilder content: () -> Content) 

рдФрд░ рд╕рд╛рдордЧреНрд░реА рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рдХрд╕реНрдЯрдо рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ @ViewBuilder
рдЗрд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:


 @_functionBuilder public struct ViewBuilder { /// Builds an empty view from an block containing no statements, `{ }`. public static func buildBlock() -> EmptyView /// Passes a single view written as a child view (e..g, `{ Text("Hello") }`) through /// unmodified. public static func buildBlock<Content>(_ content: Content) -> Content where Content : View } 

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд┐рд╢реЗрд╖рддрд╛ @ _functionBuilder , рдЬреЛ рдЗрд╕рдХреА рдШреЛрд╖рдгрд╛ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдкрдВрдЬреАрдХреГрдд рд╣реИред


рдФрд░ рдЕрдЧрд░ рдЖрдк рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреЛ рдФрд░ рднреА рдХрдо рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХрдИ рд╕реНрдерд┐рд░ buildBlock рд╡рд┐рдзрд┐рдпрд╛рдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рддрд░реНрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рднрд┐рдиреНрди рд╣реИрдВред


рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╡реНрдпреВ рдХреЛрдб


 var body: some View { VStack { Text("Placeholder1") Text("Placeholder2") Text("Placeholder3") } } 

рд╣реБрдб рдХреЗ рддрд╣рдд рдЗрд╕ рддрд░рд╣ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рджрд┐рдпрд╛ рд╣реИ


  var body: some View { VStack(alignment: .leading) { ViewBuilder.buildBlock(Text("Placeholder1"), Text("Placeholder2"), Text("Placeholder3")) } } 

рдпрд╛рдиреА рдмрд┐рд▓реНрдбрдмреНрд▓реЙрдХ рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ (:: _ :) рдмрд┐рд▓реНрдбрд░ рд╡рд┐рдзрд┐ред


рдкреВрд░реА рд╕реВрдЪреА рд╕реЗ, рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рд╡рд┐рдзрд┐ рдЗрд╕ рдЖрджрдореА рдХрд╛ рдмрд┐рд▓реНрдбрдмреНрд▓реЙрдХ (::::::::: :) :) (10 рддрд░реНрдХ):


 extension ViewBuilder { public static func buildBlock<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7, _ c8: C8, _ c9: C9) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View, C7 : View, C8 : View, C9 : View } 

рдФрд░ рддрджрдиреБрд╕рд╛рд░, рдореВрд▓ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд▓реМрдЯрддреЗ рд╣реБрдП, рдЬрдм рдЖрдк VStack рдФрд░ рдЧреНрдпрд╛рд░рд╣ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЛ рдЕрдВрджрд░ рдЙрдард╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдХрдВрдкрд╛рдЗрд▓рд░ ViewBuilder'a buildBlock рд╡рд┐рдзрд┐ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ 11 рдЗрдирдкреБрдЯ рддрд░реНрдХ рд╣реИрдВред рд▓реЗрдХрд┐рди рдРрд╕реА рдХреЛрдИ рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИ: рдЗрд╕рд▓рд┐рдП рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ред
рдпрд╣ рдЙрди рд╕рднреА рд╕рдВрдЧреНрд░рд╣реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рд╣реИ, рдЬреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝рд░ рдореЗрдВ @ViewBuilder рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ: V | Z-Stack, List, Group рдФрд░ рдЕрдиреНрдп, рдЬрд┐рдирдХреЗ рдЕрдВрджрд░ рдЖрдк рдПрдиреНрдпреВрдорд░реЗрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рджреГрд╢реНрдп рдШреЛрд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдФрд░ рдпрд╣ рджреБрдЦрдж рд╣реИред


рдореЗрдо (рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рдореБрдЭреЗ рдПрдХ рдЕрдЪреНрдЫрд╛ рдореЗрдо рдирд╣реАрдВ рдорд┐рд▓рд╛)


рдХреИрд╕реЗ рд╣реЛ?


рд╣рдо ForEach рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рд╕реАрдорд╛ рдХреЛ рджрд░рдХрд┐рдирд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ForEach


 struct TestView : View { var body: some View { VStack { ForEach(texts) { i in Text(┬л\(i)┬╗) } } } var texts: [Int] { var result: [Int] = [] for i in 0...150 { result.append(i) } return result } } 

рдпрд╛ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╢рд┐рдХрд╛рд░ рд╕рдВрдЧреНрд░рд╣:


 var body: some View { VStack { VStack { Text("Placeholder_1") Text("Placeholder_2") //   8 } Group { Text("11") Text("12") //   8 } } } 

рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ рдХреЗ рдлреИрд╕рд▓реЗ рдмреИрд╕рд╛рдЦреА рдХреА рддрд░рд╣ рджрд┐рдЦрддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдЙрдЬреНрдЬрд╡рд▓ рднрд╡рд┐рд╖реНрдп рдХреА рдЙрдореНрдореАрдж рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рднрд╡рд┐рд╖реНрдп рдХреИрд╕рд╛ рд╣реИ?
рд╕реНрд╡рд┐рдлреНрдЯ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╡реИрд░рд╛рдбрд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ ред рдпрд╣ рдЧрдгрдирд╛ рджреНрд╡рд╛рд░рд╛ рддрд░реНрдХ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреА рдПрдХ рд╡рд┐рдзрд┐ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рднреА рдХреЛ рдЬреНрдЮрд╛рдд print рд╡рд┐рдзрд┐ рдЖрдкрдХреЛ print(1, 2) рдФрд░ print(1, 2, 3, 4) рджреЛрдиреЛрдВ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ print(1, 2, 3, 4) рдФрд░ рдпрд╣ рд╡рд┐рдзрд┐ рдХреЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЕрдзрд┐рднрд╛рд░ рдХреЗ рдмрд┐рдирд╛ рд╣реИред


 print(items: Any...) 

рд▓реЗрдХрд┐рди рднрд╛рд╖рд╛ рдХреА рдпрд╣ рд╡рд┐рд╢реЗрд╖рддрд╛ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ buildBlock рд╡рд┐рдзрд┐ рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рд╕рд╛рдорд╛рдиреНрдп рддрд░реНрдХреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреА рд╣реИред
Variadic рдЬреЗрдиреЗрд░рд┐рдХ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рд╣реЛрдЧрд╛ред Variadic рдЬреЗрдиреЗрд░рд┐рдХ рдЖрдкрдХреЛ рдХрдИ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░реЛрдВ рд╕реЗ рд╕рд╛рд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреБрдЫ рдЗрд╕ рддрд░рд╣:


  static func buildBlock<тАжComponent>(Component...) -> TupleView<(Component...)> where Component: View 

рдФрд░ Apple рдмрд╕ рдЗрд╕реЗ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рд╣реИред рд╕рдм рдХреБрдЫ рдЗрд╕ рддрдВрддреНрд░ рдХреЗ рдЦрд┐рд▓рд╛рдл рд╣реИред рдФрд░ рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЗрд╕реЗ рдХреЗрд╡рд▓ WWDC 2019 рддрдХ рдЦрддреНрдо рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдирд╣реАрдВ рдХрд┐рдпрд╛ (рд▓реЗрдХрд┐рди рдпрд╣ рдХреЗрд╡рд▓ рдЕрдЯрдХрд▓реЗрдВ рд╣реИрдВ)ред

Source: https://habr.com/ru/post/hi455760/


All Articles