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

Posted

技术标签:

【中文标题】如何为在按钮标题之间移动的矩形设置动画?【英文标题】:How to animate a rectangle traveling between buttons headings? 【发布时间】:2021-10-06 22:14:31 【问题描述】:

我有一组按钮,其行为类似于分段选择器。当你点击一个按钮时,它会更新一个枚举状态。我想在顶部显示一个在按钮之间运行的指示器,而不是显示/隐藏。

这就是我所拥有的:

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()
    

我认为matchedGeometryEffect 会帮助做到这一点,但我可能使用错误或存在更好的方法。如果按钮顶部的黑线在一个按钮上进行动画处理并在另一个按钮上移动,我该如何实现这一点?

【问题讨论】:

【参考方案1】:

你错过了动画:

 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"
        
    

【讨论】:

哇,它成功了!谢谢!! 不客气! ? @TruMan1:我看到您的代码需要进行一些必要的重构,如果您有兴趣,我可以更新我的答案。

以上是关于如何为在按钮标题之间移动的矩形设置动画?的主要内容,如果未能解决你的问题,请参考以下文章

如何为矩形的对角线设置动画?

如何为 SVG 多边形设置动画以进行填充?

如何为 QPushButton 的背景颜色设置动画(动态更改按钮颜色)

更改设备方向时如何为uiimageview设置动画

当一个被删除时,如何为剩余的 ng-repeat 项目的移动设置动画?

如何为 UIView 动画设置相同的速度