Как вы редактируете элементы структуры типа View из другой структуры типа View? (SwiftUI) - PullRequest
1 голос
/ 11 июля 2020

У меня есть следующие 2 структуры в отдельных файлах, которые отображаются в contentView. Я пытаюсь понять, как поддерживать contentView только для отображения и организации пользовательского интерфейса. Размещение всех остальных моих представлений в отдельных файлах. Моя первая мысль заключалась в том, что правильным подходом было бы использование переменных stati c, обновляемых функциями, которые вызываются из действия нажатия кнопки. Но текст кнопок соответственно не обновился. Поскольку они динамически обновляются в соответствии с @State.

update:

Я попытался решить эту проблему с помощью протоколов и делегатов, но безрезультатно. Насколько я понимаю, этот вызов делегата должен быть получен на другом конце и обновлен structcop.ID, и изменение должно быть отражено в представлении содержимого.

FILE 1

import SwiftUI

    struct structdispatch: View {
    
    var radio:RadioDelegate?
    
    func send() {
        radio?.update()
        self.debug()
    }
    
    var body: some View {
        Button(action: self.send)
        {Text("DISPATCHER")}
    }
    func debug() {
        print("Button is sending?")
    }
}
struct structdispatch_Previews: PreviewProvider {
    static var previews: some View {
        structdispatch()
    }
}

**FILE 2:**

import SwiftUI
    
    protocol RadioDelegate {
        func update()
    }
    
    struct structcop: View, RadioDelegate {
        @State public var ID:Int = 3
        func update(){
            print("message recieved")
            self.ID += 1
            print(self.ID)
        }
        var body: some View {
            Text(String(self.ID))
        }
    }
    struct structcop_Previews: PreviewProvider {
        static var previews: some View {
            structcop()
        }
    }

DEBUG CONSOLE RETURNS:

The Button is working

Ответы [ 2 ]

0 голосов
/ 14 июля 2020

Решение:

После некоторого рытья у меня есть рабочее решение, но мне все еще интересно, есть ли способ изменить свойства других структур, сохраняя динамические c обновления просмотра .

Решение: хранить данные для отображения в наблюдаемом объекте, который будет либо читать, либо действовать как модель, с которой взаимодействует пользователь.

Наблюдаемый объект - это настраиваемый объект для ваши данные, которые можно привязать к представлению из хранилища в среде SwiftUI. SwiftUI отслеживает любые изменения наблюдаемых объектов, которые могут повлиять на представление, и отображает правильную версию представления после изменения. -apple

Объявлен новый тип модели, который соответствует протоколу ObservableObject из платформы Combine. SwiftUI подписывается на наблюдаемый объект и обновляет соответствующие представления, которые необходимо обновлять при изменении данных. SceneDelegate.swift должен иметь модификатор .environmentObject(_:), добавленный в ваше root представление.

Свойства, объявленные в ObservableObject, должны иметь значение @Published, чтобы подписчики принимали любые изменения.

Для тестового кода я создал объект ObservableObject с именем штаб-квартира

import SwiftUI
import Combine

final class hq: ObservableObject {
    @Published var info = headQuarters
}

let headQuarters = hqData(id: 3)

struct hqData {
    var id: Int
    mutating func bump() {
        self.id += 1
    }
}

В моем struct dispatch я подписался на объект и вызвал функцию, которая повторяла идентификатор в модели при каждом нажатии кнопки. Мой struct cop также подписался на объект, поэтому модель и текст кнопки обновлялись в соответствии с изменениями.

struct dispatch: View {
    @EnvironmentObject private var hq: headqarters
    var body: some View {
        Button(action: {self.hq.info.bump()}) {
            Text("Button")
        }
    }
}

struct cop: View {
    @EnvironmentObject private var hq: headquarters
    var body: some View {
        Text(String(self.hq.info.id))
    }
}
0 голосов
/ 11 июля 2020

Представление обновляется при некоторых внутренних DynamicProperty изменениях, например @State, поэтому вот возможное решение

Протестировано с Xcode 12 / iOS 14

struct structcop: View {
    static public var ID = 3
    @State private var localID = Self.ID {
        didSet {
            Self.ID = localID
        }
    }
    var body: some View {
        Button(action: printme)
            {Text(String(localID))}
    }

    func printme(){
        self.localID = 5
        print(structcop.ID)
    }
}
...