0

Before anyone says inheritance.. hear me out first.

I have 2 totally unrelated view controllers. They each have an MKMapView. I would like both of them to conform to and implement the same delegate methods.

For example, I want both to implement:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        let polyline = overlay as! MKPolyline
        let renderer = MKPolylineRenderer(polyline: polyline)
        renderer.strokeColor = UIColor.red
        renderer.lineWidth = 4
        return renderer
    }

Again, these 2 view controllers aren't related at all, so I don't want to make a base class. As a matter of fact, these 2 view controllers are already inheriting from their respective inheritance hierarchy.

7ball
  • 2,183
  • 4
  • 26
  • 61
  • https://stackoverflow.com/questions/46018677/what-is-where-self-in-protocol-extension ? – Larme Jun 06 '18 at 17:54

2 Answers2

4

Use a protocol and a default implementation.

protocol SomeMapFunctions {
    var mapView : MKMapView? { get }

    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
}

extension SomeMapFunctions {
    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        let polyline = overlay as! MKPolyline
        let renderer = MKPolylineRenderer(polyline: polyline)
        renderer.strokeColor = UIColor.red
        renderer.lineWidth = 4
        return renderer
    }
}

class VC1 : UIViewController, SomeMapFunctions {
    var mapView : MKMapView?
}

class VC2 : UIViewController, SomeMapFunctions {
    var mapView : MKMapView?
}

As shown, any common properties that are necessary for the default implementations can be put into the protocol as well.

David Berry
  • 40,941
  • 12
  • 84
  • 95
  • Ahh... the good old `extension` for default implementation trick.. I forgot about this!! Thanks.. it was so obvious. – 7ball Jun 06 '18 at 19:49
0

One solution could be:

protocol CommonStuff {
   func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer 
}

extension CommonStuff where Self: UIViewController {
    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        let polyline = overlay as! MKPolyline
        let renderer = MKPolylineRenderer(polyline: polyline)
        renderer.strokeColor = UIColor.red
        renderer.lineWidth = 4
        return renderer
    }
}

Then, adopting the protocol by both view controllers would provide them the same behaviour.

Mick F
  • 7,312
  • 6
  • 51
  • 98