首页 > 解决方案 > 在 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便条。

标签: iosswiftuitableviewanimationrows

解决方案


我找到了一种方法,但我确信有更好的方法。

这是我修改的内容:

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
}

推荐阅读