This can be done by using Trait Variations on stack views, changing the Axis between Vertical and Horizontal.
Consider this layout - I've given the labels background colors to help visualize:
![enter image description here]()
- Each "name / Value" label set is in a Vertical Stack View
- Each "Pair" of "sets" - Power / Slope, Distance / Elapsed Time, Heart Rate / Cadence - is also in their own Vertical Stack View
- The 3 "pairs" are in a Horizontal Stack View
Select the RedPairStack and, in the Attributes Inspector pane, click the + icon to the left of the Axis:
![enter image description here]()
From that popup, change Width to Any and change Height to Compact and click Add Variation:
![enter image description here]()
For the new hC variation, select Horizontal:
![enter image description here]()
Do the same for the GreenPairStack and the BluePairStack.
Now, when the device is has a Regular Height, those three stack views will use a Vertical Axis... in Compact Height, they'll use a Horizontal Axis.
Here's the result:
![enter image description here]()
![enter image description here]()
Here is the source to the Storyboard so you can inspect everything: https://pastebin.com/dqNp8CcC
Edit - after comments...
To get side-by-side, we need a few changes:
![enter image description here]()
Looks very similar, but:
- embedded the "label/value" horizontal stack in a
UIView - "PairsContainerView" (cantaloupe background)
- embed that view plus the Map view in a Vertical stack view
I removed the Trait variations from the PairStacks, then constrained the HorizontalStack to all 4 sides of the "PairsContainerView"
The result looks good at first, but when rotating the labels get stretched out. So, we add a couple new Trait Variations.
First, set the Content Hugging Priority on all the labels to Required.
Next, for Compact Height (hC) trait, we add a CenterY constraint to the HorizontalStack, and remove the Top and Bottom constraints.
Here's the new results:
![enter image description here]()
![enter image description here]()
and with colors removed:
![enter image description here]()
![enter image description here]()
Since you didn't provide an image of how you want your layout to look, this may be close enough to get you on your way.
New Storyboard souce: https://pastebin.com/TkVbNUVE
Edit 2
Start with the first example above...
Add a UIView as a sibling of the Map View and assign its Custom Class to HeartRateView:
![enter image description here]()
Here's my quick HeartRateView (red squiggly line):
class HeartRateView: UIView {
let shapeLayer = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
layer.addSublayer(shapeLayer)
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineWidth = 1.0
let pth = UIBezierPath()
let topY: CGFloat = 40.0
var pt: CGPoint = CGPoint(x: 0.0, y: topY)
pth.move(to: pt)
for _ in 1...30 {
pt.x += 2
pt.y = topY + CGFloat.random(in: 0...40)
pth.addLine(to: pt)
}
shapeLayer.path = pth.cgPath
}
}
Add these constraints to HeartRateView:
- Top equal to MapView Top
- Leading equal to MapView Leading
- Width equal to MapView Width
- Height equal to MapView Height
As you would expect, this will "overlay" the HeartRateView on the MapView.
Now, in Storyboard, switch the Orientation to Landscape and click the "Vary for Traits" button. From that popup, select Height
Select the MapView in the Document Outline pane, and over in the Size Inspector pane, select the Trailing to Safe Area and Leading to Heart Rate View constraints:
![enter image description here]()
Tap Delete on your keyboard - it will delete those constraints only for this Trait variation. Should look like this:
![enter image description here]()
and your view should look like this:
![enter image description here]()
Select the Heart Rate View and constrain its Trailing to the Safe Area (I'm using 4-pts padding on everything). Your view should now look like this (Heart Rate View has a clear background, so we can only see the selection handles):
![enter image description here]()
Now add a constraint from MapView Trailing to HeartRateView Leading (of 4 for the little padding):
![enter image description here]()
Because HeartRateView is still constrained Equal Width to MapView, they automatically fill out the width.
Last step, click Done Varying
Now we get this output:
![enter image description here]()
![enter image description here]()
Here's the third Storyboard source: https://pastebin.com/2hPXisAH