You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI列表项拖拽排序时出现黑色背景的问题排查

列表拖拽排序时列表项背景变黑问题解决

问题场景

我正在尝试实现列表拖拽排序功能,基础代码示例如下:

import SwiftUI

struct ContentView: View {

    @State var items = [
        "One",
        "Two",
        "Three"
    ]

    var body: some View {
        NavigationStack {
            ZStack {
                Color.gray
                    .ignoresSafeArea()

                List($items, id: \.self, editActions: .move) { $item in
                    ListItem(text: item)
                }
                .scrollContentBackground(.hidden)
                .listStyle(.plain)
            }
            .navigationTitle("Test")
            .navigationBarTitleDisplayMode(.inline)
        }
    }

}

struct ListItem: View {

    let text: String

    var body: some View {
        Text(text)
            .frame(maxWidth: .infinity)
            .foregroundColor(.white)
            .padding()
            .background(.blue)
            .clipShape(RoundedRectangle(cornerRadius: 4.0))
            .listRowSeparator(.hidden)
            .listRowBackground(Color.clear)
    }

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

功能整体正常,但长按开始拖拽手势时,列表项的背景会变为黑色。已添加listRowBackground和scrollContentBackground等修饰符,但问题仍存在。

拖拽时黑色背景示例

解决方案

方法一:自定义拖拽预览样式

给ListItem添加onDrag修饰符,手动指定拖拽时的预览视图,完全控制其样式:

struct ListItem: View {
    let text: String

    var body: some View {
        Text(text)
            .frame(maxWidth: .infinity)
            .foregroundColor(.white)
            .padding()
            .background(.blue)
            .clipShape(RoundedRectangle(cornerRadius: 4.0))
            .contentShape(RoundedRectangle(cornerRadius: 4.0))
            .listRowSeparator(.hidden)
            .listRowBackground(Color.clear)
            // 自定义拖拽预览
            .onDrag {
                NSItemProvider(object: text as NSString)
            } preview: {
                Text(text)
                    .frame(maxWidth: .infinity)
                    .foregroundColor(.white)
                    .padding()
                    .background(.blue)
                    .clipShape(RoundedRectangle(cornerRadius: 4.0))
            }
    }
}

方法二:给列表行添加透明背景

在List的子视图(即ListItem)上直接添加.background(.clear),覆盖系统默认的拖拽背景:

List($items, id: \.self, editActions: .move) { $item in
    ListItem(text: item)
        .background(.clear) // 添加该行代码
}
.scrollContentBackground(.hidden)
.listStyle(.plain)

方法三:全局设置拖拽预览背景

如果希望所有列表都生效,可以在App初始化或ContentView的init方法中修改UITableView的全局外观:

struct ContentView: View {
    @State var items = ["One", "Two", "Three"]
    
    init() {
        UITableView.appearance().dragPreviewBackgroundColor = .clear
    }

    var body: some View {
        // 原有代码不变
    }
}

原理说明

拖拽时系统生成的预览视图背景并非直接继承listRowBackground的设置,而是使用UITableView的dragPreviewBackgroundColor属性。通过自定义预览视图、覆盖行背景或全局修改该属性,都能解决黑色背景问题。


内容的提问来源于stack exchange,提问作者Kex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 03:45:38