如何从swift中的树型数据结构中创buildUIButtons

我有一个树型数据结构,想要使用该树型结构生成button,以一个新的视图控制器编程的方式,它就像在苹果的设置菜单中,你有不同的select,当你点击一个随机的父母,它会延续到它的孩子。

class OptionNode{ var value: String weak var parent: OptionNode? var children = [OptionNode]() init(value: String){ self.value = value } func addOption(node: OptionNode){ children.append(node) node.parent = self } } struct MenuStructure { static var menuOptions: OptionNode { let mainMenu = OptionNode(value: "Main Menu") let vehicle = OptionNode(value: "vehicle Menu") let food = OptionNode(value: "Food Menu") let computer = OptionNode(value: "Computer Menu") let ford = OptionNode(value: "Ford Menu") let toyota = OptionNode(value: "Toyota Menu") let honda = OptionNode(value: "Honda Menu") let apple = OptionNode(value: "Apple Menu") let orange = OptionNode(value: "Orange Menu") let pear = OptionNode(value: "Pear Menu") let hp = OptionNode(value: "HP Menu") let chrome = OptionNode(value: "Chrome Menu") let samsung = OptionNode(value: "Samsung Menu") mainMenu.addOption(node: vehicle) mainMenu.addOption(node: food) mainMenu.addOption(node: computer) vehicle.addOption(node: ford) vehicle.addOption(node: toyota) vehicle.addOption(node: honda) food.addOption(node: apple) food.addOption(node: orange) food.addOption(node: pear) computer.addOption(node: hp) computer.addOption(node: chrome) computer.addOption(node: samsung) return mainMenu } } 

因此,代码的第一部分是build立我的树数据结构,其余的代码是填充我的树结构与先前定义的节点。 这将与viewController分开,因为这是MVC的模型层。 然后,用这个树结构,我想以编程方式添加代表树结构的button。 因此,例如,第一页将有三个button,即“车辆”,“食物和”计算机“,当用户点击”食物“button时,屏幕将延续到具有另一组button的新的视图控制器,即“苹果”,“橙”和“梨”,希望这是有道理的,谢谢!

谢谢

好吧,按照承诺我写了一个演示项目,希望可以帮助你了解如何工作。 我只是简单地包含您的演示数据,以便您可以更好地遵循: https : //github.com/GeroHerkenrath/SOExDynamicButtonGen

为了在这里提供一个解释(并使之成为一个独立于我的演示的有用答案),一些一般的东西:

如果我正确地理解了你的想法是完全dynamic地确定给定节点显示哪个视图控制器。 即您点击一个button,然后决定的场景显示孩子,如果他们被点击,一个新的场景出现等等。

我说场景,因为这主要是发生了什么,虽然重要的部分实际上是视图控制器。 对于用户来说,两者都可能是可见的,就像在iPad上的主细节视图(在iPhone上基本上是两个表视图控制器分别显示)。 我只是提到这一点,因为你自己提到了设置应用程序,这基本上是一个主/从视图。


现在是这样的事情:

由于你的用户界面基本上是在运行时确定的,所以我build议不要使用场景和插件。 我的示例项目显示了这一点,并有一些进一步的解释(我将在这里添加在底部),这是为什么。 您可以使用故事板作为基本上 所需的视图控制器 的集合 (如“存储库”) ,然后通过标识符实例化 。 在我的例子中,我只是演示了这个使用表视图控制器(或更确切地说,一个重复使用)和一个导航视图控制器。 您的用户界面可能与容器视图或所述主控细节控制器看起来不同。 一旦你实例化一个视图控制器,你可以做任何必要的事情(我把它推到导航堆栈上)。 这可能会变得复杂,但有无尽的可能性,我不能提供一切的演示。 :)导航视图控制器是最简单的例子,但是经常遇到这种情况,而iPhone则严重依赖它(由于屏幕大小)。

所以为了把它变成你的ToDos公式,

  1. 为树中的节点types创build视图控制器(取决于你如何devise这个)。 给他们一个在故事板中的标识符,但不要连接他们与segues。
  2. 在您的通用用户界面中准备一个导航视图控制器。 从那里,一旦你得到你的树,实例化第一个视图控制器(顶层),准备与根节点,并推到堆栈。
  3. 在这些控制器的代码中,根据需要使用节点的数据来configurationUI。 依靠子节点填充表格单元格,button等
  4. 再次在控制器中,在处理点击表示子元素(我的例子中的单元格)的部分,根据需要实例化一个新的视图控制器,就像您在导航控制器的堆栈开始时一样。 用选定的孩子的数据和子孩子填充它。 推这个。

如上所述,如果你不使用导航视图控制器,你必须做任何你需要的东西(embedded到容器视图或其他),但我想你会有这个地方。 以模态方式显示控制器也可能是一个选项(即不是“按压导航堆栈”,而是调用presentViewController或任何它被调用)。

我希望这可以帮助你理解UI的错综复杂,随时拉我的github项目,并在其中玩耍。 阅读自述文件,我解释了我在那里做了什么。


最后,我将在这里复制我的自述文件的部分,我认为这对于iOS中的所有人来说都是一个有价值的技巧,

有关场景转换的故事板devise和dynamic决策的一般说明

有很多你可以做的故事板,甚至没有他们(我甚至没有去实例化视图控制器时使用普通的旧xibs)。 但是,这并不意味着你应该尽一切努力。 就我个人而言,我总是毫不夸张地说出他们的名字。 我希望我的故事板能够帮助我理解程序的UIstream程。 在我的故事板中,segue是自动尽可能多的。 有一次,我甚至添加了一个segue,我没有使用,只是为了说明会有一个从这里到那里的转换(开销很小,因为它只是一个小故事板条目,并且不会做任何事情)。

如果我想要从代码中实例化出来的“实用”场景/视图控制器,我可以清楚地说明这一点(可惜我不能在故事板上添加注释,那将是国际海事组织),例如,我将它们分组,甚至可以使用不同的故事板,或者我首先与xib解决scheme一起去。

考虑到整个项目的可读性是非常重要的,并且通过标识符不经意地混合实例化以及定期的阶段转换会导致混乱,难以追踪错误。 在这个示例项目中,在DynamicLevelControllertableView(_:didSelectRowAt:)我提供了一个我认为不能做的例子。

我遇到过类似这样的代码的项目,这直接导致了故事板的误导性:故事板看起来像是有一个特定的path,场景带有一个“浮动”的场景,你可能首先想到的是一个可以从任何地方访问的实用程序。 这个实用控制器中的代码突然导致了一个随机点,原本看起来像是一个规则的,很好的场景path。 为了解决这个问题,你必须查看代码中的几个地方,比较标识符等等。 这没有帮助。

有时可能会像以往一样,当你需要做这样的事情,但是如果没有真正的需要这样做,那么不要这样做。