如何修改拖放预览SwiftUI的背景颜色和形状?
Posted
技术标签:
【中文标题】如何修改拖放预览SwiftUI的背景颜色和形状?【英文标题】:How do I modify the background color and shape of drag&drop preview SwiftUI? 【发布时间】:2021-09-28 14:48:18 【问题描述】:我正在尝试使用可拖动单元格(ios 15)实现简单列表。目前我有两个基本解决方案:List 和 ScrollView。这些方法都不会导致我得到适当的结果。
首先我会提供一些代码:
列表项视图:
struct ListItemView: View
let index: Int
var body: some View
HStack
Text("Item \(index)")
.foregroundColor(.white)
Spacer()
.padding()
.background(Color.gray)
.clipShape(RoundedRectangle(cornerRadius: 16.0))
第一个解决方案(使用列表):
struct ContentView: View
var body: some View
List(0 ..< 10) i in
ListItemView(index: i)
.onDrag
NSItemProvider(object: String(describing: "item_\(i)") as NSString)
.padding(.bottom, 8.0)
.listRowBackground(Color.clear)
.listRowSeparator(.hidden)
.listRowInsets(EdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8))
.background(Color.black)
.listStyle(PlainListStyle())
结果很好,但是当我开始拖动动作时,我看到我的单元格周围有一些白色矩形,这不是我想要的:
第二种解决方案(使用 ScrollView)
struct ContentView: View
var body: some View
ScrollView
ForEach(0 ..< 10) i in
ListItemView(index: i)
.onDrag
NSItemProvider(object: String(describing: "item_\(i)") as NSString)
.background(Color.black)
结果有点不同:我们看不到任何彩色矩形(我想,这是因为我们没有使用 List 并且拖放功能的机制不同)。还有没有圆角的缩放预览和形状。
因此,理想的行为是: a) 预览的大小与列表项的原始大小相同 b) 有圆角形状,没有白框
我怎样才能实现它?
【问题讨论】:
【参考方案1】:理论上,您的NSItemProvider
可以提供previewImageHandler
,这是一个绘制您希望系统用作拖动预览的图像的块。不幸的是,这似乎不起作用。 onDrag
修饰符的文档说它使用视图的图片作为预览图像,它似乎忽略了previewImageHandler
。如果有人发现其他情况,请发表评论,我会修改答案。这是我尝试过的:
import SwiftUI
struct ListItem : Identifiable
let id: Int
let title: String
let itemsInList = (0..<10).map ListItem(id: $0, title: "Item \($0)")
@ViewBuilder func ListItemView(title : String) -> some View
ZStack(alignment: .leading)
RoundedRectangle(cornerRadius: 18, style: .circular)
.foregroundColor(Color(red: 142.0/255.0, green: 142.0/255.0, blue: 142.0/255.0, opacity: 1.0))
Text(title)
.foregroundColor(.white)
.padding()
struct ContentView: View
var body: some View
List(itemsInList)
let itemTitle = $0.title
ListItemView(title: itemTitle)
.onDrag
let itemProvider = NSItemProvider()
itemProvider.registerObject("Item \(itemTitle)" as NSString, visibility: .all)
itemProvider.previewImageHandler =
(completionHandler, expectedClass, options) -> Void in
var resultImage : CGImage?
debugPrint(expectedClass ?? "Unknown")
if let cgContext = CGContext(data: nil,
width: 72,
height: 72,
bitsPerComponent: 8,
bytesPerRow: 16 * (((72 * 4) + 15) / 16),
space: CGColorSpace(name: CGColorSpace.sRGB)!,
bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue)
let frame = CGRect(x: 0, y: 0, width: 72, height: 72)
cgContext.clear(frame)
cgContext.setFillColor(UIColor.red.cgColor)
cgContext.fillEllipse(in: frame)
resultImage = cgContext.makeImage()
if let completionHandler = completionHandler
if let resultImage = resultImage
completionHandler(UIImage(cgImage: resultImage), nil)
else
completionHandler(nil, NSError(domain: "ItemCompletion", code: -1, userInfo: nil))
return itemProvider
struct previews : PreviewProvider
static var previews: some View
ContentView()
【讨论】:
嗨,斯科特,谢谢你的回答!我试图为我的NSItemProvider
实现这个处理程序,但它没有被调用(我想,iOS 应该自己管理它)。我得到这个的唯一方法——我自己调用loadPreviewImage
方法。您能否提供有关如何使用此处理程序的更多详细信息?附言我发现了关于previewImageHandler
的类似问题,但遗憾的是,根本没有任何答案或示例……***.com/questions/67248900/…
我也无法让样本工作,但我把我尝试过的放在上面。我将把它作为错误报告发送以上是关于如何修改拖放预览SwiftUI的背景颜色和形状?的主要内容,如果未能解决你的问题,请参考以下文章