我使用Combine
来获取匹配作为搜索字段中的用户类型。它在删除、重复数据删除和获取数据方面工作得很好。但我不能动画条目。当比赛到达时,ObservedObject
立即更新,UI已经显示了比赛。我更倾向于将匹配项的入口动画化。
我认为问题是在assign
方法中设置匹配,缺少withAnimation
。是否有可能在Combine
管道中添加动画?我应该用副作用来代替吗?
代码如下:
class DictionarySearchViewModel: ObservableObject {
@Published var translationMatches = [TranslationMatch]()
@Published var text: String = ""
@Published var isLoading = true
@Published var connectionError = false
private var cancellable: AnyCancellable? = nil
init() {
cancellable = $text
.debounce(for: .seconds(0.1), scheduler: DispatchQueue.main)
.removeDuplicates()
.map { [self] queryText -> AnyPublisher<[TranslationMatch], Never> in
if queryText.count < 2 {
return Future<[TranslationMatch], Never> { promise in
promise(.success([TranslationMatch]()))
}
.eraseToAnyPublisher()
} else {
return DictionaryService.sharedInstance()
.searchMatchesPublisher(queryText)
.retry(3)
.replaceError(with: [TranslationMatch]())
.eraseToAnyPublisher()
} else {
return Future<[TranslationMatch], Never> { promise in
promise(.success([TranslationMatch]()))
}
.eraseToAnyPublisher()
}
}
}
.switchToLatest()
.eraseToAnyPublisher()
.receive(on: DispatchQueue.main)
.assign(to: .translationMatches, on: self)
}
}
struct DictionarySearchView: View {
@ObservedObject var viewModel: DictionarySearchViewModel
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
VStack(alignment: .leading, spacing: 15) {
ForEach(viewModel.translationMatches, id: .id) { translationMatch in
Text(translationMatch.label)
}
}
}
}
}
在ForEach
中的Text
上使用.animation
和.transition
。
Text(translationMatch.label)
.animation(.default)
.transition(AnyTransition.move(edge: .top))
https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions