草庐IT

ios - 以 Swifty(/协议(protocol))方式在 Controller 之间传递信息?

coder 2023-09-14 原文

我正在尝试将信息从 Controller A 传递到 Controller B。问题是,我想要:

  • 简洁:尽量减少XCode对一些关键信息的自动补全。我想以一种简单的方式知道在将 Controller 插入堆栈之前所需的确切参数。

  • 避免转场。根据我的理解,segues 在 Storyboard中创建了很多紧密耦合。我不想依赖 Storyboard来传递信息。 (每次我想将 Controller A 切换到另一个 Controller 时,我都必须去 Storyboard 中进行一些更改)。我可能会在某个时候将我的应用拆分成多个 Storyboard ,而处理转场可能会非常烦人。

  • Beautiful:也许Swift可以提供一个我没有想到的Swifty解决方案。

一开始我一直试图完成的是将 Controller 作为协议(protocol)来插入。即使不可能,让我解释一下:

  • 将 Controller 作为协议(protocol)推送将使我能够准确了解我的属性。

  • Storyboard没有紧耦合

  • 许多 Controller (A、C、D)可能想要推送一个 B Controller ,我可能会给他们每个人一个不同的协议(protocol)来推送 Controller B。也许 B 会在不同的情况下出现。

起初,我的代码看起来像那样( Storyboard扩展有效):

if let myBCustomVC = storyboard.instanciateControllerWithIdentifier(MyBCustomVC.self) as? myVCustomFromAProtocol{
    myBCustomVC.AToB = self.data.count
    self.navigationController?.pushViewController(myBCustomVC, animated: true)
}

protocol myVCustomFromAProtocol {
    var AToB: Int {get set}
}

问题是,我无法将 View Controller 向下推送到协议(protocol)。我不得不通过一个丑陋的 UINavigationController 扩展来。这是完整的结果。

if let myBCustomVC = storyboard.instanciateControllerWithIdentifier(MyBCustomVC.self) as? myVCustomFromAProtocol{
    myBCustomVC.AToB = self.data.count
    self.navigationController?.pushViewController(vcToPush: myBCustomVC, animated: true)
}

extension UINavigationController{
    func pushViewController(vcToPush: Any, animated: Bool){
        if let vc = vcToPush as? UIViewController{
            self.pushViewController(vc, animated: animated)
        }
    } 
}

让我们面对现实吧,在实现我的前两个目标的同时,我已经将 Any 向下转换为 UIViewController,呜呜。

有什么方法可以避免紧耦合并以漂亮的方式将 Controller 插入堆栈,同时保持对参数的有限可见性从第一个 View Controller (A)传递到第二个(B)。你觉得呢?你有没有什么想法?为什么我不想那样做?

最佳答案

我会从另一侧(即您展示的 Controller 的一侧)来处理这个问题。

你可以做一些事情,比如创建一个 Presenter 协议(protocol)。

protocol Presenter {
    func present(inContext context: UIViewController)
    // possibly with some data in it too (if it's across all instances)...
    var count: Int {get set}
}

并且在每个...之上都有某种工厂结构......

struct BVCPresenter: Presenter {
    var count: Int = 0

    func present(inContext context: UIViewController) {
        // create the BViewController here
        let controller = ...

        context.push(controller, animated: true)
    }
}

或者类似的东西。这实际上取决于用例和传递的数据等......

现在 A 可以做...

someGenericPresenter.present(inContext: navigationController)

通用表示器可以作为属性传递给 A 或作为参数传递给函数等...

或者什么的。

您甚至可以创建一个“FlowController”来为您管理这些转换和数据...

self.flowController.presentB()

flowController 然后知道 B 需要什么以及如何以及在何处呈现它并用数据填充它。各个 View Controller 实际上不需要了解彼此的任何信息。

我认为没有适合所有情况的解决方案。这需要大量的思考和设计。但是有很多选择。想想你在 View Controller 之间需要什么,然后从中开始工作。

此外,即使它不是教科书中通用的、“敏捷的”、优雅的、漂亮的代码,也不要太担心创建“正常工作”的东西。拥有可以运行的代码比拥有一个设计精美但无法运行的系统要好得多。

:)

关于ios - 以 Swifty(/协议(protocol))方式在 Controller 之间传递信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39577270/

有关ios - 以 Swifty(/协议(protocol))方式在 Controller 之间传递信息?的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  5. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  6. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  7. ruby-on-rails - rails : How to make a form post to another controller action - 2

    我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak

  8. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  9. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  10. ruby-on-rails - 如何在 Rails Controller Action 上触发 Facebook 像素 - 2

    我有一个ruby​​onrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素

随机推荐