问题描述
我创建了以下演示视图控制器以在最小示例中重现该问题。
在这里,我使用 UICollectionViewDiffableDataSource 将相同数据的快照重复应用到相同的集合视图,并且每次重新加载所有单元格时,即使没有任何更改。
看起来其他用户也遇到了同样的问题,但他们没有提供足够的信息来准确重现错误: iOS UICollectionViewDiffableDataSource reloads all data with no changes
编辑:我还发现了一个奇怪的行为 - 如果动画差异为 public function purchase(Request $request)
{
$order_number = "JT2070215";
$user = User::firstOrCreate(
[
'email' => $request->input('email')
],[
'password' => Hash::make(Str::random(12)),'name' => $request->input('first_name') . ' ' . $request->input('last_name'),'address' => $request->input('address'),'city' => $request->input('city'),'line2' => $request->input('line2'),'zip_code' => $request->input('post_code'),]
);
try {
$user->createOrGetStripeCustomer();
$user->addPaymentMethod($request->input('payment_method_id'));
$payment = $user->charge(
$request->input('amount'),$request->input('payment_method_id'),[
'currency'=>'GBP','customer'=>$user->stripe_id
],);
$payment = $payment->asstripePaymentIntent();
$order = $user->orders()
->create([
'transaction_id' => $payment->charges->data[0]->id,'total' => $payment->charges->data[0]->amount,'name' => $request->first_name." ".$request->last_name,'email' => $request->email,'address' => $request->address,'city' => $request->city,'country' => $request->country,'post_code' => $request->postal_code,'order_number'=>$order_number
]);
dispatch(new OrderConfirmationEmailJob($order->transaction_id));
return $order;
} catch (\Exception $e) {
return response()->json(['message' => $e->getMessage(),'type'=>'stripe_error'],206);
}
}
,则单元格不会每次都重新加载。
true
解决方法
我想你已经注意到了。当您说 animatingDifferences
是 false
时,您是在要求可区分数据源表现得好像它不是可区分数据源。你是在说:“跳过所有那些不同的东西,只接受这些新数据。”换句话说,您说的相当于 reloadData()
。没有创建新单元格(通过记录很容易证明这一点),因为所有单元格都已经可见;但出于同样的原因,所有可见单元格都被重新配置,这正是人们所期望的 reloadData()
。
另一方面,当 animatingDifferences
为 true
时,diffable 数据源会认真考虑发生了什么变化,以便在必要时可以对其进行动画处理。因此,作为所有幕后工作的结果,它知道什么时候可以避免重新加载单元格(因为它可以代替移动单元格)。
确实,当 animatingDifferences
为 true
时,您可以应用反转单元格的快照,但永远不会再次调用 configure
,因为移动单元格是全部 需要做的:
func updateSnapshot(animatingChange: Bool = true) {
var snapshot = NSDiffableDataSourceSnapshot<Section,Item>()
snapshot.appendSections([.all])
self.items = self.items.reversed()
snapshot.appendItems(self.items,toSection: .all)
self.dataSource.apply(snapshot,animatingDifferences: animatingChange)
}
有趣的是,我还使用 shuffled
而不是 reversed
尝试了上述方法,我发现有时某些单元格被重新配置。显然,diffable 数据源的主要意图不是不重新加载单元格;这只是一种副作用。