load from api
This commit is contained in:
parent
efc7773c04
commit
a02fa53902
58
Shared/Components/RemoteImageView.swift
Normal file
58
Shared/Components/RemoteImageView.swift
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import SwiftUI
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
// 1. Класс для загрузки изображения
|
||||||
|
class ImageLoader: ObservableObject {
|
||||||
|
@Published var image: UIImage?
|
||||||
|
private var cancellable: AnyCancellable?
|
||||||
|
private let url: URL
|
||||||
|
|
||||||
|
init(url: URL) {
|
||||||
|
self.url = url
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
cancellable?.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
func load() {
|
||||||
|
cancellable = URLSession.shared.dataTaskPublisher(for: url)
|
||||||
|
.map { UIImage(data: $0.data) }
|
||||||
|
.replaceError(with: nil)
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.assign(to: \.image, on: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cancel() {
|
||||||
|
cancellable?.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. View для отображения удаленного изображения
|
||||||
|
struct RemoteImageView: View {
|
||||||
|
@StateObject private var loader: ImageLoader
|
||||||
|
private let placeholder: Image
|
||||||
|
|
||||||
|
init(url: URL, placeholder: Image = Image("placeholderPhoto")) {
|
||||||
|
_loader = StateObject(wrappedValue: ImageLoader(url: url))
|
||||||
|
self.placeholder = placeholder
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
content
|
||||||
|
.onAppear(perform: loader.load)
|
||||||
|
.onDisappear(perform: loader.cancel)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var content: some View {
|
||||||
|
Group {
|
||||||
|
if let image = loader.image {
|
||||||
|
Image(uiImage: image)
|
||||||
|
.resizable()
|
||||||
|
} else {
|
||||||
|
placeholder
|
||||||
|
.resizable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -50,15 +50,24 @@ struct PostGridItem: View {
|
|||||||
let post: Post
|
let post: Post
|
||||||
let width: CGFloat // Ширина элемента
|
let width: CGFloat // Ширина элемента
|
||||||
|
|
||||||
|
// Формируем URL для загрузки изображения
|
||||||
|
private var imageURL: URL? {
|
||||||
|
// Используем picsum.photos для получения уникального изображения для каждого поста
|
||||||
|
URL(string: "https://picsum.photos/seed/\(post.id.uuidString)/400/400")
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 0) { // Убираем отступ между картинкой и текстом
|
VStack(alignment: .leading, spacing: 0) { // Убираем отступ между картинкой и текстом
|
||||||
// 1. Медиа контент
|
// 1. Медиа контент
|
||||||
if let _ = post.media.first {
|
if let url = imageURL {
|
||||||
Image("placeholderPhoto")
|
// Создаем контейнер с четкими границами, чтобы избежать перекрытия
|
||||||
.resizable()
|
Color.clear
|
||||||
.scaledToFill() // Заполняем кадр, сохраняя пропорции
|
.frame(width: width, height: width)
|
||||||
.frame(width: width, height: width) // Устанавливаем жесткий размер
|
.background(
|
||||||
.clipped() // Обрезаем лишнее
|
RemoteImageView(url: url)
|
||||||
|
.scaledToFill()
|
||||||
|
)
|
||||||
|
.clipped()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Контейнер для текста, который создает эффект "расширения"
|
// Контейнер для текста, который создает эффект "расширения"
|
||||||
|
|||||||
@ -37,6 +37,7 @@
|
|||||||
1A9B016E2E4BFB9000887E0B /* NewHomeTabViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A9B016D2E4BFB9000887E0B /* NewHomeTabViewModel.swift */; };
|
1A9B016E2E4BFB9000887E0B /* NewHomeTabViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A9B016D2E4BFB9000887E0B /* NewHomeTabViewModel.swift */; };
|
||||||
1A9B017C2E4C087F00887E0B /* SideMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A9B017B2E4C087F00887E0B /* SideMenuView.swift */; };
|
1A9B017C2E4C087F00887E0B /* SideMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A9B017B2E4C087F00887E0B /* SideMenuView.swift */; };
|
||||||
1A9E4FB32E4D6A67002249D6 /* ThemeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A9E4FB22E4D6A67002249D6 /* ThemeManager.swift */; };
|
1A9E4FB32E4D6A67002249D6 /* ThemeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A9E4FB22E4D6A67002249D6 /* ThemeManager.swift */; };
|
||||||
|
1A9E4FD72E4E47EF002249D6 /* RemoteImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A9E4FD62E4E47EF002249D6 /* RemoteImageView.swift */; };
|
||||||
1AB4F8CD2E22E341002B6E40 /* AccountShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB4F8CC2E22E341002B6E40 /* AccountShareSheet.swift */; };
|
1AB4F8CD2E22E341002B6E40 /* AccountShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB4F8CC2E22E341002B6E40 /* AccountShareSheet.swift */; };
|
||||||
1AB4F8F32E22EC9F002B6E40 /* FollowersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB4F8F22E22EC9F002B6E40 /* FollowersView.swift */; };
|
1AB4F8F32E22EC9F002B6E40 /* FollowersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB4F8F22E22EC9F002B6E40 /* FollowersView.swift */; };
|
||||||
1AB4F8F72E22ECAC002B6E40 /* FollowingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB4F8F62E22ECAC002B6E40 /* FollowingView.swift */; };
|
1AB4F8F72E22ECAC002B6E40 /* FollowingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB4F8F62E22ECAC002B6E40 /* FollowingView.swift */; };
|
||||||
@ -92,6 +93,7 @@
|
|||||||
1A9B016D2E4BFB9000887E0B /* NewHomeTabViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewHomeTabViewModel.swift; sourceTree = "<group>"; };
|
1A9B016D2E4BFB9000887E0B /* NewHomeTabViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewHomeTabViewModel.swift; sourceTree = "<group>"; };
|
||||||
1A9B017B2E4C087F00887E0B /* SideMenuView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SideMenuView.swift; sourceTree = "<group>"; };
|
1A9B017B2E4C087F00887E0B /* SideMenuView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SideMenuView.swift; sourceTree = "<group>"; };
|
||||||
1A9E4FB22E4D6A67002249D6 /* ThemeManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeManager.swift; sourceTree = "<group>"; };
|
1A9E4FB22E4D6A67002249D6 /* ThemeManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeManager.swift; sourceTree = "<group>"; };
|
||||||
|
1A9E4FD62E4E47EF002249D6 /* RemoteImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoteImageView.swift; sourceTree = "<group>"; };
|
||||||
1AB4F8CC2E22E341002B6E40 /* AccountShareSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountShareSheet.swift; sourceTree = "<group>"; };
|
1AB4F8CC2E22E341002B6E40 /* AccountShareSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountShareSheet.swift; sourceTree = "<group>"; };
|
||||||
1AB4F8F22E22EC9F002B6E40 /* FollowersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowersView.swift; sourceTree = "<group>"; };
|
1AB4F8F22E22EC9F002B6E40 /* FollowersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowersView.swift; sourceTree = "<group>"; };
|
||||||
1AB4F8F62E22ECAC002B6E40 /* FollowingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingView.swift; sourceTree = "<group>"; };
|
1AB4F8F62E22ECAC002B6E40 /* FollowingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingView.swift; sourceTree = "<group>"; };
|
||||||
@ -257,6 +259,7 @@
|
|||||||
1AB7F5132E32EBF1003756F3 /* Components */ = {
|
1AB7F5132E32EBF1003756F3 /* Components */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
1A9E4FD62E4E47EF002249D6 /* RemoteImageView.swift */,
|
||||||
1AB7F5142E32EC1C003756F3 /* RefreshableScrollView.swift */,
|
1AB7F5142E32EC1C003756F3 /* RefreshableScrollView.swift */,
|
||||||
1AB7F5152E32EC1C003756F3 /* TopBarView.swift */,
|
1AB7F5152E32EC1C003756F3 /* TopBarView.swift */,
|
||||||
);
|
);
|
||||||
@ -429,6 +432,7 @@
|
|||||||
1AEE5EAB2E21A83200A3DCA3 /* HomeTab.swift in Sources */,
|
1AEE5EAB2E21A83200A3DCA3 /* HomeTab.swift in Sources */,
|
||||||
1ACE60F82E22F3DC00B37AC5 /* SettingsView.swift in Sources */,
|
1ACE60F82E22F3DC00B37AC5 /* SettingsView.swift in Sources */,
|
||||||
1AD757CD2E27608C0069C1FD /* PostFeedView.swift in Sources */,
|
1AD757CD2E27608C0069C1FD /* PostFeedView.swift in Sources */,
|
||||||
|
1A9E4FD72E4E47EF002249D6 /* RemoteImageView.swift in Sources */,
|
||||||
1A9B017C2E4C087F00887E0B /* SideMenuView.swift in Sources */,
|
1A9B017C2E4C087F00887E0B /* SideMenuView.swift in Sources */,
|
||||||
1A7940C62DF7A98E002569DA /* ContactsTab.swift in Sources */,
|
1A7940C62DF7A98E002569DA /* ContactsTab.swift in Sources */,
|
||||||
1ACE61092E22F57100B37AC5 /* AppPreferencesView.swift in Sources */,
|
1ACE61092E22F57100B37AC5 /* AppPreferencesView.swift in Sources */,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user