草庐IT

swift - 在 SwiftUI View 中实现委托(delegate)

coder 2023-09-10 原文

我正在尝试实现需要委托(delegate)方法的功能(如 NSUserActivity)。因此,我需要一个符合 NSUserActivityDelegate(或类似的其他委托(delegate))的 UIViewController,处理并保存所有必需的信息。我的问题是我的界面使用 SwiftUI,因此我没有使用 UIViewControllers。那么我怎样才能实现这个功能并仍然使用 SwiftUI 作为 UI。我尝试了什么:view1 只是一个普通的 SwiftUI View,它可以呈现(通过 NavigationLink)view2,它是想要实现此功能的 View 。所以我尝试不链接 view1 和 view2,而是将 view1 链接到 UIViewControllerRepresentable,然后处理此功能的实现并添加 UIHostingController(rootView: view2) 作为 subview Controller .

struct view1: View {    
    var body: some View {
        NavigationLink(destination: VCRepresentable()) {
            Text("Some Label")
        }
    }
}

struct view2: View {    
    var body: some View {
        Text("Hello World!")
    }
}

struct VCRepresentable: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIViewController {
        return implementationVC()
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) { }
}

class implementationVC: UIViewController, SomeDelegate for functionality {
    // does implementation stuff in delegate methods
    ...

    override func viewDidLoad() {
        super.viewDidLoad()

        attachChild(UIHostingController(rootView: view2()))
    }

    private func attachChild(_ viewController: UIViewController) {
        addChild(viewController)

        if let subview = viewController.view {
            subview.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(subview)

            subview.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
            subview.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
            subview.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
            subview.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        }

        viewController.didMove(toParent: self)
    }
}

我在 VC 和 view2 之间传输数据时遇到问题。所以我想知道是否有更好的方法在 SwiftUI View 中实现这样的功能。

最佳答案

您需要创建一个符合 UIViewControllerRepresentable 并具有处理所有委托(delegate)功能的 Coordinator 的 View 。

例如,对于您的示例 View Controller 和委托(delegate):

struct SomeDelegateObserver: UIViewControllerRepresentable {
    let vc = SomeViewController()
    var foo: (Data) -> Void
    func makeUIViewController(context: Context) -> SomeViewController {
        return vc
    }

    func updateUIViewController(_ uiViewController: SomeViewController, context: Context) { }
    func makeCoordinator() -> Coordinator {
        Coordinator(vc: vc, foo: foo)
    }

    class Coordinator: NSObject, SomeDelegate {
        var foo: (Data) -> Void
        init(vc: SomeViewController, foo: @escaping (Data) -> Void) {
            self.foo = foo
            super.init()
            vc.delegate = self
        }
        func someDelegateFunction(data: Data) {
            foo(data)
        }
    }
}

用法:

struct ContentView: View {
    var dataModel: DataModel

    var body: some View {
        NavigationLink(destination: CustomView(numberFromPreviousView: 10)) {
            Text("Go to VCRepresentable")
        }
    }
}

struct CustomView: View {
    @State var instanceData1: String = ""
    @State var instanceData2: Data?
    var numberFromPreviousView: Int // example of data passed from the previous view to this view, the one that can react to the delegate's functions
    var body: some View {
        ZStack {
            SomeDelegateObserver { data in
                print("Some delegate function was executed.")
                self.instanceData1 = "Executed!"
                self.instanceData2 = data
            }
            VStack {
                Text("This is the UI")
                Text("That, in UIKit, you would have in the UIViewController")
                Text("That conforms to whatever delegate")
                Text("SomeDelegateObserver is observing.")
                Spacer()
                Text(instanceData1)
            }
        }
    }
}

注意:我将 VCRepresentable 重命名为 SomeDelegateObserver 以更好地说明它的作用:它的唯一目的是等待委托(delegate)函数执行然后运行您提供的闭包(即本例中的 foo)。您可以使用此模式创建尽可能多的函数来“观察”您关心的任何委托(delegate)函数,然后执行可以更新 UI、数据模型等的代码。在我的示例中,当 SomeDelegate 触发 someDelegateFunction(data:), View 将显示“Excuted”并更新数据实例变量。

关于swift - 在 SwiftUI View 中实现委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57281389/

有关swift - 在 SwiftUI View 中实现委托(delegate)的更多相关文章

  1. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

  2. ruby-on-rails - 如何在 Ruby on Rails 中实现无向图? - 2

    我需要在RubyonRails中实现无向图G=(V,E)并考虑构建一个Vertex和一个Edge模型,其中Vertex有_多条边。由于边恰好连接两个顶点,您将如何在Rails中执行此操作?您是否知道任何有助于实现此类图表的gem或库(对重新发明轮子不感兴趣;-))? 最佳答案 不知道有任何现有库在ActiveRecord之上提供图形逻辑。您可能必须实现自己的Vertex、EdgeActiveRecord支持的模型(请参阅Rails安装的rails/activerecord中的vertex.rb和edge.rb/test/fixtur

  3. ruby-on-rails - 如何在 Ruby on Rails 中实现由 JSF 2.0 (Primefaces) 驱动的 UI 魔法 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道ruby​​onrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim

  4. ruby - 在 Ruby 中实现 to_int 和 to_str 的后果 - 2

    我haveaclass它公开了一个字符串值和一个int值(分别是命令输出和退出代码)。除了通过to_s和to_i公开它们之外,我还使用to_str和to_int,如下所示:classStatusdefto_s@outputendalias:to_str:to_sdefto_i@status.exitstatusendalias:to_int:to_iend我的想法是能够在尽可能多的情况下使用这个对象。将其强制转换为字符串或整数会增加可用性。例如,我可以将对象与字符串连接起来:a_string="Outputwas:"+results(我想用这个作为int强制转换的例子,但是Fixnum

  5. ruby - 在 Ruby 中实现二叉树 - 2

    我一直在尝试在Ruby中实现BinaryTree类,但我得到了stackleveltoodeep错误,尽管我似乎没有在该特定代码段中使用任何递归:1.classBinaryTree2.includeEnumerable3.4.attr_accessor:value5.6.definitialize(value=nil)7.@value=value8.@left=BinaryTree.new#stackleveltoodeephere9.@right=BinaryTree.new#andhere10.end11.12.defempty?13.(self.value==nil)?true:

  6. ruby - 将属性方法委托(delegate)给父对象 - 2

    我有以下类(class):classAlphabetattr_reader:letter_freqs,:statistic_letterdefinitialize(lang)@lang=langcaselangwhen:en@alphabet=('A'..'Z').to_a@letter_freqs={...}when:ru@alphabet=('А'..'Я').to_a.insert(6,'Ё')@letter_freqs={...}...end@statistic_letter=@letter_freqs.max_by{|k,v|v}[0]endendfoo=Alphabet.n

  7. ruby - 如何在 Ruby 中实现私有(private)内部类 - 2

    来自Java,我正在尝试在Ruby中实现LinkedList。我在Java中实现它的通常方法是有一个名为LinkedList的类和一个名为Node的私有(private)内部类,其中LinkedList的每个对象都作为Node对象。classLinkedListprivateclassNodeattr_accessor:val,:nextendend我不想将Node类暴露给外部世界。然而,通过Ruby中的这个设置,我可以使用这个访问LinkedList类之外的私有(private)Node类对象-node=LinkedList::Node.new我知道,在Ruby1.9中,我们可以使用

  8. ruby - 在 Ruby 中实现 Luhn 算法 - 2

    我一直在尝试用Ruby实现Luhn算法。我一直在执行以下步骤:该公式根据其包含的校验位验证数字,该校验位通常附加到部分帐号以生成完整帐号。此帐号必须通过以下测试:从最右边的校验位开始向左移动,每第二个数字的值加倍。将乘积的数字(例如,10=1+0=1、14=1+4=5)与原始数字的未加倍数字相加。如果总模10等于0(如果总和以零结尾),则根据Luhn公式该数字有效;否则无效。http://en.wikipedia.org/wiki/Luhn_algorithm这是我想出的:defvalidCreditCard(cardNumber)sum=0nums=cardNumber.to_s.s

  9. ruby - 在 Ruby 中实现生产者消费者模式 - 2

    假设我有200个昂贵的方法调用(每个都有不同的参数)。出于某种原因,我可以并行执行其中的5个调用,但不能更多。我可以一次执行一个,但一次执行5个要快5倍。我想一直执行五件事。不想排五个,等五个都排完了,再排五个。如果我排队A、B、C、D、E并且C先完成,我想立即用F替换它,即使A和B还没有完成。我一直在研究这个问题,因为我可以想象它会定期发生。解决方案似乎是生产者-消费者模式,Ruby在其标准库中内置了一些用于该模式的结构(Queue和SizedQueue)。我玩过代码示例,阅读了一些文档,我想我对它有一个粗略的了解。但是我有一些问题我对我的解决方案没有信心,而且多线程的整个领域对我来

  10. ruby - 如何在 Ruby 中实现枚举器? - 2

    例如:a=[1,2,3,4,5]a.delete_if{|x|x>3}相当于:a=[1,2,3,4,5]a.delete_if.each.each.each.each{|x|x>3}我知道a.delete_if返回一个枚举器。但是当eachblock返回true时,它​​如何知道应该删除对象呢?如何手动(和在Ruby中)实现delete_if? 最佳答案 可以看看Rubinius源码:enumerablemodule这里是一个拒绝方法的例子:defrejectreturnto_enum(:reject)unlessblock_giv

随机推荐