我想在任务完成时显示一个视图,我还能如何调用 SwiftView 来显示而不使用基于 State bool 的条件?基本上我想避免在下面为每个需要加载视图的文件进行硬编码...
chart.colors = [
{
backgroundColor: "#0f0",
pointBackgroundColor: "#000",
},
{
backgroundColor: "#f0f",
pointBackgroundColor: "#00f",
},
{
backgroundColor: "#ff0",
pointBackgroundColor: "#f00",
},
];
答案 0 :(得分:0)
您可以探索一些减少重复代码的策略。
自定义 EnvironmentValue
将状态广播到子视图。这将使您免于通过可能不消耗该值的视图传递 @Binding。
请记住,这是一种自上而下的单向广播。与@Binding 不同,孩子不能改变父状态。 (但他们可以改变自己孩子对所述状态的了解。)
@State var isHovered = false
var parent: some View {
///
.environment(\.parentIsHovered, isHovered)
}
@Environment(\.parentIsHovered) var parentIsHovered
var child: some View {
///
.grayscale(parentIsHovered ? 0 : 0.9)
.animation(.easeInOut, value: parentIsHovered)
}
private struct ParentIsHoveredKey: EnvironmentKey {
static let defaultValue: Bool = false
}
extension EnvironmentValues {
var parentIsHovered: Bool {
get { return self[ParentIsHoveredKey] }
set { self[ParentIsHoveredKey] = newValue }
}
}
如果您使某些视图变灰或显示加载指示器,则可以使用接受 Binding 并有条件地显示叠加层、背景或效果的 ViewModifier。
下面的示例通过将 .animation
API 链接到 accessibilityReduceMotion
来演示这一点。
// view
.animate(.easeOut(duration: .fast), value: isLoading)
extension View {
func animate<E: Equatable>(_ animation: Animation?, value: E) -> some View {
self.modifier(AccessibleAnimationModifier(animation, for: value))
}
}
struct AccessibleAnimationModifier<E: Equatable>: ViewModifier {
@Environment(\.accessibilityReduceMotion) var reduceMotion
init(_ animation: Animation? = .default, for value: E) {
self.animation = animation
self.value = value
}
var animation: Animation?
var value: E
func body(content: Content) -> some View {
content
.animation(reduceMotion ? .none : animation, value: value)
}
}
除非您通过某个观察到的类处理加载状态,否则您需要使用@State 将该状态存储在您的视图中。
也许在扩展中具有默认实现的协议有助于减少计算视图之间复杂加载状态时的重复代码。
下面的伪代码定义了一个带有返回 NSItemProvider 函数的 DragSource 协议。该扩展提供了 View 或 VM 可以调用的默认实现。
protocol DragSource {
func makeDraggableThing1(/// content + logic objects) -> NSItemProvider
}
extension DragSource {
func makeDraggableThing1(///) -> NSItemProvider {
/// Default work I only want to edit once in the app
}
}