自定义页面指示器无法切换激活索引的问题求助
自定义页面指示器无法切换激活索引的问题求助
看起来你的自定义页面指示器遇到了状态更新不生效的问题,我帮你排查了代码里的几个关键问题,应该能解决你的困扰:
1. 子视图名称的笔误
你在CustomDotIndicatorView的body里调用的是CloveDotItemView,但实际定义的子视图是CustomDotItemView——这是个很容易忽略的笔误!它会导致系统找不到正确的视图实现,自然无法响应activeIndex的变化。把CloveDotItemView改成CustomDotItemView就能解决这个基础问题。
2. 不必要的双向Binding使用
你的CustomDotItemView只是用来展示激活/未激活状态,不需要修改外部的activeIndex,所以完全没必要用@Binding var isActive: Bool,改成普通的let isActive: Bool就足够了,这样还能避免无效的Binding定义。修改后的子视图代码:
private struct CustomDotItemView: View { let isActive: Bool // 替换原有的@Binding private let activeImage: some View = Image( "dotindicator-active", bundle: Bundle(identifier: bundleID)) .renderingMode(.original) .colorMultiply(.green) private let inactiveImage: some View = Image( "dotindicator-inactive", bundle: Bundle(identifier: bundleID)) var body: some View { ZStack { isActive ? activeImage : inactiveImage } } }
3. 简化激活状态的传递
既然子视图不需要双向绑定,那在父视图里直接传递计算好的Bool值就行,不需要自定义空实现的Binding。修改CustomDotIndicatorView里的ForEach部分:
ForEach(0..<indicatorCount) { index in CustomDotItemView(isActive: actualActiveIndex == index) }
另外,还要确认bundleID是你项目中正确的Bundle标识符,否则图片加载失败也可能让你误以为状态没更新。
最后附上修改后的完整代码,你可以直接替换测试:
import SwiftUI public struct CustomDotIndicatorView: View { let indicatorCount: Int @Binding var activeIndex: Int let height: CGFloat let spacing: CGFloat public var body: some View { let actualActiveIndex = min(max(activeIndex, 0), indicatorCount - 1) return HStack(alignment: .center, spacing: spacing) { ForEach(0..<indicatorCount) { index in CustomDotItemView(isActive: actualActiveIndex == index) } } .frame(height: height) } } private struct CustomDotItemView: View { let isActive: Bool private let activeImage: some View = Image( "dotindicator-active", bundle: Bundle(identifier: bundleID)) .renderingMode(.original) .colorMultiply(.green) private let inactiveImage: some View = Image( "dotindicator-inactive", bundle: Bundle(identifier: bundleID)) var body: some View { ZStack { isActive ? activeImage : inactiveImage } } } struct CustomDotIndicatorView_Previews: PreviewProvider { @State static var activeIndex: Int = 0 static let indicatorCount: Int = 5 static var previews: some View { ZStack { Color.blue.opacity(0.2).ignoresSafeArea(.all) VStack { Spacer() HStack { Button { activeIndex -= 1 } label: { Label("", systemImage: "chevron.left") } .padding(.leading, 48) Spacer() CustomDotIndicatorView(indicatorCount: indicatorCount, activeIndex: $activeIndex, height: 6, spacing: 12) Spacer() Button { activeIndex += 1 } label: { Label("", systemImage: "chevron.right") } .padding(.trailing, 48) } } } } }
内容来源于stack exchange
相关产品推荐
相关产品推荐

