2

在表格视图中实现 iOS 11 拖放。如果我不想拖动第一行,我假设我从 tableView(:itemsForBeginning:) 返回一个空数组

func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
    if indexPath.row == 0 {
        return []
    }
    let dragItems = self.dragItems(forRowAt: indexPath)
    print("dragging row index \(String(describing: dragItems.first?.localObject as? Int))")
    return dragItems
}

当您不允许用户从指定的索引路径拖动内容时,返回一个空数组。

但即使验证了 [ ] 已返回,拖动仍然会发生。这意味着要么我搞砸了,要么该功能没有按文档实现。我总是犹豫是否认为它是其他人,所以我的问题是 [ ] 的返回是否实际上应该防止 0 行的拖累?其他人对此进行验证或将其显示为按记录工作吗?

谢谢

编辑:来自 WWDC 视频的示例代码包括这个块:

    if tableView.isEditing {
        // User wants to reorder a row, don't return any drag items. The table view will allow a drag to begin for reordering only.
        return []
    }

这是说如果你不返回任何拖动项,表格视图仍然允许拖动?!?!那么如何防止一行被拖动呢?

4

1 回答 1

3

感谢@Losiowy 指出有用的方向。

我知道在 tableView 中,tableView(:moveRowAt:)如果只有一个UIDragItem. 我没有看到任何地方记录的是它也检查过tableView(:canMoveRowAt:),尽管现在回想起来似乎很明显。

canMoveRowAt看起来像这样:

// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    // Return false if you do not want the item to be re-orderable. If coded that the first row is non-editable, that row is by definition also non-re-orderable
    return true
}

注意方法内的注释。我不知道是我写了评论还是从某个地方复制了它。我阻止了第 0 行是可编辑的(在编辑模式下可删除和重新排序)并让它覆盖canMoveRowAt,但这显然被 iOS 11 拖放忽略了。所以解决方案是明确的,如:

// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    // Return false if you do not want the item to be re-orderable.
    if indexPath.row == 0 {return false}
    return true
}

诊断此问题的另一个复杂性是,iPad 上的 iMessage 应用程序中的相同代码没有到达tableView(:moveRowAt:),但在 iPhone 上到达那里。对于 iOS 应用程序,tableView(:moveRowAt:)可以在 iPad 和 iPhone 上访问,尽管这可能是单独的问题。

于 2017-08-25T23:05:37.087 回答