#swift #swiftui
#swift #swiftui
Вопрос:
Обновление: этот метод предназначен только для целей обучения, не используемых в реальном проекте!(До нового обновления)
Здесь я получаю 2 проблемы с определением переменной состояния как Any
типа. Как вы знаете, мы должны ее инициализировать. Например, в этом коде я должен инициализировать свою переменную состояния с помощью Image, чего я не хочу, весь смысл выбора any в качестве типа заключался в свободе ввода типа, но государство забирает у меня эту свободу, инициализируя ее, и вишня на вершине, я должен принудительно развернуть, чтобы состояниестало доступно для использования!
Итак, с этой проблемой 2 (инициализация принудительное разворачивание) о типе переменной any с состоянием, есть ли у нас способы решения этих проблем?
@State var anyItem: Any = UIImage(named: "apple")!
Вот мое новое обновление кода с помощью master’s:
import SwiftUI
struct ContentView: View
{
@State var anyItem: Any?
@State var changedType: Bool = false
init() {
_anyItem = .init(initialValue: UIImage(named: "Apple"))
}
var body: some View {
if changedType == false
{
Image(uiImage: anyItem as! UIImage)
}
else
{
Text(anyItem as! String)
}
Text("Test")
.onTapGesture
{
chandType.toggle()
anyItem = "anyItem changed to Text! Kaboom!"
}
}
}
V2: расширенная версия
import SwiftUI
struct ContentView: View
{
@State var anyItem: Any?
enum anyItemType { case String, Image, Unknowen }
@State var choosenType: anyItemType = anyItemType.Unknowen
var body: some View {
ZStack
{
VStack
{
if choosenType == anyItemType.String
{
Text(anyItem as! String).bold()
}
else if choosenType == anyItemType.Image
{
Image(uiImage: anyItem as! UIImage).resizable().frame(width: 200, height: 200, alignment: .center).clipShape(Circle())
}
}
VStack
{
Spacer()
Button(choosenType == anyItemType.String ? "Change anyItem Type to Image" : "Change anyItem Type to String")
{
if choosenType == anyItemType.String
{
anyItem = UIImage(named: "Apple")
choosenType = anyItemType.Image
}
else
{
anyItem = "anyItem changed to Text! KABOOOM!"
choosenType = anyItemType.String
}
}.font(Font.body.bold())
}
.padding(.bottom, 100)
}
}
}
Комментарии:
1. Не совсем уверен, чего вы пытаетесь достичь здесь … где-нибудь, присваивая что-то любой переменной, вы потеряли реальный тип, и вам нужно будет восстановить его позже с помощью
is
илиas
. На самом деле это плохой дизайн для swift — используйте либо статические типы, либо общие, иначе у вас возникнут проблемы, рано или поздно, но обязательно.2. да, вы правы, я бы никогда не использовал состояние с типом Any! это вызывает проблемы! сбой сбой сбой! лол
Ответ №1:
Проблема не в том, что Any
. Это потому, что эта строка:
UIImage(named: "apple")
возвращает необязательный ( UIImage?
) .
Если вы хотите anyItem
принимать значения типа UIImage?
, вам нужно сделать это Any?
:
@State var anyItem: Any? = UIImage(named: "apple")
или укажите значение по умолчанию для необязательного:
@State var anyItem: Any = UIImage(named: "apple") ?? UIImage()
Вот пример того, как вы можете инициализировать anyItem
с разными типами (это только для демонстрации и, вероятно, не следует использовать в реальном приложении):
struct ContentView: View {
@State var anyItem: Any?
init() {
_anyItem = .init(initialValue: UIImage(named: "apple"))
}
var body: some View {
Text("Test")
.onAppear {
anyItem = "test"
}
}
}
Но, как уже предположил Аспери, это не очень хорошая идея, и вы обычно хотите избежать использования Any
в SwiftUI.
Комментарии:
1. Ну, вы решили половину проблемы с разверткой! Но существует другая половина проблемы, и это связано с проблемой инициализации, причина выбора Any для меня — получить свободу выбора типа с моим или вашим кодом, на первом шаге теряя эту свободу. Посмотрите на этот код var anyItem: Any? мы можем сделать с этим что угодно позже в наших кодах! Но с вашим кодом мы ограничимся только изображением, например, я не смогу подписывать строку или URL на anyItem, так что эта половина проблемы все еще существует.
2. @Omid Вы сможете назначать разные типы. Смотрите обновленный ответ. Но, пожалуйста, рассмотрите различные подходы, как указано в комментариях.