如何使用SwiftUI框架实现删除和移动功能
无法删除和移动列表视图中项目的行 苹果公司在他们的培训视频中提供了这些方法,但它不起作用 删除:如何使用SwiftUI框架实现删除和移动功能,swiftui,Swiftui,无法删除和移动列表视图中项目的行 苹果公司在他们的培训视频中提供了这些方法,但它不起作用 删除: array.remove(atOffsets: IndexSet) 移动: array.move(fromOffsets: IndexSet, toOffset: Int) 这两种方法在apple文档中都不可用 您所参考的方法现在在Xcode 11 GM上可用。您可以这样使用它们 删除元素 TLDR: 完整代码(可以复制粘贴): 导入快捷键 struct MyTableView : View {
array.remove(atOffsets: IndexSet)
移动:
array.move(fromOffsets: IndexSet, toOffset: Int)
这两种方法在apple文档中都不可用
您所参考的方法现在在Xcode 11 GM上可用。您可以这样使用它们 删除元素 TLDR: 完整代码(可以复制粘贴): 导入快捷键
struct MyTableView : View {
@State var array=[1,2,3,4,5]
var body: some View {
List{
ForEach(array,id:\.self){element in
Text("\(element)")
}
.onDelete{offsets in
self.array.remove(atOffsets: offsets)
}
}
}
}
struct MyTableView_Previews : PreviewProvider {
static var previews: some View {
MyTableView()
}
}
移动元素
.onMove { (offsets, targetOffset) in
self.array.move(fromOffsets: offsets, toOffset: targetOffset)
}
他们要么对数组使用自定义扩展,要么使用一些尚未向公众提供的Swift版本。我实施的变通方法包括: 删除
func delete(偏移量处:IndexSet){
如果let first=offsets.first{
仓库。房间。移除(在:第一个)
}
}
移动
func移动(从源:IndexSet到目标:Int){
如果let first=source.first{
仓库、房间、swapAt(第一个,目的地)
}
}
移动功能正常,但动画效果不如2019年WWDC上的视频效果好。这些方法是Swift 5.1标准库的一部分,苹果将在未来的Xcode测试版中提供该库。同时,您可以使用以下扩展:
extension Array {
mutating func remove(atOffsets offsets: IndexSet) {
let suffixStart = halfStablePartition { index, _ in
return offsets.contains(index)
}
removeSubrange(suffixStart...)
}
mutating func move(fromOffsets source: IndexSet, toOffset destination: Int) {
let suffixStart = halfStablePartition { index, _ in
return source.contains(index)
}
let suffix = self[suffixStart...]
removeSubrange(suffixStart...)
insert(contentsOf: suffix, at: destination)
}
mutating func halfStablePartition(isSuffixElement predicate: (Index, Element) -> Bool) -> Index {
guard var i = firstIndex(where: predicate) else {
return endIndex
}
var j = index(after: i)
while j != endIndex {
if !predicate(j, self[j]) {
swapAt(i, j)
formIndex(after: &i)
}
formIndex(after: &j)
}
return i
}
func firstIndex(where predicate: (Index, Element) -> Bool) -> Index? {
for (index, element) in self.enumerated() {
if predicate(index, element) {
return index
}
}
return nil
}
}
谢谢你的解决方案。。。但我特别寻找与使用方法array.remove(atoffset:indexSet)和move:array.move(fromfoffsets:indexSet,toOffset:Int)使用indexSet在索引处删除相关的API。这些方法在WWDC 2019 SwiftUI简介中介绍。我在最新版本的xcode 11中找不到。顺便说一句,将项目从一个索引移动到另一个索引的任何方法。
extension Array {
mutating func remove(atOffsets offsets: IndexSet) {
let suffixStart = halfStablePartition { index, _ in
return offsets.contains(index)
}
removeSubrange(suffixStart...)
}
mutating func move(fromOffsets source: IndexSet, toOffset destination: Int) {
let suffixStart = halfStablePartition { index, _ in
return source.contains(index)
}
let suffix = self[suffixStart...]
removeSubrange(suffixStart...)
insert(contentsOf: suffix, at: destination)
}
mutating func halfStablePartition(isSuffixElement predicate: (Index, Element) -> Bool) -> Index {
guard var i = firstIndex(where: predicate) else {
return endIndex
}
var j = index(after: i)
while j != endIndex {
if !predicate(j, self[j]) {
swapAt(i, j)
formIndex(after: &i)
}
formIndex(after: &j)
}
return i
}
func firstIndex(where predicate: (Index, Element) -> Bool) -> Index? {
for (index, element) in self.enumerated() {
if predicate(index, element) {
return index
}
}
return nil
}
}