рд╕рдордЧреНрд░ "рдбреЗрдЯрд╛рд╕реЛрд░реНрд╕" рдСрдмреНрдЬреЗрдХреНрдЯ рдФрд░ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рддрддреНрд╡

рдПрдХ рдмрд╛рд░, рдореИрдВрдиреЗ (рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдореБрдЭреЗ рднреА рдирд╣реАрдВ) рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреА рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рд╕рд╛рде UICollectionView рд▓рд┐рдП рдПрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рдХреА рдПрдХ рд╕реЗрд▓ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛, рдФрд░ рдХреЗрд╡рд▓ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ рдореЗрдВ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЬреЛ "рдКрдкрд░" рд╕рдВрд╕рд╛рдзрд┐рдд рд╣реЛрддрд╛ рд╣реИ рдФрд░ рд╕реАрдзреЗ UICollectionView рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдХрд╛рд░реНрдп рдиреЗ рд╡реГрджреНрдзрд┐ рджреА, рдЕрдЧрд░ рдореЗрд░реА рд╕реНрдореГрддрд┐ рдореБрдЭреЗ рдмрджрд╕реВрд░рдд рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреЛ рд╕реЗрд╡рд╛ рджреЗрддреА рд╣реИ, if - UICollectionViewDataSource рдФрд░ UICollectionViewDelegate рдЕрдВрджрд░ рдмреНрд▓реЙрдХ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ "рдЙрддреНрдкрд╛рджрди" рдХреЛрдб рдореЗрдВ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдмрд╕реЗ рд╣реИрдВ рдФрд░, рд╢рд╛рдпрдж, рд╡рд╣рд╛рдВ рд╕реЗ рдХрд╣реАрдВ рднреА рдирд╣реАрдВ рдЬрд╛рдПрдВрдЧреЗред

рдЙрдкрд░реНрдпреБрдХреНрдд рдХрд╛рд░реНрдп рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░, рдХрд┐рд╕реА рднреА рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рдкрд░ рд╕реЛрдЪрдиреЗ рдпрд╛ рдЗрд╕ рдкрд░ "рд╡рд┐рдЪрд╛рд░рд╢реАрд▓" рдКрд░реНрдЬрд╛ рдмрд░реНрдмрд╛рдж рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рдерд╛ред рдлрд┐рд░ рднреА, рдореБрдЭреЗ рдпрд╣ рдХрд╣рд╛рдиреА рдпрд╛рдж рд╣реИ: рдореИрдВрдиреЗ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд "рдбреЗрдЯрд╛рд╕реЛрд░реНрд╕" рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрд╛ рдерд╛, рдЬреЛ рдХрд┐рд╕реА рднреА "рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд" рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рдХрд┐рд╕реА рднреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдПрдХ рдкреВрд░реЗ рдореЗрдВ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИред рд╕рдорд╛рдзрд╛рди, рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ, рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХрд┐рд╕реА рднреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдШрдЯрдХреЛрдВ (рд╢реВрдиреНрдп рдФрд░ рдПрдХ рд╕рд╣рд┐рдд) рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИ рдФрд░ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рд╣реИред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдпрд╣ рди рдХреЗрд╡рд▓ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╣реИ, рдмрд▓реНрдХрд┐ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рднреА рдирд╣реАрдВ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдХреЛрдб рдХреЛ "рд╕реБрдВрджрд░" рдмрдирд╛рдирд╛ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реИ)ред

рдореИрдВ рдпрд╣ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдореИрдВрдиреЗ UITableView рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд┐рдпрд╛ред рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ, рддреЛ UICollectionView рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдХреЛрдб рд▓рд┐рдЦрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

"рдПрдХ рд╡рд┐рдЪрд╛рд░ рд╣рдореЗрд╢рд╛ рдЕрдкрдиреЗ рдЕрд╡рддрд╛рд░ рд╕реЗ рдЕрдзрд┐рдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реЛрддрд╛ рд╣реИ"


рдпрд╣ рдХрд╛рдореЛрддреНрддреЗрдЬрдирд╛ рдорд╣рд╛рди рдХреЙрдорд┐рдХ рдмреБрдХ рдХреЗ рд▓реЗрдЦрдХ рдПрд▓рди рдореВрд░ ( "рдХреАрдкрд░реНрд╕" , "V рдХрд╛ рдЕрд░реНрде рд╡реЗрдВрдбреЗрдЯреНрдЯрд╛ рдХреЗ рд▓рд┐рдП рд╣реИ , " "рд▓реАрдЧ рдСрдлрд╝ рдЖрдЙрдЯрд╕реНрдЯреИрдВрдбрд┐рдВрдЧ рдЬреЗрдВрдЯрд▓рдореЗрди" ) рд╕реЗ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рд╣реИ рдирд╛?

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

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

 protocol ComposableTableViewDataSource: UITableViewDataSource { var numberOfSections: Int { get } func numberOfRows(for section: Int) -> Int } 

