小编Mar*_*ner的帖子

如何以动画方式删除使用 ForEach 循环创建的视图,并从 SwiftUI 中的 ObservableObject 获取数据

该应用程序具有以下设置:

我的主视图使用 SwiftUI 循环创建标签云ForEach。从被调用的数组中获取ForEach数据。使用 a ,每三秒向数组添加一个新标签。通过添加标签,会再次触发并创建另一个. 一旦将三个以上的标签添加到数组中,就会从数组中删除第一个(最旧的)标签,并且 ForEach 会删除该特定的。@PublishedObservableObjectTagModelTimerObservableObjectForEachTagViewObservableObjectTagView

存在以下问题:

TagView 的创建非常完美。它还使用动画和 .onAppear 修饰符以应有的方式进行动画处理TagView。然而,当最旧的标签被删除时,它不会动画化其删除。中的代码.onDisappear会执行,但TagView会立即被删除。

我尝试了以下方法来解决该问题:

我尝试通过使用重复然后自动反转的动画来让整个出现和消失的动画TagView在内部运行。.onAppear它有点有效,但这样有两个问题。首先,如果动画时间太短,一旦动画完成并被TagView删除,将在没有应用任何修改器的情况下显示一小会儿,然后它将被删除。其次,如果我将动画持续时间设置得更长,则会TagView在动画完成之前将其删除。为了使其工作,我需要非常精确地计算动画的删除和持续时间,这将使动画TagView非常依赖Timer,这似乎不是一个好的解决方案。

我尝试的另一个解决方案是找到类似于self.presentationMode.wrappedValue.dismiss()使用@Environment(\.presentationMode)变量的东西,并以某种方式TagView.onAppear动画完成后将其自身删除。但这仅适用于在导航堆栈中创建视图并且我找不到任何其他方法来让视图自行销毁的情况。我还认为,一旦TagModel更新其数组,就会再次引起问题。

我阅读了其他几个 SO 解决方案,它们指向 ForEach 循环中的数据枚举。但我将每个 TagView 创建为自己的对象,我认为这不应该是问题,并且我不确定如果这是问题的一部分,我必须如何实现它。

这是我的应用程序的简化代码,可以在 iOS 单视图 SwiftUI 项目中运行。

import SwiftUI

struct ContentView: View {
    private let timer = …
Run Code Online (Sandbox Code Playgroud)

foreach animation swift swiftui observableobject

6
推荐指数
1
解决办法
2255
查看次数

如何在 SwiftUI 中相对于不同坐标系中的其他视图定位视图

我正在尝试使用 SwiftUI 在我的应用程序中实现拖放功能。

我创建了两个圆圈,它们位于两个不同的HStacks. 它们不共享相同的坐标空间。

带有描边的圆圈是目标,绿色实心圆圈是要拖动的对象。

我能够使用GeometryReaderinside an来获得他们的绝对位置.overlay。我用它来检测当对象圆被拖动到目标圆上时它们是否重叠。这有效。

当它们不重叠时,对象圆将移回其原始位置。当它们重叠时,对象圆应该卡入目标圆的位置。这是我似乎有问题的地方。

我试图通过以下方式设置对象圆的新 X 和 Y 位置:对象圆本地位置 - 对象圆全局位置 + 目标圆全局位置。

    objectPosition = CGPoint(
        x: objectPosition.x - objectFrame.midX + targetFrame.midX,
        y: objectPosition.y - objectFrame.midY + targetFrame.midY
   )
Run Code Online (Sandbox Code Playgroud)

我假设这会将我带到目标圆的坐标空间。但不知怎的,它不起作用。

到目前为止,我一直无法找到一种可靠且简单的方法来转换 SwiftUI 中的坐标空间。使用覆盖内部的解决方法GeometryReader至少给了我正确的全局位置。但我还没有找到一种方法来使用这些位置将视图放置在.global坐标空间中。

如果有人知道为什么我对坐标空间的计算是错误的,或者甚至知道一种更容易地相对于彼此转换和定位视图的方法,我将非常感激。

这是我的 SwiftUI 单视图 iOS 应用程序的代码:

import SwiftUI

struct ContentView: View {
    
    @State private var isDragging: Bool = false
    
    @State private var objectDragOffset: CGSize = .zero
    @State private var objectPosition: CGPoint = …
Run Code Online (Sandbox Code Playgroud)

drag-and-drop coordinates swift swiftui geometryreader

5
推荐指数
1
解决办法
2061
查看次数

在第一个索引处向集合中插入新元素时,如何使用 PageTabViewStyle 修饰符更新 TabView 中的 SwiftUI 的 ForEach

ForEachTabViewwithPageTabViewStyle修饰符中使用时,这是一个非常具体的问题。

每次我在数组的开头插入一个元素时,我的应用程序都会崩溃。

我得到一个

尝试从更新前仅包含 11 个项目的部分 0 中删除项目 11

错误。

在画布中它也会崩溃。

最后的常规附加工作正常,当我删除 PageTabViewStyle 修饰符时也可以正常工作。

如果我需要详细说明或有任何问题,请告诉我。

更新:我似乎在 iOS 15 中此问题已得到修复并且我的代码有效。我仍然希望找到 iOS 14 的解决方法。

我用一个简单的单页应用程序重现了这个问题:

import SwiftUI

struct SwiftUIView: View {

    @State var myArray: [String] = ["C", "D", "E", "F", "G"]

    var body: some View {

        VStack {
            Button("Insert before", action: {
                myArray.insert("A", at: 0)
            })
            TabView {
                ForEach(myArray, id: \.self) { value in
                    Text("\(value)")
                }
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
        }
    }
}

struct SwiftUIView_Previews: PreviewProvider { …
Run Code Online (Sandbox Code Playgroud)

swift swiftui swiftui-foreach swiftui-tabview

5
推荐指数
1
解决办法
124
查看次数

如何将导入的 Cocoapod 框架标记为已弃用

在我们的框架之一中,我们使用 SwiftObserver pod。我们的框架已用于我们应用程序的其他几个框架中。

将开发目标提高到 iOS 13.0 后,我想将 SwiftObserver 方法的所有使用标记为已弃用,以逐步更改我们的代码库以使用合并的观察者。

我正在考虑从现在开始分叉 SwiftObserver 或链接 pod 的本地副本。pod update然而,只要不是所有代码都更改为使用组合,应用程序中仍然使用 SwiftObserver 的部分应该能够继续更新它。

有没有一种更简单的方法,也许在 podfile 中,或者通过某种覆盖,来标记该 pod 的使用已弃用,而不破坏其任何功能?

如果您还有其他问题或者我可以提供任何代码示例,请告诉我。

frameworks deprecated ios cocoapods swift

3
推荐指数
1
解决办法
744
查看次数