SwiftUI - разверните необязательные данные изображения для создания изображения на основе UIImage (данные) - PullRequest
2 голосов
/ 21 апреля 2020

Я нашел эту ссылку , и в некоторых ответах говорится, что мы можем решить две задачи:

  • При необходимости отобразить элемент представления
  • Или вместо этого отобразить значение по умолчанию если найдено nil

У меня есть модель данных, которая содержит необязательный Data, который я правильно использую для своего элемента Image на View.

В настоящее время, поскольку я не нашел способ обойти это и использовать этот знак !, который небезопасен:

Image(uiImage: UIImage(data: userService.user.imageData!)!)

Конечно, я не могу гарантировать это, и я не должен использовать это, но мне нужна помощь, как развернуть это.

В качестве быстрого обходного пути я могу сделать это свойство данных изображения необязательным, а затем загрузить некоторые данные из локального файла, но даже тогда у меня все еще есть еще одно принудительное развертывание здесь UIImage(data.

Ответы [ 3 ]

1 голос
/ 21 апреля 2020

Следующий вариант является простым и безопасным (если вам необходимо всегда иметь изображение в иерархии представления), поскольку UIImage(data: Data()) всегда создает действительное пустое изображение.

Image(uiImage: UIImage(data: userService.user.imageData ?? Data())!)
1 голос
/ 21 апреля 2020

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

extension Image {

    public init?(data: Data?) {
        guard let data = data,
            let uiImage = UIImage(data: data) else {
                return nil
        }
        self = Image(uiImage: uiImage)
    }
}

Тогда вы можете просто использовать его следующим образом:

Image(data: userService.user.imageData)

так как это nullable, оно должно содержаться в другом View как минимум с одним другим View.

Если вы хотите предоставить заполнитель вместо отсутствующего изображения, вы можете использовать расширение как this:

extension Image {

    public init(data: Data?, placeholder: String) {
        guard let data = data,
          let uiImage = UIImage(data: data) else {
            self = Image(placeholder)
            return
        }
        self = Image(uiImage: uiImage)
    }
}

Тогда вы можете просто использовать его следующим образом:

Image(data: userService.user.imageData, placeholder: "nameOfPlaceholder")

, поскольку это не nullable, его не нужно содержать в другом View с хотя бы еще один View.

1 голос
/ 21 апреля 2020

Подход:

  • Использование операторов управления
  • Использование AnyView для стирания типа

Причина AnyView

  • Вам необходимо стереть тип так, чтобы ваше представление последовательно возвращало один и тот же тип представления независимо от того, какой путь выполнения он принимает (независимо от того, удовлетворен оператор if или нет).
  • Таким образом он возвращает AnyView независимо от того, что и будет удовлетворять типу тела (some View)

Пример:

  • Если данные действительные данные изображения, изображение будет отображаться
  • Если нет, то отображается пустой вид

Примечание: Вместо пустого вида вы можете отобразить любой другой просмотр.

код:

import SwiftUI

class Model : ObservableObject {
    var data : Data?

    init(data: Data?) {
        self.data = data
    }
}

struct ContentView: View {

    @ObservedObject var model : Model

    var body: some View {

        let view : AnyView

        if let data = model.data,
            let uiimage = UIImage(data: data) {
            view = AnyView(Image(uiImage: uiimage))
        }
        else {
            view = AnyView(EmptyView()) //You could have view = AnyView(Text("no image found"))
        }

        return view
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...