рдФрд░ рд╕рдордЧреНрд░ "рдбреЗрдЯрд╛рд╕реЛрд░реНрд╕" рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╡рд░реНрдЧ рдирд┐рдХрд▓рд╛, рдЬреЛ UITableViewDataSource рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХреЗрд╡рд▓ рдПрдХ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдЖрд░рдВрдн рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - ComposableTableViewDataSource рдХреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ:

 final class ComposedTableViewDataSource: NSObject, UITableViewDataSource { private let dataSources: [ComposableTableViewDataSource] init(dataSources: ComposableTableViewDataSource...) { self.dataSources = dataSources super.init() } private override init() { fatalError("\(#file) \(#line): Initializer with parameters must be used.") } } 

рдЕрдм рдпрд╣ рдХреЗрд╡рд▓ UITableViewDataSource рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд╕рднреА рддрд░реАрдХреЛрдВ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ рдХрд┐ рд╡реЗ рд╕рдВрдмрдВрдзрд┐рдд рдШрдЯрдХреЛрдВ рдХреЗ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рддреЗ рд╣реИрдВред

тАЬрдпрд╣ рд╕рд╣реА рдирд┐рд░реНрдгрдп рдерд╛ред рдореЗрд░рд╛ рдлреИрд╕рд▓рд╛


рдпреЗ рд╢рдмреНрдж рд░реВрд╕реА рд╕рдВрдШ рдХреЗ рдкрд╣рд▓реЗ рдЕрдзреНрдпрдХреНрд╖ рдмреЛрд░рд┐рд╕ рдирд┐рдХреЛрд▓рд╛рдпреЗрд╡рд┐рдЪ рдпреЗрд▓реНрддрд╕рд┐рди рдХреЗ рдереЗ, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдкрд╛рда рдХрд╛ рд╕рдВрджрд░реНрдн рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВ, рдореБрдЭреЗ рдмрд╕ рдЙрдиреНрд╣реЗрдВ рдкрд╕рдВрдж рдЖрдпрд╛ред

