代码之家  ›  专栏  ›  技术社区  ›  TruMan1

如何设置在按钮和标题之间移动的矩形的动画?

  •  1
  • TruMan1  · 技术社区  · 3 年前

    这就是我所拥有的:

    struct ContentView: View {
        enum PageItem: String, CaseIterable, Identifiable {
            case page1
            case page2
    
            var id: String { rawValue }
    
            var title: LocalizedStringKey {
                switch self {
                case .page1:
                    return "Page 1"
                case .page2:
                    return "Page 2"
                }
            }
        }
    
        @Namespace private var pagePickerAnimation
        @State private var selectedPage: PageItem = .page1
    
        var body: some View {
            HStack(spacing: 16) {
                ForEach(PageItem.allCases) { page in
                    Button {
                        selectedPage = page
                    } label: {
                        VStack {
                            if page == selectedPage {
                                Rectangle()
                                    .fill(Color(.label))
                                    .frame(maxWidth: .infinity)
                                    .frame(height: 1)
                                    .matchedGeometryEffect(id: "pageIndicator", in: pagePickerAnimation)
                            }
                            Text(page.title)
                                .padding(.vertical, 8)
                                .padding(.horizontal, 12)
                        }
                        .contentShape(Rectangle())
                    }
                }
            }
            .padding()
        }
    }
    

    enter image description here

    matchedGeometryEffect

    1 回复  |  直到 3 年前
        1
  •  1
  •   swiftPunk Alexander    3 年前

    您错过了动画:

     struct ContentView: View {
        
        @Namespace private var pagePickerAnimation
        @State private var selectedPage: PageItem = .page1
    
        var body: some View {
            
            HStack(spacing: 16) {
                
                ForEach(PageItem.allCases) { page in
                    
                    Button { selectedPage = page } label: {
                        
                        VStack {
                            
                            if page == selectedPage {
                                
                                Rectangle()
                                    .fill(Color(.label))
                                    .frame(maxWidth: .infinity)
                                    .frame(height: 1)
                                    .matchedGeometryEffect(id: "pageIndicator", in: pagePickerAnimation)
                                
                            }
                            
                            
                            Text(page.title)
                                .padding(.vertical, 8)
                                .padding(.horizontal, 12)
                            
                            
                            
                        }
                        .contentShape(Rectangle())
                        
                    }
                }
            }
            .padding()
            .animation(.default, value: selectedPage) // <<: here
        }
    }
    
    
    
    enum PageItem: String, CaseIterable, Identifiable {
        case page1
        case page2
    
        var id: String { rawValue }
    
        var title: LocalizedStringKey {
            switch self {
            case .page1:
                return "Page 1"
            case .page2:
                return "Page 2"
            }
        }
    }