如何防止 UITableViewCell 移动 (Swift 5)

发布于 2025-01-10 14:56:17 字数 817 浏览 2 评论 0原文

这实际上是一个由两部分组成的问题。首先看一下代码:

//canEditRowAt
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    if tableView.tag == 1000{
        return indexPath.row == 0 ? false : true
        }
    return true
}

//canMoveRowAt
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    if tableView.tag == 1000{
        return indexPath.row == 0 ? false : true
    }
    return true
}

所以从这里我希望它会阻止索引 0 处的行让其他单元格移动到它,但是不会...正如您所看到的:

在此处输入图像描述

我明明想阻止却做不到似乎找到任何文档来解决该问题。

我正在努力解决的另一件事;如果您查看记录,您可以看到,一旦我将单元格移动到任何位置,单元格后面就会出现一个黑条。我也想避免这种情况发生,并尝试了几种方法,但没有任何效果。

任何帮助表示赞赏,谢谢!

This is actually a two part question. First take a look at the code:

//canEditRowAt
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    if tableView.tag == 1000{
        return indexPath.row == 0 ? false : true
        }
    return true
}

//canMoveRowAt
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    if tableView.tag == 1000{
        return indexPath.row == 0 ? false : true
    }
    return true
}

So from this I would expect that it would prevent the row at index 0 from having other cells move to it, but no... as you can see:

enter image description here

I obviously want to prevent it, but can't seem to find any documentation to solve the issue.

The other bit I'm struggling with; if you look at the recording you can see that once I move a cell into any location, a black bar appears behind the cell. I would like to avoid that from happening as well, and have tried several things but nothing has worked.

Any help is appreciated, thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

断爱 2025-01-17 14:56:17

要回答第一个问题,如果您查看 tableView(_:canMoveRowAt:) 文档

该方法允许数据源指定重新排序
不显示指定行的控件。默认情况下,重新排序
如果数据源实现了则显示控件
tableView(_:moveRowAt:to:) 方法。

这主要讨论显示的重新排序控件,而不是具体说明它永远不能移动。因此,如果您查看 UI,会发现 indexPath.row == 0 时未显示 重新排序控件

我可以建议 2 个替代方案:

1。反转移动操作

override func tableView(_ tableView: UITableView,
                        moveRowAt sourceIndexPath: IndexPath,
                        to destinationIndexPath: IndexPath)
{
    // Reverse the action for the first row
    if destinationIndexPath.row == 0
    {
        // You need the give a slight delay as the table view
        // is still completing the first move animation
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
        {
            tableView.beginUpdates()
            tableView.moveRow(at: destinationIndexPath,
                              to: sourceIndexPath)
            tableView.endUpdates()
        }
        
        return
    }
    
    // update the data source
}

UITableView 重新排序移动 UITableViewCell 表视图单元格 swift iOS

2.使用标题视图

这样您就不必担心指定哪些单元格可以移动、哪些单元格不能移动的任何逻辑,因为您可以在标题视图中拥有不可移动的数据:

override func tableView(_ tableView: UITableView,
                        viewForHeaderInSection section: Int) -> UIView?
{
    if section == 0
    {
        // Customize any view
        let headerView = UIView(frame: CGRect(x: 0,
                                              y: 0,
                                              width: tableView.bounds.width,
                                              height: 100))
        headerView.backgroundColor = .red
        
        let label = UILabel(frame: headerView.bounds)
        label.text = "Header view"
        label.textColor = .white
        label.textAlignment = .center
        headerView.addSubview(label)
        
        return headerView
    }
    
    return nil
}

override func tableView(_ tableView: UITableView,
                        heightForHeaderInSection section: Int) -> CGFloat
{
    if section == 0
    {
        // specify any height
        return 100
    }
    
    return 0
}

UITableView 自定义标头 UIView swift iOS

我推荐第二个选项,因为它具有更好的用户体验,并且似乎是解决此问题的正确方法。

要回答第二个问题,在您的 cellForRowAt indexPath 或自定义单元格实现中,您可能将单元格的背景视图或 contentView 设置为黑色。

尝试设置其中之一或两者:

cell.backgroundColor = .clear
cell.contentView.backgroundColor = .clear

这不应该给你一个黑色背景

To answer the first question, if you look at the tableView(_:canMoveRowAt:) documentation :

This method allows the data source to specify that the reordering
control for the specified row not be shown. By default, the reordering
control is shown if the data source implements the
tableView(_:moveRowAt:to:) method.

This mainly talks about the reordering control being shown rather than specifically saying it can never be moved. So if you look at your UI, the reordering control is not showing for indexPath.row == 0

I can suggest 2 alternatives:

1. Reverse the move action

override func tableView(_ tableView: UITableView,
                        moveRowAt sourceIndexPath: IndexPath,
                        to destinationIndexPath: IndexPath)
{
    // Reverse the action for the first row
    if destinationIndexPath.row == 0
    {
        // You need the give a slight delay as the table view
        // is still completing the first move animation
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
        {
            tableView.beginUpdates()
            tableView.moveRow(at: destinationIndexPath,
                              to: sourceIndexPath)
            tableView.endUpdates()
        }
        
        return
    }
    
    // update the data source
}

UITableView reorder move UITableViewCell table view cell swift iOS

2. User a header view

This way you don't have to worry about specify any logic of which cells can move and which cannot as you can have the non movable data in a header view:

override func tableView(_ tableView: UITableView,
                        viewForHeaderInSection section: Int) -> UIView?
{
    if section == 0
    {
        // Customize any view
        let headerView = UIView(frame: CGRect(x: 0,
                                              y: 0,
                                              width: tableView.bounds.width,
                                              height: 100))
        headerView.backgroundColor = .red
        
        let label = UILabel(frame: headerView.bounds)
        label.text = "Header view"
        label.textColor = .white
        label.textAlignment = .center
        headerView.addSubview(label)
        
        return headerView
    }
    
    return nil
}

override func tableView(_ tableView: UITableView,
                        heightForHeaderInSection section: Int) -> CGFloat
{
    if section == 0
    {
        // specify any height
        return 100
    }
    
    return 0
}

UITableView custom header UIView swift iOS

I recommend the second option as it has the better user experience and seems to be the right way of approaching this problem.

To answer your second question, in your cellForRowAt indexPath or custom cell implementation, you probably set the background view of the cell or the contentView to black.

Try setting one of these or both:

cell.backgroundColor = .clear
cell.contentView.backgroundColor = .clear

This should not give you a black background

猥︴琐丶欲为 2025-01-17 14:56:17

实现 tableView(_:targetIndexPathForMoveFromRowAt:toProposedIndexPath:) 并确保永远不会返回第 0 行(当 proposedDestinationIndexPath 为第 0 行时返回第 1 行)。

Implement tableView(_:targetIndexPathForMoveFromRowAt:toProposedIndexPath:) and ensure row 0 is never returned (return row 1 when proposedDestinationIndexPath is row 0).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文