An interactive pizza-selection app: an animated opening, a carousel of pizzas, a size picker that resizes the pizza with it, and a live total.
Built for iOS 26 in SwiftUI, Swift 6.
Open PizzaLab.xcodeproj and run. Nothing to install — no package
dependencies. The menu comes from https://oursongapp.com/api/pizzas; after
the first launch it is cached, so the app also opens without a network.
Tests: ⌘U.
- Opening. Eight slices fly in and assemble a pizza on a white page, the disc grows in beneath it, and the catalogue opens around it from the top and the bottom. The menu loads while all this plays, so the reader does not meet a spinner afterwards.
- Carousel. The chosen pizza sits in the middle with its neighbours peeking in from either side; tapping one brings it over.
- Size. S, M and L sit on the disc's own arc. Picking one redraws the pizza at that size — beside a banana that never changes, so the sizes mean something.
- Order. Quantity and total per pizza, so five of one is not five of another. The total is the chosen size's price times the quantity.
- A closer look. Pinch the pizza — or tap the magnifier — and it opens until it fills the screen, the interface moving out of its way rather than a viewer opening over it. The pinch is continuous: the pizza sits wherever the fingers have left it and settles to whichever end is nearer when they lift.
- Architecture — the layers and which way they point.
- Design tokens — where a colour, a typeface or an animation lives, and the geometry two screens share.
- Carousel dragging is not implemented, by decision rather than oversight; a neighbouring pizza is selected by tapping it. The row's position is already a function of the selected index, so a gesture would only have to change which index that is.
- Back, favourite and Add carry no logic, as the brief allows. They are drawn and reachable, and Add has the one place it would call.
- The API's images are about 1024px, which is the ceiling on how sharp the zoom can be. The cache keeps them at full resolution and decodes them before first draw, so nothing is lost on our side of that.
- An opened pizza cannot be panned, only opened and closed. At the resolution above there is little in the corners worth travelling to.
PizzaLabUITestslaunches the app with-uiTesting, which serves it canned JSON, so the one UI test does not depend on a network.