fix(home): 추천 크리에이터 카드를 화면 폭에 맞춘다
This commit is contained in:
@@ -7,6 +7,8 @@ struct MainHomeGenreCreatorSection: View {
|
|||||||
let onTapCreator: (Int) -> Void
|
let onTapCreator: (Int) -> Void
|
||||||
let onTapFollowAll: ([Int], String) -> Void
|
let onTapFollowAll: ([Int], String) -> Void
|
||||||
|
|
||||||
|
@State private var containerWidth = UIScreen.main.bounds.width
|
||||||
|
|
||||||
init(
|
init(
|
||||||
items: [HomeGenreCreatorGroupItem],
|
items: [HomeGenreCreatorGroupItem],
|
||||||
isFollowAllCompleted: @escaping (String) -> Bool = { _ in false },
|
isFollowAllCompleted: @escaping (String) -> Bool = { _ in false },
|
||||||
@@ -38,16 +40,42 @@ struct MainHomeGenreCreatorSection: View {
|
|||||||
onTapFollowAll(item.creators.map(\.creatorId), followKey)
|
onTapFollowAll(item.creators.map(\.creatorId), followKey)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
.frame(width: cardWidth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.leading, SodaSpacing.s14)
|
.padding(.leading, SodaSpacing.s14)
|
||||||
.padding(.trailing, SodaSpacing.s20)
|
.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 {
|
struct MainHomeCreatorGroupSection: View {
|
||||||
|
private static let maxProfileSize: CGFloat = 75
|
||||||
|
|
||||||
let title: String
|
let title: String
|
||||||
let showTitle: Bool
|
let showTitle: Bool
|
||||||
let creators: [HomeCreatorItem]
|
let creators: [HomeCreatorItem]
|
||||||
@@ -56,6 +84,8 @@ struct MainHomeCreatorGroupSection: View {
|
|||||||
let onTapCreator: (Int) -> Void
|
let onTapCreator: (Int) -> Void
|
||||||
let onTapFollowAll: () -> Void
|
let onTapFollowAll: () -> Void
|
||||||
|
|
||||||
|
@State private var cardWidth = UIScreen.main.bounds.width - (SodaSpacing.s14 * 2)
|
||||||
|
|
||||||
init(
|
init(
|
||||||
title: String,
|
title: String,
|
||||||
showTitle: Bool = true,
|
showTitle: Bool = true,
|
||||||
@@ -75,6 +105,8 @@ struct MainHomeCreatorGroupSection: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
let profileSize = profileSize(for: cardWidth)
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: SodaSpacing.s14) {
|
VStack(alignment: .leading, spacing: SodaSpacing.s14) {
|
||||||
if showTitle {
|
if showTitle {
|
||||||
Text(title)
|
Text(title)
|
||||||
@@ -89,12 +121,12 @@ struct MainHomeCreatorGroupSection: View {
|
|||||||
CreatorProfileItem(
|
CreatorProfileItem(
|
||||||
imageUrl: creator.creatorProfileImage,
|
imageUrl: creator.creatorProfileImage,
|
||||||
name: creator.creatorNickname,
|
name: creator.creatorNickname,
|
||||||
imageSize: CGSize(width: 75, height: 75),
|
imageSize: CGSize(width: profileSize, height: profileSize),
|
||||||
spacing: SodaSpacing.s6
|
spacing: SodaSpacing.s6
|
||||||
) {
|
) {
|
||||||
onTapCreator(creator.creatorId)
|
onTapCreator(creator.creatorId)
|
||||||
}
|
}
|
||||||
.frame(width: 75)
|
.frame(width: profileSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,13 +137,40 @@ struct MainHomeCreatorGroupSection: View {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
.padding(SodaSpacing.s14)
|
.padding(SodaSpacing.s14)
|
||||||
.frame(width: 374)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.background(cardBackground)
|
.background(cardBackground)
|
||||||
|
.background(widthReader)
|
||||||
.clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous))
|
.clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous))
|
||||||
}
|
}
|
||||||
|
|
||||||
private var columns: [GridItem] {
|
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 {
|
private var cardBackground: some View {
|
||||||
|
|||||||
Reference in New Issue
Block a user