рд╕рд╣реА рдирд┐рд░реНрдгрдп рдореБрдЭреЗ рд╕реНрд╡рд┐рдлреНрдЯ рднрд╛рд╖рд╛ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рдЧ рд░рд╣рд╛ рдерд╛, рдФрд░ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд┐рдХрд▓рд╛ред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдПрдХ рд╡рд┐рдзрд┐ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╡рд░реНрдЧреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ - рдпрд╣ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╣рдореЗрдВ рдШрдЯрдХреЛрдВ рдХреЗ рд╕рднреА рд╡рд░реНрдЧреЛрдВ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

 func numberOfSections(in tableView: UITableView) -> Int { // Default value if not implemented is "1". return dataSources.reduce(0) { $0 + ($1.numberOfSections?(in: tableView) ?? 1) } } 

(рдореИрдВ рдорд╛рдирдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдФрд░ рдЕрд░реНрде рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдирд╣реАрдВ рдХрд░реВрдБрдЧрд╛ред рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдЗрдВрдЯрд░рдиреЗрдЯ рд╡рд┐рд╖рдп рдкрд░ рдЕрдЪреНрдЫреЗ рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ рд▓реЗрдЦреЛрдВ рд╕реЗ рднрд░рд╛ рд╣реИред рдФрд░ рдореИрдВ рдПрдХ рдЕрдЪреНрдЫреА рдкреБрд╕реНрддрдХ рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рднреА рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред)

UITableViewDataSource рдХреА рд╕рднреА рд╡рд┐рдзрд┐рдпреЛрдВ рдкрд░ рдПрдХ рддреНрд╡рд░рд┐рдд рдирдЬрд╝рд░, рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реЗ рдХреЗрд╡рд▓ рддрд╛рд▓рд┐рдХрд╛ рдХреА рдПрдХ рдХрдбрд╝реА рдФрд░ рдЕрдиреБрднрд╛рдЧ рд╕рдВрдЦреНрдпрд╛ рдпрд╛ рд╕рдВрдмрдВрдзрд┐рдд IndexPath рдкрдВрдХреНрддрд┐ рдХреЗ рдореВрд▓реНрдп рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдХреБрдЫ рд╕рд╣рд╛рдпрдХ рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рдЕрдиреНрдп рд╕рднреА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдВрдЧреЗред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдПрдХ "рдЬреЗрдиреЗрд░рд┐рдХ" рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдХрдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ ComposableTableViewDataSource рдФрд░ рдЕрдиреБрднрд╛рдЧ рд╕рдВрдЦреНрдпрд╛ рдпрд╛ IndexPath рдХреЗ рдореВрд▓реНрдп рдХреЗ рд╕рдВрджрд░реНрдн рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддрд╛ рд╣реИред рд╕реБрд╡рд┐рдзрд╛ рдФрд░ рд╕рдВрдХреНрд╖рд┐рдкреНрддрддрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЫрджреНрдо рд╢рдмреНрдж рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред рд╕рд╛рде рд╣реА, рдЕрддрд┐рд░рд┐рдХреНрдд рдкрдардиреАрдпрддрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЦрдВрдб рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдирд╛рдо рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП:

 private typealias SectionNumber = Int private typealias AdducedSectionTask<T> = (_ composableDataSource: ComposableTableViewDataSource, _ sectionNumber: SectionNumber) -> T private typealias AdducedIndexPathTask<T> = (_ composableDataSource: ComposableTableViewDataSource, _ indexPath: IndexPath) -> T 

(рдореИрдВ рдиреАрдЪреЗ рдЪрдпрдирд┐рдд рдирд╛рдореЛрдВ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░реВрдВрдЧрд╛ред)

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

 private func decompose(section: SectionNumber) -> (dataSource: ComposableTableViewDataSource, decomposedSection: SectionNumber) { var section = section var dataSourceIndex = 0 for (index, dataSource) in dataSources.enumerated() { let diff = section - dataSource.numberOfSections dataSourceIndex = index if diff < 0 { break } else { section = diff } } return (dataSources[dataSourceIndex], section) } 

рд╢рд╛рдпрдж, рдпрджрд┐ рдЖрдк рдореЗрд░реЗ рдореБрдХрд╛рдмрд▓реЗ рдереЛрдбрд╝рд╛ рд▓рдВрдмрд╛ рд╕реЛрдЪрддреЗ рд╣реИрдВ, рддреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдФрд░ рдХрдо рд╕реАрдзрд╛ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореЗрд░реЗ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдиреЗ рддреБрд░рдВрдд рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдХрд┐ рдореИрдВ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдЦреЛрдЬ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реВрдВ (рдкрд╣рд▓реЗ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрд░рдВрднреАрдХрд░рдг рдХреЗ рджреМрд░рд╛рди, рд╡рд░реНрдЧреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдХреА рд░рдЪрдирд╛ рдХрд░рдХреЗ - рдкреВрд░реНрдгрд╛рдВрдХ рдХрд╛ рдПрдХ рд╕рд░рд▓ рд╕рд░рдгреА )ред рдпрд╛ рдЕрдиреБрднрд╛рдЧ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рдкрддреНрд░рд╛рдЪрд╛рд░ рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдФрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдореЗрдВ рднреА рдереЛрдбрд╝рд╛ рд╕рдордп рд╡реНрдпрддреАрдд рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд░ O (n) рдпрд╛ O (log n) рдХреА рд╕рдордп рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рд╕рд╛рде рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЖрдк O (1) рдХреА рд▓рд╛рдЧрдд рдкрд░ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рд╕реНрдкрд╖реНрдЯ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдФрд░ рдЙрдЪрд┐рдд рдорд╛рдк рдХреЗ рдмрд┐рдирд╛ рд╕рдордп рд╕реЗ рдкрд╣рд▓реЗ рдЕрдиреБрдХреВрд▓рди рдореЗрдВ рд╕рдВрд▓рдЧреНрди рди рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдорд╣рд╛рди рдбреЛрдирд╛рд▓реНрдб рдирде рдХреА рд╕рд▓рд╛рд╣ рд▓реЗрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рд╣рд╛рдВ, рдФрд░ рдЗрд╕ рд▓реЗрдЦ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВред

рдФрд░ рдЕрдВрдд рдореЗрдВ, рдХрд╛рд░реНрдп рдЬреЛ AdducedSectionTask рдФрд░ AdducedIndexPathTask рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдКрдкрд░ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ AdducedIndexPathTask рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП "рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ" рдХрд░рддреЗ рд╣реИрдВ:

 private func adduce<T>(_ section: SectionNumber, _ task: AdducedSectionTask<T>) -> T { let (dataSource, decomposedSection) = decompose(section: section) return task(dataSource, decomposedSection) } private func adduce<T>(_ indexPath: IndexPath, _ task: AdducedIndexPathTask<T>) -> T { let (dataSource, decomposedSection) = decompose(section: indexPath.section) return task(dataSource, IndexPath(row: indexPath.row, section: decomposedSection)) } 

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

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

рдпреЗ рд╕рднреА рддреИрдпрд╛рд░реА рдФрд░ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░реВрдк рд╕реЗ рд▓рд╛рдн рджреЗрддреЗ рд╣реИрдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗред рддрд╛рд▓рд┐рдХрд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╡рд┐рдзрд┐рдпрд╛рдБ:

 func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return adduce(section) { $0.tableView?(tableView, titleForHeaderInSection: $1) } } func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { return adduce(section) { $0.tableView?(tableView, titleForFooterInSection: $1) } } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return adduce(section) { $0.tableView(tableView, numberOfRowsInSection: $1) } } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { return adduce(indexPath) { $0.tableView(tableView, cellForRowAt: $1) } } 

