【问题标题】:How to declare a variable type depending on a ternary expression?如何根据三元表达式声明变量类型?
【发布时间】:2019-03-01 09:18:48
【问题描述】:

我有这个枚举:

enum WeatherMapDisplayType {
    case temperature
    case wind
}

我可以这样声明一个变量吗?

let markerView: mode == .temperature ? WeatherMapItemTemp : WeatherMapItemWind = UIView.fromNib()

知道modeWeatherMapDisplayType 类型

我怎样才能优雅地处理这种情况?

编辑:

我希望能够做这样的事情:

let markerView: WeatherMapItem = UIView.fromNib()
markerView.frame = CGRect(x: 0, y: 0, width: 80, height: 30)
markerView.setupWeatherInformations(mode: self.currentDisplayMode, forecast: forecasts)
marker.iconView = markerView

以前我只有WeatherMapItem 类型。

然后我被要求添加另一个天气图项目,这就是为什么我现在有WeatherMapItemTempWeatherMapItemWind(也对应于我的枚举显示类型)。


func setupWeatherInformations(forecast: Forecast.HourlyForecast)

这是我的自定义类中的一种方法,用于配置网点。

但是如果我从框架中初始化我的自定义视图,我将无法访问此方法,因为它是 UIView 类型的。

【问题讨论】:

  • 这里最优雅的方式很可能是使用enums with associated values以适当类型作为关联值的markerView.
  • WeatherMapItemTemp 是什么?还是WeatherMapItemWind
  • 这是我自定义的 UIView 类。你能用示例写一个答案,以便我将其标记为已回答吗?
  • @Balanced 答案已更新,请检查
  • @Balanced 是的,您需要从 nib 加载更新的答案请检查

标签: swift enums variable-declaration ternary


【解决方案1】:

为这些视图添加一个通用协议:

protocol WeatherMapItem where Self: UIView {
    func setupWeatherInformations()
}

class WeatherMapItemTemp: UIView, WeatherMapItem {
    func setupWeatherInformations() {
        // setup
    }
}

class WeatherMapItemWind: UIView, WeatherMapItem {
    func setupWeatherInformations() {
        // setup
    }
}

将计算变量添加到枚举中:

enum WeatherMapDisplayType {
    case temperature
    case wind

    var view: (UIView & WeatherMapItem)? {
        var nibName: String? = nil
        switch self {
        case .temperature:
            nibName = "WeatherMapItemTemp"
        case .wind:
            nibName = "WeatherMapItemWind"
        }
        if let nibName = nibName, let views = Bundle.main.loadNibNamed(nibName, owner: nil), views.count > 0 {
            return views[0] as? UIView & WeatherMapItem
        }
        return nil
    }
}

现在您可以像这样生成视图:

// assuming mode is the variable of type WeatherMapDisplayType
let view = mode.view
view?.setupWeatherInformations()
return view

【讨论】:

  • 不知道计算变量。它很强大。谢谢,这正是我想要的。
【解决方案2】:

更新答案

如果您想在单个三元语句中设置数据,则在您的自定义视图类中声明一个函数。 类似以下的东西

class WeatherMapItemTemp: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    public func setForecast(forecastData: Forecast) -> WeatherMapItemTemp {
        let view = WeatherMapItemTemp.init(frame: CGRect.init(x: 0, y: 0, width: 100, height: 100))

        //Set your appropriate value to your view objects
        return view
    }
}

如下使用这个

let markerView = mode == .temperature ? (WeatherMapItemTemp().setForecast(forecastData: YOUR_FORECAST_OBJ)) : (WeatherMapItemWind().setForecast(forecastData: YOUR_FORECAST_OBJ))

更新 2

是的,你需要从笔尖加载它

如下更新 setForecast。

class func setForecast(forecastData: Forecast) -> WeatherMapItemTemp {
        let view = UINib(nibName: "WeatherMapItemTemp", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! WeatherMapItemTemp

        //Do your further stuff here
        return view
    }

【讨论】:

  • 是的,我的自定义类就是这样。检查我编辑的问题。
  • 我正在测试它。在这里加载我的 XIB 文件(和网点)不会有问题吗?
  • 不出所料,我的网点有问题。我需要 loadFromNib 吗?
  • 感谢您的帮助,接受的答案是“更优雅”。但你也对我的想法很有帮助。真诚的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
  • 2019-06-08
  • 2015-04-28
相关资源
最近更新 更多