Рефакторинг панели инструментов в другой файл - PullRequest
0 голосов
/ 13 июня 2019

Опытный кодер Swift UIKit, но определенно не с SwiftUI.Допустим, у меня есть следующий код:

HStack {
    Button(
        action: { self.createNode() },
        label: {
            Text("ADD").bold().font(.system(size: 40)).frame(width: 200, height: 80).background(Color.yellow).cornerRadius(5)
    })
    Spacer()
    Button(
        action: { self.deleteNode() },
        label: {
            Text("DELETE").bold().font(.system(size: 40)).frame(width: 200, height: 80).background(Color.yellow).cornerRadius(5)
    })
}

A очень простая панель инструментов.Но теперь давайте добавим (а) еще четыре Buttons и поместим это в «корневое» представление.Делает для того, что в UIKit мы называем контроллером массивного представления .

Я пытаюсь вывести весь этот HStack из корневого представления, но у меня возникают проблемы с action.Я знаю, что могу создавать ViewModifiers, настраиваемые представления и - по крайней мере, до некоторой степени - переносить некоторые вещи в расширения.Но я не смог нигде переместить это расширение «блокировка, запас и ствол».Я застрял, пытаясь переместить createNode() и deleteNode() куда-либо еще.

Я уверен, что я пытаюсь втиснуть квадратный колышек (UIKit) в круглое отверстие (SwiftUI),но ни один из сеансов WWDC или других ресурсов, которые я обнаружил, не указывает мне правильное направление.Чего мне не хватает?

РЕДАКТИРОВАТЬ:

Вот каковы эти два действия - они работают правильно.

@State var nodes: [Node] = []

func createNode() {
    let newNodeName = nodes.count + 1
    let newNode = Node(name: newNodeName)
    nodes.append(newNode)
}
func deleteNode() {
    if nodes.count != 0 {
        nodes.remove(at: nodes.count - 1)
    }
}

Мой вопрос не оСвифт, или о поддержании массива.Речь идет о SwiftUI и о том, как «преобразовать» мой текущий файл из 140 строк в более мелкие вещи - в этом случае, удалив «верхнюю панель» HStack в его собственный файл в Xcode.

Этот горизонтальный стек кнопок в конечном итоге будет иметь номер 5 (это приложение только для iPad), и моя проблема заключается в том, как правильно перемещать кнопку "действия", введите () -> Void.

Подробнее, вотупрощенное представление всего файла (извините за уценку, я не смог найти лучшего способа представить это):

HStack    
    VStack
       HStack  <-- Contains the Buttons that add/delete the nodes
       HStack
       HStack  <-- Contains the nodes themselves, will soon contain thumbnails    
    List

Если мой HStack состоит из горизонтальной строки Text представлений, онработает отлично.Но когда я пытаюсь переместить Button (будь то вложенный в HStack или автономный) в отдельный файл, у меня возникают проблемы со сборкой.

1 Ответ

1 голос
/ 13 июня 2019

Я предлагаю рефакторинг действий и @State в модель представления.

final class ViewModel: BindableObject {

    let didChange = PassthroughSubject<Void, Never>()

    var nodes: [Node] = [] {
        didSet {
            didChange.send(())
        }
    }

    func createNode() {
        let newNodeName = nodes.count + 1
        let newNode = Node(name: newNodeName)
        nodes.append(newNode)
    }

    func deleteNode() {
        if nodes.count != 0 {
            nodes.remove(at: nodes.count - 1)
        }
    }

}

Все представления, которым необходим доступ к действиям, должны объявить это свойство:

@EnvironmentObject var viewModel: ViewModel

Подробнее о @EnvironmentObject здесь .

При каждом изменении узлов будут перерисовываться все подпредставления, которые объявляют объект среды.

Вам нужно только установить объект средыв представлении контейнера для передачи всех подпредставлений.

например,

ContentView().environmentObject(ViewModel())

Иерархия представлений :

HStack    
    VStack
       HStack  <- @EnvironmentObject (will call the actions)
       HStack
       HStack  <- @EnvironmentObject (will use viewModel.nodes to display nodes)
    List
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...