【问题标题】:Event listeners on View elementView 元素上的事件监听器
【发布时间】:2022-01-17 07:06:57
【问题描述】:

在 SwiftUI 视图中,我们可以有一个 Button 元素,这个按钮元素有 onHover 事件以及一个在单击按钮时触发的事件(称为 action),如下所示:

Button("MyButton1", action: {
            // EVENT1: executed on button click
        })
            .onHover { hovered in
                // EVENT2: executed on hover event
            }

现在我有了自己的 UI 元素,我这样定义:

struct MyCustomSwiftUIView: View {

var body: some View {
    HStack
    {
        Button("MyButton1", action: {
                // EVENT1: executed on button click
        })
            .onHover { hovered in
                // EVENT2: executed on hover event
            }
        }
    }
}

现在我已经定义了MyCustomSwiftUIView,我希望它提供onClickonHover 事件,就像按钮一样。它应该是这样的:

MyCustomSwiftUIView()
    .onHover { hovered in
                // EVENT1: executed on hover event
            }
    .onClick {
                // EVENT2: executed on hover event
            }

问题:如何在我自己的自定义元素MyCustomSwiftUIView 上添加/实现这些事件?

PS:我是 SwiftUI 的新手,恕我直言,语言很混乱。这是我无法自学的第一门语言,我正在努力解决与我所经历过的任何其他语言截然不同的基本概念。第一次连 Google 都帮不了我(希望我不要太戏剧化)。

【问题讨论】:

  • “我是 SwiftUI 新手,恕我直言,这门语言很混乱”——SwiftUI 不是一种语言,它是与 Swift 语言一起使用的框架。从您的帖子中不清楚您是 Swift 的初学者还是只是 SwiftUI 的初学者。 “我正在努力解决与我曾经体验过的任何其他语言截然不同的基本概念”——SwiftUI 是一个声明性框架。如果你是从使用 React 开始的,你可能会发现这些概念非常相似。如果您来自命令式视图/布局系统,是的,它可能非常不同。
  • 感谢您的提问:我是 iOS 开发的新手,这意味着 Swift 和 SwiftUI 都是初学者,但我觉得 SwiftUI 的能力要差得多。例如,我已经熟悉 C# 的代表(我有 3 年以上的专业经验),并且我认为我可以在这里利用这些知识,但这很难。
  • 如果你从全新的语言 (Swift) 和新的布局范式 (declarative/SwiftUI) 的角度来看待它,它肯定会看起来很新,但我不同意前提是它“非常混乱”。许多人发现声明式 UI 的某些方面工作起来更快、更简单,尽管有时更详细或更复杂的工作可能更具挑战性。我建议你通过 Swift 的“SwiftUI 100 天”课程和 Apple SwiftUI 教程学习 Hacking。

标签: ios macos swiftui


【解决方案1】:

与其尝试使用.onHover.onClick 之类的修饰符,我建议您将闭包作为参数传递。看起来像这样:

struct ContentView : View {
    var body: some View {
        MyCustomSwiftUIView(
            onClick: {
                //click
            }, onHover: { hovered in
                //hover
            }
        )
    }
}

struct MyCustomSwiftUIView: View {
    var onClick : () -> Void
    var onHover : (Bool) -> Void
    
    var body: some View {
        HStack {
            Button("MyButton1", action: onClick)
                .onHover(perform: onHover)
        }
    }
}

另一个内置 SwiftUI 修饰符的示例:

struct ContentView : View {
    var body: some View {
        MyCustomSwiftUIView()
            .onTapGesture {
                //click
            }
            .onHover { hovered in
                //hover
            }
    }
}

struct MyCustomSwiftUIView: View {
    var body: some View {
        HStack {
            Text("My custom view")
        }
    }
}

【讨论】:

  • 这正是我所需要的。太感谢了!使用修饰符.onHover.onClick 获得相同的效果有多复杂?还有一个问题:我很确定这样的问题一定已经被问过了。在 StackOverflow 或 Google 上搜索时,您会如何表达?
  • 如果这回答了您的问题,您可以用绿色复选标记将其标记为已接受。就使用修饰符而言,使用您构建事物的方式(例如内部的Button)可能不可能(或非常复杂)。如果您不希望它们成为按钮上的操作,这很容易——我已经更新了我的答案以显示一个示例。
  • 在措辞方面,再次,这取决于你想要什么。如果您只想知道如何获得悬停动作,请搜索“SwiftUI hover”。如果您想知道如何将闭包传递给子视图,请搜索“SwiftUI 闭包作为参数”
  • 现在我看到我的问题中的例子有点模棱两可。我举了一个简单的例子,只有一个按钮和两个事件,View 结构中已经有内置修饰符可用。实际上,我在MyCustomSwiftUIView 中有很多按钮(编辑、查看、添加、克隆等)。尽管如此,由于在我目前的理解中,修饰符只是一种语法糖,我认为答案是完整的。不过,如果您发现任何可以帮助我将闭包“转换”为修饰符的资源,请随时将其添加到答案中或在此处发表评论。
  • 我认为第二个示例不需要注释——对于发现此问题的其他用户来说,它可能是一个有效的解决方案。他们可以关注评论线程,以查看对您的特定案例有效的确切方法。
猜你喜欢
  • 2021-03-17
  • 2014-02-18
  • 2010-12-22
  • 1970-01-01
  • 2017-04-16
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多