рдкрдВрдХреНрддрд┐рдпрд╛рдБ рдбрд╛рд▓реЗрдВ рдФрд░ рд╣рдЯрд╛рдПрдВ:

 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { return adduce(indexPath) { $0.tableView?(tableView, commit: editingStyle, forRowAt: $1) } } func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { // Default if not implemented is "true". return adduce(indexPath) { $0.tableView?(tableView, canEditRowAt: $1) ?? true } } 

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

"рдЕрд╕рдВрднрд╡ рдЖрдЬ рдХрд▓ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛"


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

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

рджреВрд╕рд░реЗ, рдФрд░ рдЕрдзрд┐рдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд, рд╕реНрдХреНрд░реАрди рдкрд░ рдбреЗрдЯрд╛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрдВрддреНрд░ рдкрд░ рд╕реЛрдЪрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ ComposableTableViewDataSource рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреЗ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рддрд░реАрдХреЗ ComposableTableViewDataSource рджреНрд╡рд╛рд░рд╛ рд▓рд╛рдЧреВ рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗ рдФрд░ рдПрдХ рд╕рдВрдХреЗрдд рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧрд╛ рдХрд┐ рдореВрд▓ "рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд" рдХреЛ рдПрдХ рдЕрджреНрдпрддрди рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖ рд╣реИред рджреЛ рдкреНрд░рд╢реНрди рдЦреБрд▓реЗ рд░рд╣рддреЗ рд╣реИрдВ: рдпрд╣ рдХреИрд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ ComposableTableViewDataSource рдХрд┐ рдХреМрди рд╕рд╛ ComposableTableViewDataSource рдЕрдВрджрд░ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ рдФрд░ рдпрд╣ рдХреИрд╕реЗ рдПрдХ рдЕрд▓рдЧ рдФрд░ рд╕рдмрд╕реЗ рддреБрдЪреНрдЫ рдХрд╛рд░реНрдп рд╣реИ, рд▓реЗрдХрд┐рди рдХрдИ рд╕рдорд╛рдзрд╛рди рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдРрд╕реЗ )ред рдФрд░, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдЖрдкрдХреЛ ComposedTableViewDataSource рдкреНрд░рддрд┐рдирд┐рдзрд┐ ComposedTableViewDataSource рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЬрд┐рдирдореЗрдВ рд╕реЗ рддрд░реАрдХреЛрдВ рдХреЛ рд╕рдордЧреНрд░ "рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд" рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╕рдордп рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдкреНрд░рдХрд╛рд░ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдирд┐рдпрдВрддреНрд░рдХ рдпрд╛ рджреГрд╢реНрдп рдореЙрдбрд▓ ) рджреНрд╡рд╛рд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдореИрдВ рд╕рдордп рдХреЗ рд╕рд╛рде рдЗрди рдореБрджреНрджреЛрдВ рдХреА рдмреЗрд╣рддрд░ рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд▓реЗрдЦ рдХреЗ рджреВрд╕рд░реЗ рднрд╛рдЧ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреА рдЙрдореНрдореАрдж рдХрд░рддрд╛ рд╣реВрдВред рдЗрд╕ рдмреАрдЪ, рдореИрдВ рдЦреБрд╢ рд╣реВрдБ, рдЖрдк рдЗрди рдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрд╕реБрдХ рдереЗ!

рдкреБрдирд╢реНрдЪ


рджреВрд╕рд░реЗ рджрд┐рди, рдореБрдЭреЗ рдЗрд╕реЗ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдЪрдп рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХреЛрдб рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдирд╛ рдкрдбрд╝рд╛: рдореБрдЭреЗ рдЙрди рджреЛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рд╕реНрд╡реИрдк рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдореБрдЭреЗ рдЦреБрдж рдХреЛ рддрдбрд╝рдкрд╛рдирд╛ рдерд╛ рдФрд░ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд╛рдиреЛрдВ рдореЗрдВ рд▓рдЧрд╛рддрд╛рд░ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд╡рд╛рд▓реА Index out of bounds "рдЬреАрдирд╛" рдмрдирд╛рдирд╛ рдерд╛ред рд╡рд░реНрдгрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдХреЗрд╡рд▓ рдПрдХ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рд╕рд░рдгреА рдореЗрдВ рджреЛ "рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд" рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕реНрд╡реИрдк рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред

рд╕рдВрджрд░реНрдн:
- рдкреВрд░реНрдг рдХреЛрдб рдФрд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде Playgroud
- рдореЗрд░рд╛ рдЯреНрд╡рд┐рдЯрд░

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


All Articles