diff --git a/SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeGenreCreatorSection.swift b/SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeGenreCreatorSection.swift index 8806efb5..fb696e0b 100644 --- a/SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeGenreCreatorSection.swift +++ b/SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeGenreCreatorSection.swift @@ -7,6 +7,8 @@ struct MainHomeGenreCreatorSection: View { let onTapCreator: (Int) -> Void let onTapFollowAll: ([Int], String) -> Void + @State private var containerWidth = UIScreen.main.bounds.width + init( items: [HomeGenreCreatorGroupItem], isFollowAllCompleted: @escaping (String) -> Bool = { _ in false }, @@ -38,16 +40,42 @@ struct MainHomeGenreCreatorSection: View { onTapFollowAll(item.creators.map(\.creatorId), followKey) } ) + .frame(width: cardWidth) } } .padding(.leading, SodaSpacing.s14) .padding(.trailing, SodaSpacing.s20) } + .background(widthReader) } } + + private var cardWidth: CGFloat { + max(0, containerWidth - (SodaSpacing.s14 * 2)) + } + + private var widthReader: some View { + GeometryReader { proxy in + Color.clear + .onAppear { + updateContainerWidth(proxy.size.width) + } + .onChange(of: proxy.size.width) { newWidth in + updateContainerWidth(newWidth) + } + } + } + + private func updateContainerWidth(_ width: CGFloat) { + guard width > 0, abs(containerWidth - width) > 0.5 else { return } + + containerWidth = width + } } struct MainHomeCreatorGroupSection: View { + private static let maxProfileSize: CGFloat = 75 + let title: String let showTitle: Bool let creators: [HomeCreatorItem] @@ -56,6 +84,8 @@ struct MainHomeCreatorGroupSection: View { let onTapCreator: (Int) -> Void let onTapFollowAll: () -> Void + @State private var cardWidth = UIScreen.main.bounds.width - (SodaSpacing.s14 * 2) + init( title: String, showTitle: Bool = true, @@ -75,6 +105,8 @@ struct MainHomeCreatorGroupSection: View { } var body: some View { + let profileSize = profileSize(for: cardWidth) + VStack(alignment: .leading, spacing: SodaSpacing.s14) { if showTitle { Text(title) @@ -89,12 +121,12 @@ struct MainHomeCreatorGroupSection: View { CreatorProfileItem( imageUrl: creator.creatorProfileImage, name: creator.creatorNickname, - imageSize: CGSize(width: 75, height: 75), + imageSize: CGSize(width: profileSize, height: profileSize), spacing: SodaSpacing.s6 ) { onTapCreator(creator.creatorId) } - .frame(width: 75) + .frame(width: profileSize) } } @@ -105,13 +137,40 @@ struct MainHomeCreatorGroupSection: View { ) } .padding(SodaSpacing.s14) - .frame(width: 374) + .frame(maxWidth: .infinity, alignment: .leading) .background(cardBackground) + .background(widthReader) .clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous)) } private var columns: [GridItem] { - Array(repeating: GridItem(.fixed(75), spacing: SodaSpacing.s14), count: 4) + Array(repeating: GridItem(.fixed(profileSize(for: cardWidth)), spacing: SodaSpacing.s14), count: 4) + } + + private var widthReader: some View { + GeometryReader { proxy in + Color.clear + .onAppear { + updateCardWidth(proxy.size.width) + } + .onChange(of: proxy.size.width) { newWidth in + updateCardWidth(newWidth) + } + } + } + + private func updateCardWidth(_ width: CGFloat) { + guard width > 0, abs(cardWidth - width) > 0.5 else { return } + + cardWidth = width + } + + private func profileSize(for width: CGFloat) -> CGFloat { + let contentWidth = width - (SodaSpacing.s14 * 2) + let spacingWidth = SodaSpacing.s14 * 3 + let availableItemWidth = (contentWidth - spacingWidth) / 4 + + return min(Self.maxProfileSize, max(0, availableItemWidth.rounded(.down))) } private var cardBackground: some View {