SwiftUI рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдореМрдЬреВрджрд╛ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рд╕рдорд╛рдзрд╛рди рдХреЛ рдЕрдкрдирд╛рдирд╛ред рднрд╛рдЧ 2

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

рддреЛ, рдЖрдЗрдП рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ рдХрд┐ рдЖрдк рд╕реНрд╡рд┐рдлреНрдЯрдпреВрдЖрдИ рдкрд░ рдПрдХ рдЖрд╡реЗрджрди рдореЗрдВ рдорд╛рдирдХ рдЖрдИрдУрдПрд╕ рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрдЗрдП рдХреНрд▓рд╛рд╕рд┐рдХ рд╕реЙрд▓реНрдпреВрд╢рди рд▓реЗрдВ: SDWebImage рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рдЪрд┐рддреНрд░ рдЕрдкрд▓реЛрдб рдХрд░реЗрдВред



рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ ImageManager рдореЗрдВ рд╕рдордЭрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХрд╣рддрд╛ рд╣реИ:

  • SDWebImageDownloader
  • SDImageCache

рдЫрд╡рд┐рдпреЛрдВ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рдХреИрд╢рд┐рдВрдЧ рдХреЗ рд▓рд┐рдПред

рдкрд░рдВрдкрд░рд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░, UIImageView рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ 2 рддрд░реАрдХреЛрдВ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

  • рдЗрд╕реА UIImageView рдХреЗ рд▓рд┐рдП рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдкрд╛рд╕ рдХрд░рдХреЗ;
  • ImageManager рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдХреНрд▓реЛрдЬрд░ рдмреНрд▓реЙрдХ рдкрд╛рд╕ рдХрд░рдХреЗ


ImageManager рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрд▓ рдЖрдорддреМрд░ рдкрд░ UIImageView рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдореЗрдВ рдпрд╛ рддреЛ рдЗрдирдХреИрдкреНрд╕реБрд▓реЗрдЯ рдХреА рдЬрд╛рддреА рд╣реИ:

extension UIImageView {
 func setup(by key: String) {
        ImageManager.sharedInstance.setImage(toImageView: self, forKey: key)
    }
}

рдпрд╛ рддреЛ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░реА рд╡рд░реНрдЧ рдореЗрдВ:

class CachedImageView : UIImageView {
    private var _imageUrl: String?
    var imageUrl: String?  {
        get {
            return _imageUrl
        }
        set {
            self._imageUrl = newValue
            if let url = newValue, !url.isEmpty {
                self.setup(by: url)
            }
        }
    }
    
    func setup(by key: String) {
        ImageManager.sharedInstance.setImage(toImageView: self, forKey: key)
    }
}

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

- рд╕рдВрд░рдЪрдирд╛ред рд╡рдВрд╢рд╛рдиреБрдХреНрд░рдо рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ


- рд╕рд╛рдорд╛рдиреНрдп рдЕрд░реНрдереЛрдВ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рдмреЗрдХрд╛рд░ рд╣реИред рдмреЗрд╢рдХ , рд╣рдо рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рддрд░реАрдХреЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рдЗрд╕реЗ рдбреЗрдЯрд╛рдлрд╝реНрд▓реЛ рдореЗрдВ рдмрд╛рдБрдзрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ;

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

рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП, рд╣рдо рд╡реНрдпреВ рд╕рд╛рдЗрдб рд╕реЗ рдФрд░ рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣ рдЕрдиреБрдХреВрд▓рди рдкрдХреНрд╖ рд╕реЗ рджреЛрдиреЛрдВ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрдЗрдП рджреЗрдЦреЗрдВ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВред

рд╢реБрд░реБрдЖрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рд╕реНрд╡рд┐рдлреНрдЯрдпреВрдЖрдИ рдЦреБрдж рд╕реЗ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпреВрдЖрдИрдХреИрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдРрдб-рдСрди рдХреЗ рд░реВрдк рдореЗрдВред SwiftUI рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ SwiftUI UIView рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рддрдВрддреНрд░ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдПрдирд╛рд▓реЙрдЧреНрд╕ рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдирд┐рдпрдВрддреНрд░рдгреЛрдВ рдореЗрдВ рд╕реЗ рдирд╣реАрдВ рд╣реИрдВред рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рдХреНрд░рдорд╢рдГ UIView рдФрд░ UIViewController рдХреЛ рдЕрдкрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП UIViewRepresentable рдФрд░ UIViewControllerRepresentable рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╣реИрдВред

рдПрдХ рдРрд╕реА рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдПрдВ рдЬреЛ рдПрдХ UIViewRepresentable рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рддрд░реАрдХреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

  • makeUiView;
  • updateUIView

рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдХрд┐рд╕ рдпреВрдЖрдИрд╡рд╛рдИрдпреВрд╡рд╛рдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдФрд░ рдЙрдирдХреА рдмреБрдирд┐рдпрд╛рджреА рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рд╕реЗрдЯ рдХрд░реЗрдВред рдФрд░ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдЧреБрдгреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░реЙрдкрд░реНрдЯреАрд╡реИрдкрд░реНрд╕ рдХреЛ рдордд рднреВрд▓рдирд╛ред

struct WrappedCachedImage : UIViewRepresentable {
    let height: CGFloat
    @State var imageUrl: String
    
    func makeUIView(context: Context) -> CachedImageView {
        let frame = CGRect(x: 20, y: 0, width: UIScreen.main.bounds.size.width - 40, 
                                     height: height)
        return CachedImageView(frame: frame)
    }
    
    func updateUIView(_ uiView: CachedImageView, context: Context) {
        uiView.imageUrl = imageUrl
        uiView.contentMode = .scaleToFill
    }
}

рд╣рдо View SwiftUI рдореЗрдВ рдкрд░рд┐рдгрд╛рдореА рдирдП рдирд┐рдпрдВрддреНрд░рдг рдХреЛ рдПрдореНрдмреЗрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:



рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдлрд╛рдпрджреЗ рд╣реИрдВ:

  • рдХрд┐рд╕реА рдореМрдЬреВрджрд╛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ
  • рддрд░реНрдХ рдПрдореНрдмреЗрдбреЗрдб UIView рдореЗрдВ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╣реИред

рд▓реЗрдХрд┐рди рдирдИ рдЬрд┐рдореНрдореЗрджрд╛рд░рд┐рдпрд╛рдВ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ View-UIView рдмрдВрдбрд▓ рдореЗрдВ рдореЗрдореЛрд░реА рдкреНрд░рдмрдВрдзрди рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рджреГрд╢реНрдп рд╕рдВрд░рдЪрдирд╛ рд╣реИ, рддреЛ рдЙрдирдХреЗ рд╕рд╛рде рд╕рднреА рдХрд╛рд░реНрдп рдкреГрд╖реНрдарднреВрдорд┐ рдореЗрдВ рд░реВрдкрд░реЗрдЦрд╛ рджреНрд╡рд╛рд░рд╛ рд╣реА рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдирдИ рд╡рд╕реНрддреБрдУрдВ рдХреА рд╕рдлрд╛рдИ рдбреЗрд╡рд▓рдкрд░ рдХреЗ рдХрдВрдзреЛрдВ рдкрд░ рдЖрддреА рд╣реИред

рджреВрд╕рд░реЗ, рдЕрдиреБрдХреВрд▓рди (рдЖрдХрд╛рд░, рд╢реИрд▓реА) рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдЪрд░рдгреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрджрд┐ рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рдпреЗ рд╡рд┐рдХрд▓реНрдк рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕рдХреНрд╖рдо рд╣реИрдВ, рддреЛ рдЙрдиреНрд╣реЗрдВ UIView рдХреЗ рд╕рд╛рде рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдХрд╛рд░реЛрдВ рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЬреНрдпреЛрдореЗрдЯреНрд░реАрд░реАрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╣рдорд╛рд░реА рдЫрд╡рд┐ рд╕реНрдХреНрд░реАрди рдХреА рдкреВрд░реА рдЪреМрдбрд╝рд╛рдИ рдФрд░ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдКрдВрдЪрд╛рдИ рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░ рд▓реЗ:

 var body: some View {
      GeometryReader { geometry in 
        VStack {
           WrappedCachedImage(height:300, imageUrl: imageUrl) 
           .frame(minWidth: 0, maxWidth: geometry.size.width,
                     minHeight: 0, maxHeight: 300)
        }
    }
}

рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рдПрдореНрдмреЗрдбреЗрдб рдпреВрдЗрд╡реАрдпреВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдЕрддрд┐рд╡реНрдпрд╛рдкреА рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред рддреЛ рдЕрдм DataFlow SwiftUI рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред

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

рд╣рдо рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:

  • рдПрдХ рдХрд╕реНрдЯрдо рджреГрд╢реНрдп рдмрдирд╛рдПрдВ, рдЬрд┐рд╕рдХреЗ рдЕрдВрджрд░ рд╣рдо рд╕реНрд╡рд┐рдлреНрдЯрдпреВрдЖрдИ рдирд┐рдпрдВрддреНрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ;
  • рдПрдХ ViewModel рдмрдирд╛рдПрдВ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдореЙрдбрд▓ (ImageManager) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реНрдХ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред


