我最近在 TabView 的 tabViewStyle 修饰符上使用 PageTabViewStyle() 。然而我想要一个更定制的设计,如下图所示,但我不知道该怎么做。
我想要的本质上是滑动视图(我将用电影海报替换那些灰色视图),选择的中间视图应该是最大的,而旁边的其他视图较小,我希望能够水平滑动视图。怎么才能实现这个设计呢?
如果我是你,我会在 ScrollView 中使用 LazyHStack,然后使用 GeometryReader 来确定 LazyHStack 中项目的位置。最后使用scaleEffect修饰符。像这样的东西:
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 20) {
ForEach(0..<moviePosters.count, id: \.self) { index in
GeometryReader { geometry in
let scale = getScale(for: index)
let isSelected = index == selectedTabIndex
MoviePosterView(imageName: moviePosters[index], isSelected: isSelected)
.frame(width: 150, height: 200)
.scaleEffect(isSelected ? scale : 1.0)
.onTapGesture {
selectedTabIndex = index
}
.offset(x: 0, y: isSelected ? -20 : 0)
}
.frame(width: 150, height: 200)
}
}
.padding(.horizontal, 20)
}
.frame(height: 220)
}
// Calculate the scale factor based on the distance from the center item
func getScale(for index: Int) -> CGFloat {
let selectedIndex = CGFloat(selectedTabIndex)
let distance = abs(selectedIndex - CGFloat(index))
return max(1.0 - (distance * 0.2), 0.8) // Adjust the scaling factor as needed
}
let moviePosters = ["poster1", "poster2", "poster3", "poster4"] // Replace with your movie poster image names
然后还创建 MoviePosterView,如:
struct MoviePosterView: View {
var imageName: String
var isSelected: Bool
var body: some View {
Image(imageName)
.resizable()
.aspectRatio(contentMode: .fill)
.clipShape(RoundedRectangle(cornerRadius: 10))
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.white, lineWidth: isSelected ? 2 : 0)
)
}
希望这有帮助,
伯克斯