ios - 在 Swift 4 中使用动画在 UITableView 中添加一行
问题描述
我有UITableView
一个第一行包含一个UISwitch
. 如果开关打开,表格只包含第一行,如果开关关闭,表格应该有另一行。
我希望 tableview 在关闭开关时添加第二行,并且我希望该行添加动画,而不使用tableView,reloadData()
,因为它没有动画。
我尝试使用tableView.insertRows(...)
between tableView.beginUpdates()
,tableView.endUpdates()
但它一直在崩溃。
以下是一些截图:
这是代码:
class ChoicesVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var votersTableView: UITableView!
var forAllVoters: Bool = true {
didSet {
votersTableView.reloadData()
//when I replace the previous line with the 3 following lines, i get the crash
//votersTableView.beginUpdates()
//votersTableView.insertRows(at: [IndexPath(row: 1, section: 0)], with: .top)
//votersTableView.endUpdates()
}
}
override func viewDidLoad() {
super.viewDidLoad()
votersTableView.dataSource = self
}
//TableView setup:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = UITableViewCell()
if indexPath.row == 0 {
cell = tableView.dequeueReusableCell(withIdentifier: "SuperCell1", for: indexPath)
let allVotersSwitch = cell.viewWithTag(1) as! UISwitch
allVotersSwitch.addTarget(self, action: #selector(didEditAllVoters(_:)), for: .allEvents)
} else if indexPath.row == 1 {
cell = tableView.dequeueReusableCell(withIdentifier: "SuperCell2", for: indexPath)
}
return cell
}
@objc func didEditAllVoters(_ s: UISwitch) {
self.forAllVoters = s.isOn
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (forAllVoters ? 1 : 2)
}
}
(注意单元格的内容是在Interface Builder中添加的)
这是崩溃信息,当我使用注释行时以及关闭开关后得到的信息:
2018-06-20 19:09:08.678204+0300 Shares[4670:129408] *** 断言失败 -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit- 3694.4.18/UITableView.m:1950
2018-06-20 19:09:08.711010+0300 Shares[4670:129408] *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:第 0 节中的行数无效。包含的行数在更新后的现有节中 (2) 必须等于更新前该节中包含的行数 (2),加上或减去从该节中插入或删除的行数(插入 1,删除 0)和加上或减去移入或移出该部分的行数(0移入,0移出)。
*** First throw call stack:
(
0 CoreFoundation 0x0000000107d7a1cb __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00000001043b9f41 objc_exception_throw + 48
2 CoreFoundation 0x0000000107d7f362 +[NSException raise:format:arguments:] + 98
3 Foundation 0x0000000103e5e089 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
4 UIKit 0x0000000104aa5932 -[UITableView _endCellAnimationsWithContext:] + 19406
5 UIKit 0x0000000104abff65 -[UITableView endUpdates] + 75
6 Shares 0x0000000103a8d8f5 _T06Shares9ChoicesVCC12forAllVotersSbfW + 645
7 Shares 0x0000000103a8dadb _T06Shares9ChoicesVCC12forAllVotersSbfs + 235
8 Shares 0x0000000103a91554 _T06Shares9ChoicesVCC16didEditAllVotersySo8UISwitchCF + 84
9 Shares 0x0000000103a915ac _T06Shares9ChoicesVCC16didEditAllVotersySo8UISwitchCFTo + 60
10 UIKit 0x000000010498a9bd -[UIApplication sendAction:to:from:forEvent:] + 83
11 UIKit 0x0000000104b01183 -[UIControl sendAction:to:forEvent:] + 67
12 UIKit 0x0000000104b014a0 -[UIControl _sendActionsForEvents:withEvent:] + 450
13 UIKit 0x0000000104b01614 -[UIControl _sendActionsForEvents:withEvent:] + 822
14 UIKit 0x000000010562df29 -[UISwitchModernVisualElement sendStateChangeActions] + 73
15 UIKit 0x0000000104ffe717 -[UISwitchMVEGestureTrackingSession _sendStateChangeActionsIfNecessary] + 63
16 UIKit 0x000000010562e612 -[UISwitchModernVisualElement _handleLongPressWithGestureLocationInBounds:gestureState:] + 796
17 UIKit 0x0000000104f76b8b -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + 57
18 UIKit 0x0000000104f7fa13 _UIGestureRecognizerSendTargetActions + 109
19 UIKit 0x0000000104f7d2be _UIGestureRecognizerSendActions + 307
20 UIKit 0x0000000104f7c52a -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 1002
21 UIKit 0x0000000104f6188d _UIGestureEnvironmentUpdate + 1306
22 UIKit 0x0000000104f61327 -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 484
23 UIKit 0x0000000104f603d3 -[UIGestureEnvironment _updateGesturesForEvent:window:] + 288
24 UIKit 0x0000000104a0045c -[UIWindow sendEvent:] + 4102
25 UIKit 0x00000001049a5802 -[UIApplication sendEvent:] + 352
26 UIKit 0x00000001052d7a50 __dispatchPreprocessedEventFromEventQueue + 2809
27 UIKit 0x00000001052da5b7 __handleEventQueueInternal + 5957
28 UIKit 0x00000001052da9bb __handleEventQueueInternal + 6985
29 CoreFoundation 0x0000000107d1d2b1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
30 CoreFoundation 0x0000000107dbcd31 __CFRunLoopDoSource0 + 81
31 CoreFoundation 0x0000000107d01c6b __CFRunLoopDoSources0 + 267
32 CoreFoundation 0x0000000107d011ff __CFRunLoopRun + 1279
33 CoreFoundation 0x0000000107d00a89 CFRunLoopRunSpecific + 409
34 GraphicsServices 0x000000010a4d69c6 GSEventRunModal + 62
35 UIKit 0x0000000104988d30 UIApplicationMain + 159
36 Shares 0x0000000103a938b7 main + 55
37 libdyld.dylib 0x0000000108ea3d81 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
和一张Thread 1: signal SIGABRT
便条。
解决方案
我找到了一种方法,但我确信有更好的方法。
这是我修改的内容:
var forAllVoters: Bool = true {
didSet {
votersTableView.beginUpdates()
votersTableView.deleteRows(at: [IndexPath(row: 1, section: 0)], with: .top)
votersTableView.insertRows(at: [IndexPath(row: 1, section: 0)], with: .top)
votersTableView.endUpdates()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
推荐阅读
- python - 在 Excel 更新时触发重命名文件夹中的图像
- c++ - 如何将opencv和自己的程序构建到dll中
- logstash - 用于 SYSLOG 的 Logstasg GROK 过滤器
- amazon-web-services - 连接 API 网关和 lambas 时应该如何对齐超时?
- powershell - 从powershell中数组的所有索引中获取相同的值
- mysql - 当数据中有 & 时,Mysql LIKE 不起作用
- python - 从训练数据中排除某些标签但保留在测试数据中,sklearn cross_val_score
- altair - Altair 中基于 FieldOneOfPredicate 条件的高亮标签
- xml - Golang用同名的嵌套节点解析XML?
- algorithm - 应用 BFS,目标节点的路径是什么?