簡體   English   中英

如何快速從樹數據結構制作UIButton

[英]How to make UIButtons from a tree data structure in swift

我有一個樹數據結構,並希望使用該樹結構來生成按鈕,以通過新的視圖控制器以編程方式為其子對象選擇按鈕,就像在Apple的設置菜單中,您可以選擇不同的選項,並且在您點擊隨機父對象時,它將為孩子們辯護。

    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

    }
}

因此,代碼的第一部分是建立我的樹數據結構,其余的代碼是使用先前定義的節點填充我的樹結構。 這將與viewController分開,因為這是MVC的模型層。 然后,使用該樹結構,我想以編程方式添加表示樹結構的按鈕。 因此,例如,第一頁將具有三個按鈕,分別是“交通工具”,“食物”和“計算機”,並且當用戶點擊說“食物”按鈕時,屏幕將通過另一組按鈕選擇到新的視圖控制器,即“ Apple”,“ Orange”和“ Pear”,希望這很有道理,謝謝!

謝謝

好的,正如我所答應的,我編寫了一個演示項目,希望可以幫助您了解它是如何工作的。 我只包含了您的演示數據,因此您可以更好地遵循: https : //github.com/GeroHerkenrath/SOExDynamicButtonGen

為了在此處提供SO的解釋(並使其成為獨立於我的演示的有用答案),一些常規事項:

如果我正確理解您的想法,則是完全動態地確定要顯示給定節點的視圖控制器。 即,您單擊一個按鈕,然后確定的場景將顯示孩子,如果單擊了孩子,則會出現一個新場景,依此類推。

我說場景,是因為這主要是發生的事情,盡管重要的部分實際上是視圖控制器。 對用戶而言,這兩個都可能是可見的,就像在iPad上的主視圖中一樣(在iPhone上,基本上是兩個單獨顯示的表格視圖控制器)。 我之所以這樣說是因為您自己是指“設置”應用程序,它基本上是一個“主視圖/詳細視圖”。


現在這是事情:

由於您的用戶界面基本上是在運行時確定的,因此我建議不要使用場景和場景。 我的示例項目顯示了這一點,並提供了有關其原因的進一步說明(我將在此處在底部添加)。 您可以將故事板基本上用作 所需視圖控制器 的集合 (如“存儲庫”) ,然后通過標識符實例化 在我的示例中,我僅使用表視圖控制器(或更確切地說,是反復使用的控制器)和導航視圖控制器進行了演示。 您的UI可能看起來有所不同,帶有容器視圖或所述主詳細信息控制器。 實例化視圖控制器后,就可以使用它進行任何必要的操作(我將其推入導航堆棧)。 這可能會變得很復雜,但是存在無限的可能性,我無法提供所有內容的演示。 :)導航視圖控制器是最簡單的示例,但它是一個經常遇到的示例,並且iPhone嚴重依賴它(由於屏幕尺寸)。

因此,將其形成為您的ToDos公式:

  1. 為樹中的節點類型創建視圖控制器(取決於您如何設計)。 在情節提要中給他們一個標識符,但不要將它們與segue連接起來。
  2. 在常規UI中准備一個導航視圖控制器。 由此,一旦您獲得了樹,就實例化第一個視圖控制器(頂層),並用根節點准備它,並將其壓入堆棧。
  3. 在這些控制器的代碼中,根據需要使用節點的數據來配置UI。 依靠子節點來填充表格單元格,按鈕等。
  4. 再次在控制器中,在處理代表孩子的元素(在我的示例中為單元格)上單擊的部分中,根據需要實例化一個新的視圖控制器,就像在導航控制器堆棧開始時所做的那樣。 用選定的孩子的數據和子孩子填充它。 推那個。

如前所述,如果您不使用導航視圖控制器,則必須做任何您需要做的事情(將其嵌入到容器視圖中或進行其他操作),但是我想您應該在某個地方擁有它。 模態顯示控制器也可能是一個選項(即不“按入導航堆棧”,而是調用presentViewController或任何被調用的東西)。

我希望這可以幫助您稍微了解一下UI的復雜性,可以隨意拉我的github項目並在其中玩轉。 還請閱讀自述文件,我將解釋我在其中的確切工作。


最后,我將在這里復制自述文件的部分,我認為這對於在iOS上也是新手的每個人也都是有價值的提示:

有關情節提要設計的一般說明以及有關場景過渡的動態決策

使用情節提要,甚至沒有它們,您都可以做很多事情(實例化視圖控制器時,我什至沒有使用普通的舊式xib)。 但是,這並不意味着您應該做所有事情。 就我個人而言,我總是從字面上取他們的名字。 我希望我的情節提要能夠幫助他們在查看程序時了解程序的UI流程。 在我的情節提要中,segue是自動的。 一旦添加了一個序列號,我就不會只是為了清楚地說明從這里到那里的過渡(開銷很小,因為這只是情節提要中的一小部分,因此不會做任何事情)。

如果我想使用從代碼中實例化的“實用”場景/視圖控制器,我會明確說明這一點(可悲的是,我無法將注釋添加到情節提要中,這應該是IMO IMO),例如,我將它們分組,甚至可以使用不同的故事板,或者我首先使用xib解決方案。

重要的是要考慮整個項目的可讀性,並且通過標識符和常規的segues過渡不小心混合實例化會導致混亂,並難以發現錯誤。 在這個示例項目中,我在DynamicLevelControllertableView(_:didSelectRowAt:)提供了一個我認為不可以執行的操作的示例。

我遇到過這樣的項目,這些代碼直接導致情節提要誤導:情節提要看上去場景與某個“浮動”場景有一定的聯系,您可能首先認為它是可以從任何地方訪問的實用程序。 然后,該實用程序控制器中的代碼突然導致原本看起來像是規則的優美場景路徑的隨機點。 為了弄清楚這一點,您必須查看代碼中的幾個位置,比較標識符等等。 那沒有幫助。

像往常一樣,在某些情況下,您需要執行類似的操作,但是如果沒有真正的需要,則不必這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM