1

I have this enum :

enum WeatherMapDisplayType {
    case temperature
    case wind
}

Can I declare a variable like this ?

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

Knowing that mode is of type WeatherMapDisplayType

How can I handle this scenario in an elegant way ?

EDIT:

I want to be able to do something like this :

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

Previously I only had WeatherMapItem type.

Then I have been asked to add an other weather map item, that is why I have the WeatherMapItemTemp and WeatherMapItemWind now (also corresponding to my enum display type).


func setupWeatherInformations(forecast: Forecast.HourlyForecast)

This is a method in my custom classes in order to configure the outlets.

But I don't have access to this method if I init my custom view from frame, because it's of UIView type.

5
  • 3
    Most elegant way here most likely would be using enums with associated values. markerView with proper type as associated value. Commented Mar 1, 2019 at 9:26
  • What's WeatherMapItemTemp? Or WeatherMapItemWind? Commented Mar 1, 2019 at 9:31
  • It's my custom UIView classes. Can you write an answer with example so that I mark it as answered ? Commented Mar 1, 2019 at 9:33
  • @Balanced Answer updated please check Commented Mar 1, 2019 at 10:44
  • @Balanced yes you will need to load from nib answer updated please check Commented Mar 1, 2019 at 11:57

2 Answers 2

1

Add a common protocol to these views:

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

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

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

Add a computed variable to the enum:

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
    }
}

Now you can generate a view like so:

// assuming mode is the variable of type WeatherMapDisplayType
let view = mode.view
view?.setupWeatherInformations()
return view
Sign up to request clarification or add additional context in comments.

1 Comment

Didn't know about the computed variable. It's powerful. Thank you, this is exactly what I was looking for.
1

Updated Answer

If you want to set data in that single ternary statement then declare one function in your custom view class. Something like following

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
    }
}

Use this as following

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

Update 2

Yes you will need to load that from a nib

Update setForecast as following.

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
    }

4 Comments

Yes, my custom classes are like that. Check my edited question.
I am testing it. There won't be an issue loading my XIB file (and outlets) here ?
As expected, I have the issue with my outlets. I need to loadFromNib no?
Thank you for your help, the accepted answer is "more elegant". But you helped me well in my thoughts too. Sincerely.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.