SwiftUI列表行背景无法实现动画?

6

我试图模拟普通的UITableView行为,即当您点击它时,单元格会高亮显示,然后淡出。我已经接近实现了这个功能,但存在以下问题:

  • .background() 不会填满整个列表单元格,它只适合内容周围。
  • .listRowBackground() 填充了单元格,但不会产生动画效果。

是否有一种方法可以使列表行背景产生动画效果?

下面是完整上下文的源代码。原始代码中,由于listRowBackground没有动画效果,您根本看不到背景发生任何变化。如果将其更改为 background,则会按预期进行动画,但不会填充单元格。

struct Profile {
    let name: String
    var selected: Bool
    var hilited: Bool = false
}

extension Profile: Identifiable {
    var id: String { name }
}

struct ProfilesPicker: View {
    @State var profiles: [Profile]

    var body: some View {
        List {
            ForEach(0..<profiles.count) { index in
                let profile = profiles[index]

                CheckCell(name: profile.name, checked: profile.selected)
                    // using .background() gets a proper fade but doesn't fill the cell
                    .listRowBackground(Color(profile.hilited ? UIColor.systemFill : UIColor.systemBackground))
                    .onTapGesture {
                        profiles[index].hilited = true
                        withAnimation(.easeIn) {
                            profiles[index].hilited = false
                            profiles[index].selected.toggle()
                        }
                    }
            }
        }
    }
}

struct CheckCell: View {
    let name: String
    let checked: Bool

    var body: some View {
        HStack {
            Text(name)
            Spacer()
            if checked {
                Image(systemName: "checkmark")
            }
        }
        .contentShape(Rectangle())
    }
}
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
4

对listRowBackground使用延迟和添加动画效果。

struct ProfilesPicker: View {
    @State var profiles: [Profile]
    
    var body: some View {
        List {
            ForEach(0..<profiles.count) { index in
                let profile = profiles[index]
                
                CheckCell(name: profile.name, checked: profile.selected)
                    .onTapGesture {
                        profiles[index].hilited = true
                        
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { //<==Here
                            profiles[index].hilited = false
                            profiles[index].selected.toggle()
                        }
                    }
                    .animation(.default)
                    .listRowBackground(Color(profile.hilited ? UIColor.systemFill : UIColor.systemBackground).animation(.easeInOut)) //<==Here
            }
        }
    }
}

这段代码可以工作,但我想让它立即变为灰色,然后再淡化为白色:Color(···).animate(profile.hilited ? .none : .easeOut) - Uncommon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,