【发布时间】:2021-08-17 03:42:42
【问题描述】:
我有一组图像,并将每个图像渲染为可以拖动的卡片对象。我不想渲染每一个,因为这会导致性能问题。目前我正在使用 forEach 循环来渲染所有这些,但是我将如何渲染说两个,直到一个被删除。一旦一个被删除,我会在当前可见的卡片下渲染一个新实例。我不需要这个确切的实现,但有人可以指出正确的方法。
import Photos
import SwiftUI
var imageToDelete = [PHAsset]()
struct ContentView: View {
var body: some View {
VStack{
// Here is where I'm rendering the card
ZStack{
ForEach(imageObjectGroup){ card in
CardView(card: card).padding(8)
}
}.zIndex(1.0)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
// You can ignore this I am converting the array item (PHAsset) to a UIImage so I can render it
func getAssetThumbnail(asset: PHAsset) -> UIImage {
let manager = PHImageManager.default()
let option = PHImageRequestOptions()
var thumbnail = UIImage()
option.isSynchronous = true
manager.requestImage(for: asset, targetSize: CGSize(width: 350, height: 350), contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in
thumbnail = result!
})
return thumbnail
}
// Card Object
struct CardView: View{
@State var card: ImageObject
let cardGradient = Gradient(colors: [Color.black.opacity(0), Color.black.opacity(0.5)])
var body: some View{
ZStack(alignment: .leading){
Image(uiImage: getAssetThumbnail(asset: card.image)).resizable().padding(8)
LinearGradient(gradient: cardGradient, startPoint: .top, endPoint: .bottom)
HStack {
Image("yes").resizable().aspectRatio(contentMode: .fit).frame(width: 150).opacity(Double(card.x/10 - 1))
Spacer()
Image("nope").resizable().aspectRatio(contentMode: .fit).frame(width: 150).opacity(Double(card.x/10 * -1 - 1))
}
//ZStack follows the coordinates of the card model
}.offset(x: card.x, y: card.y).rotationEffect(.init(degrees: card.degree)).gesture(
//Gesture recognizer updates coordinate values
DragGesture().onChanged { value in
card.x = value.translation.width
card.y = value.translation.height
card.degree = 7 * (value.translation.width > 0 ? 1 : -1)
}
//When user stops dragging
.onEnded { value in
withAnimation(.interpolatingSpring(mass: 1.0, stiffness: 50, damping: 8, initialVelocity: 0)){
switch value.translation.width {
case 0...100:
card.x = 0; card.degree = 0; card.y = 0
// Keep
case let x where x > 100:
card.x = 200; card.degree = 12
case (-100)...(-1):
card.x = 0; card.degree = 0; card.y = 0;
// Delete
case let x where x < -100:
card.x = -200; card.degree = -12
print(card.image)
imageToDelete.append(card.image)
PHPhotoLibrary.shared().performChanges( {
PHAssetChangeRequest.deleteAssets(imageToDelete as NSFastEnumeration)},
completionHandler: {
success, error in NSLog("Deletion prompt complete")
})
default: card.x = 0; card.y = 0
}
}
}
).cornerRadius(8)
}
}
【问题讨论】:
-
使用
LazyVStack怎么样,这还会导致性能问题吗? -
是的,因为出于性能原因我将其尺寸缩小了,但 LazyVStack 会强制它填满所有可用空间
-
我应该提到的另一件事是卡片是堆叠在一起的,所以我认为惰性堆栈仍然会渲染它们,因为它们在视图中都是可见的,只是彼此重叠