我有一个标签列表,当你 Select 它们时,芯片将出现.
当你点击每个芯片上的‘X’时,标签应该会滑出一个动画,列表中的标签将被标记为未选中.
我遇到的问题是,当我移除最后一个筹码时,标签左边的圆圈/圆圈判断与动画不顺畅.
我相信这是因为图标在被选中和未被选中时会发生变化,因为如果我保持图标不变,这不是问题.如果我删除芯片上的幻灯片动画也不是问题,但我喜欢这个动画并想保留它.
实际上,我在应用程序中的一些地方遇到了这个问题,涉及动画+更改图标,我想知道有没有解决这个问题的办法?
我在下面附上了一个可重现的例子.
import SwiftUI
struct ContentView: View {
var body: some View {
Icon_Animation()
}
}
struct Icon_Animation: View {
//All tags
var testTags: [Tag] =
[Tag("tag1"),
Tag("tag2"),
Tag("tag3")]
//Only tags that have been selected
@State var selectedTags = [Tag]()
var body: some View {
ScrollView{
//Hstack of the tags that have been selected
HStack{
ForEach(selectedTags){ tag in
HStack(spacing: 0){
Button{
//Clicking on the X will remove from selectedTags array, and then make that tag's isSelected = false
withAnimation(.easeOut) {
if let index = selectedTags.firstIndex(where: {$0.name == tag.name}){
selectedTags.remove(at: index)
}
}
//PROBLEM: even though this statemnt isn't in the withAnimation block, it causes a weird behavior with the circle/check-circle icon
//If I remove the withAnimation statement from the above block, it works fine. However, I would like to keep the slide animation on the chips.
tag.isSelected = false
}label:{
Image(systemName: "x.circle.fill")
.font(.subheadline)
.padding(.horizontal, 6)
}
Image(systemName: "number")
.font(.footnote.weight(.bold))
.padding(.trailing, 2)
Text("\(tag.name)")
.font(.footnote)
}
.padding(.trailing, 20)
.padding(.vertical, 6)
.background(Color.blue.opacity(0.6), in: RoundedRectangle(cornerRadius: 14, style: .continuous))
.transition(.slide)
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
//List of tags where you can select each tag to create a chip
ForEach(testTags){ tag in
TagView(tag: tag)
.onTapGesture {
tag.isSelected.toggle()
if(tag.isSelected == true){
selectedTags.append(tag)
}
}
}
.padding()
}
.padding()
}
}
class Tag: Identifiable, ObservableObject {
var id = UUID()
@Published var name: String
@Published var isSelected = false
init(_ name: String){
self.name = name
}
}
struct TagView: View {
@ObservedObject var tag: Tag = Tag("test")
var body: some View {
ZStack{
//Overlay for when tag is selected
Rectangle()
.fill(Color.purple.opacity(0.6))
.edgesIgnoringSafeArea(.all)
.cornerRadius(5)
.opacity(tag.isSelected ? 1 : 0)
HStack(spacing: 8){
//PROBLEM!!: I want to use a different icon based on whether tag isSelected, but it's causing a hitch in the animation when switching
if(tag.isSelected){
Image(systemName: "checkmark.circle.fill")
.font(.title2.weight(.light))
}else{
Image(systemName: "circle")
.font(.title2.weight(.light))
}
Image(systemName: "number")
.font(.body.weight(.bold))
Text(tag.name)
.font(.headline)
.fontWeight(.bold)
}
.frame(maxWidth: .infinity, alignment: .leading)
}
}
}