我在使用动画(UITableViewRowAnimationTop)在UITableView中插入/删除UITableViewCell时看到了一个奇怪的效果。
当要插入的单元格比上面的单元格大得多时,会发生动画故障。
This video显示了模拟器中的故障,黄色单元突然出现在它应该从顶部滑动的位置。
Here是视频中的Xcode项目。
Bellow是细胞插入/动画代码。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2 + self.thirdCellVisible;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
if (indexPath.row == 1)
{
if (self.thirdCellVisible)
{
self.thirdCellVisible = !self.thirdCellVisible;
[tableView deleteRowsAtIndexPaths:@[self.thirdCellIndexPath]
withRowAnimation:UITableViewRowAnimationTop];
}
else
{
self.thirdCellVisible = !self.thirdCellVisible;
[tableView insertRowsAtIndexPaths:@[self.thirdCellIndexPath]
withRowAnimation:UITableViewRowAnimationTop];
}
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == self.thirdCellIndexPath.row)
{
return 100.0f;
}
return 44.0f;
}
答案 0 :(得分:4)
您必须致电
[tableView beginUpdates]
和
[tableView endUpdates]
调用插入/删除方法之前和之后如下:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2 + self.thirdCellVisible;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
if (indexPath.row == 1)
{
if (self.thirdCellVisible)
{
self.thirdCellVisible = !self.thirdCellVisible;
[self.tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:@[self.thirdCellIndexPath]
withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates];
}
else
{
self.thirdCellVisible = !self.thirdCellVisible;
[self.tableView beginUpdates];
[tableView insertRowsAtIndexPaths:@[self.thirdCellIndexPath]
withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates];
}
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == self.thirdCellIndexPath.row)
{
return 100.0f;
}
return 44.0f;
}
答案 1 :(得分:2)
根据Apple here:
动画批量插入,删除和重新加载行和 在动画块中调用相应的方法 由连续调用beginUpdates和endUpdates定义。如果你 不要在其中调用插入,删除和重新加载方法 块,行和段索引可能无效。调用beginUpdates 和endUpdates可以嵌套;所有索引都被视为有 只有外部更新块。
在一个块结束时 - 也就是说,在endUpdates返回之后 表视图查询其数据源并像往常一样委托行和 部分数据。因此,支持表视图的集合对象 应该更新以反映新的或删除的行或部分。
您必须分别在调用插入/删除方法之前和之后调用[tableView beginUpdates]
和[tableView endUpdates]
。
Apple在上述链接中提供了一个示例。
注意:如果你的数组和表视图项不同步,没有开始/结束调用,将抛出异常。
建议:先尝试withRowAnimation:UITableViewRowAnimationAutomatic
答案 2 :(得分:2)
以下是我的工作代码视频的链接:https://dl.dropboxusercontent.com/u/30316681/480.mov
以下是我的工作代码:
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
require('./module.js');
angular
.module('app')
.controller('myController',
function () {
var vm = this;
vm.title = 'test';
activate();
function activate() { }
});
function test() {
var vm = 'test';
}
},{"./module.js":2}],2:[function(require,module,exports){
angular.module('app', []);
},{}]},{},[1])
答案 3 :(得分:1)
使用package me.mortadelle2.turrets;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerMoveEvent;
public class CreateTurretEvent implements Listener{
Turrets getter;
public CreateTurretEvent(Turrets plugin){
plugin.getServer().getPluginManager().registerEvents(this, plugin);
getter = plugin;
}
@EventHandler
public void playerPlacesBlockToBecomeTurret(BlockPlaceEvent e){
Player p = e.getPlayer();
if (getter.playersThatShouldPlaceBlock.contains(p.getName())){
p.sendMessage(getter.turretsMsg + "That block is now turretified!");
getter.getServer().getScheduler().cancelTask(getter.waitForPlacement);
getter.playersThatShouldPlaceBlock.remove(p.getName());
Location blockLocation = e.getBlock().getLocation();
getter.getConfig().set("Turrets." + getter.turretName.get(p.getName()), blockLocation);
}
}
@EventHandler
public void playerStepsOnTurret(PlayerMoveEvent e){
Player p = e.getPlayer();
if (getter.getConfig().contains("test")){ //I will add something more specific than test later
p.sendMessage("This is a test");
}
}
}
和[tableView beginUpdates]
,如下所示
[tableView endUpdates]