Our task was to update Worldtrotter with StackViews. I guess the authors meant to update the individual views. In case of Conversion one can delete all the constraints of the individual objects and then add a StackView and place all objects inside, set margins, top and bottom and use autolayout.
In case of the Map the StackView has to be added programmatically. The main change here is to make the stackview the actual view. The difficult part is to get the segmentcontrol overlay the map. I searched and found a solution (Keith Harrison https://useyourloaf.com/blog/stack-view-background-color/). Here is the whole code. Not shown is the UIView extension file, which has to be added as a separate swift file and can be found in the tutorial.
class MapViewController: UIViewController, MKMapViewDelegate {
// Variable declarations
var mapView: MKMapView!
var stackView:UIStackView!
var innerStackView: UIStackView!
var segmentStack: UIStackView!
override func loadView() {
// Creating an instance of a stackview and make it the main view
stackView = UIStackView()
stackView.alignment = .fill
view = stackView
// Creating another instance of a stackview for the map
innerStackView = UIStackView()
innerStackView.axis = .vertical
innerStackView.spacing = 5
innerStackView.alignment = .fill
mapView = MKMapView()
mapView.delegate = self
innerStackView.insertArrangedSubview(mapView, at: 0)
// Top Buttons for changing Map View
let standardString = NSLocalizedString("Standard", comment: "Standard map view")
let hybridString = NSLocalizedString("Hybrid", comment: "Hybrid map view")
let satelliteString = NSLocalizedString("Satellite", comment: "Satellite map view")
let segmentedControl = UISegmentedControl(items: [standardString, hybridString, satelliteString])
segmentedControl.backgroundColor = UIColor.white.withAlphaComponent(0.5)
segmentedControl.selectedSegmentIndex = 0
segmentedControl.addTarget(self, action: #selector(MapViewController.mapTypeChanged(_:)), for: .valueChanged)
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
segmentStack = UIStackView()
segmentStack.axis = .horizontal
segmentStack.alignment = .top
segmentStack.distribution = .equalCentering
segmentStack.layoutMargins = UIEdgeInsets(top: 30, left: 10, bottom: 0, right: 10)
segmentStack.isLayoutMarginsRelativeArrangement = true
segmentStack.insertArrangedSubview(segmentedControl, at: 0)
stackView.insertArrangedSubview(innerStackView, at: 0)
}
// Function to create a foreground
func pinForeground(_ view: UIView, to stView: UIStackView) {
view.translatesAutoresizingMaskIntoConstraints = false
stView.addSubview(view)
view.pin(to: stView)
}
// Function to set the map view type
func mapTypeChanged(_ segControl: UISegmentedControl) {
switch segControl.selectedSegmentIndex {
case 0:
mapView.mapType = .standard
case 1:
mapView.mapType = .hybrid
case 2:
mapView.mapType = .satellite
default:
break }
}
// Function when view is called
override func viewDidLoad() {
super.viewDidLoad()
pinForeground(segmentStack, to: innerStackView)
print("MapViewController loaded its view.")
}
}