Как мы можем определить тип переменной состояния Any?

#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 Вы сможете назначать разные типы. Смотрите обновленный ответ. Но, пожалуйста, рассмотрите различные подходы, как указано в комментариях.