рдЖрджреЗрд╢ рджреЗрдЦреЗрдВ рдФрд░ ViewModel рдХреЗ рдмреАрдЪ рдПрдХ рдХрдиреЗрдХреНрд╢рди рд╣реЛ рд╕рдХреЗрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП ViewModel рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП ObservableObject рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдФрд░ рдПрдХ рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦреЗрдВ рд╕реЗ рдХрдиреЗрдХреНрдЯ ObservedObject ред

class CachedImageModel : ObservableObject {
    @Published var image: UIImage = UIImage()
    
    private var urlString: String = ""
    
    init(urlString:String) {
        self.urlString = urlString
    }
    
    func loadImage() {
        ImageManager.sharedInstance
        .receiveImage(forKey: urlString) {[weak self] (im) in
            guard let self = self else {return}
            DispatchQueue.main.async {
                self.image = im
            }
        }
    }
}

рдЕрдкрдиреЗ рдЬреАрд╡рди-рдЪрдХреНрд░ рдХреА рдСрдирдкреЗрдпрд░ рд╡рд┐рдзрд┐ рдореЗрдВ рджреЗрдЦреЗрдВ ViewModel рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА @ рдЧреБрдгрд┐рдд рд╕рдВрдкрддреНрддрд┐ рд╕реЗ рдЕрдВрддрд┐рдо рдЫрд╡рд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ:

struct CachedLoaderImage : View {
    @ObservedObject var  model:CachedImageModel
    
    init(withURL url:String) {
        self.model = CachedImageModel(urlString: url)
    }
    
    var body: some View {
        Image(uiImage: model.image)
            .resizable()
            .onAppear{
                self.model.loadImage()
        }
    }
    
}

DataFlow SwiftUI рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдШреЛрд╖рдгрд╛рддреНрдордХ рд╕рдВрдпреБрдХреНрдд рдПрдкреАрдЖрдИ рднреА рд╣реИ ред рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдЪреМрдЦрдЯреЗ (рдПрдХ рд╣реА RxSwift) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд╕рдорд╛рди рд╣реИ: рдЗрд╕рдореЗрдВ рд╡рд┐рд╖рдп рд╣реИрдВ, рдЧреНрд░рд╛рд╣рдХ рд╣реИрдВ, рд╕рдорд╛рди рдкреНрд░рдмрдВрдзрди рд╡рд┐рдзрд┐рдпрд╛рдВ рд╣реИрдВ, рд░рджреНрдж рдХрд░рдиреЗ рдпреЛрдЧреНрдп (рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рдХреЗ рдмрдЬрд╛рдп) рд╣реИрдВред

class ImageLoader: ObservableObject {
 @Published var image: UIImage?
 private var cancellable: AnyCancellable?

 func load(url: String) {
     cancellable = ImageManager.sharedInstance.publisher(for: url)
         .map { UIImage(data: $0.data) }
         .replaceError(with: nil)
         .receive(on: DispatchQueue.main)
         .assign(to: \.image, on: self)
 }

рдпрджрд┐ рд╣рдорд╛рд░рд╛ ImageManager рдореВрд▓ рд░реВрдк рд╕реЗ Combine рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рд╕рдорд╛рдзрд╛рди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛ред

рд▓реЗрдХрд┐рди рдЬрдмрд╕реЗ ImageManager рдХреЛ рдЕрдиреНрдп рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЗ рд╕рд╛рде рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рд╣рдо рджреВрд╕рд░рд╛ рддрд░реАрдХрд╛ рдЖрдЬрдорд╛рдПрдВрдЧреЗред рдПрдХ рдШрдЯрдирд╛ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо PasstroughSubject рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рд╕рджрд╕реНрдпрддрд╛ рдХреЗ рд╕реНрд╡рдд: рдкреВрд░реНрдг рд╣реЛрдиреЗ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред

    var didChange = PassthroughSubject<UIImage, Never>()

рд╣рдо рдЕрдкрдиреЗ рдореЙрдбрд▓ рдХреА UIImage рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╕рдордп рдПрдХ рдирдпрд╛ рдореВрд▓реНрдп рднреЗрдЬреЗрдВрдЧреЗ:

var data = UIImage() {
        didSet {
            didChange.send(data)
        }
    }
 ,    .

рд╣рдорд╛рд░реЗ рджреГрд╢реНрдп рдХрд╛ рдЕрдВрддрд┐рдо рдорд╛рди onReceive рдкрджреНрдзрддрд┐ рдореЗрдВ "рд╕реБрдирддрд╛ рд╣реИ":

 var body: some View {
       Image(uiImage: image)
            .onReceive(imageLoader.didChange) { im in
            self.image = im
           //-   
        }
    }

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

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

SwiftUI рдХреЗ рддрд╣рдд View рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдБ рджреЗрдЦреЗрдВ ред

All Articles