Skip to content

Commit

Permalink
Add Devices iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
finestructure committed Jan 26, 2020
1 parent 9427581 commit bcef8b3
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ However, Gala doesn't stop there. It also offers a few other "attribute iterator
- `LegibilityWeights`
- `VerticalSizeClasses`

## Layouts

In addition, you can iterate over a given set of layouts as follows:

```
Expand All @@ -54,6 +56,42 @@ In addition, you can iterate over a given set of layouts as follows:
}
```

This is convenient if you have a range of frames you want to set your view up for.

## Devices

You can also pass in a set of devices to the `Device` iterator:

```
static var previews: some View {
Devices([.iPhoneX, .iPhone11]) {
ContentView()
}
}
```

Thanks to autocompletion you don't have to remember the precise names. Please note that particular care has been taken to transform Apple's fantastic product names into identifiers. For instance:

- `iPadPro9·7inch`
- `iPhoneXʀ`
- `appleWatchSeries5﹘40mm`

Thanks to Swift's support of unicode identifiers you can use these (and thanks to autocomplete you can actually enter them 😅).

You can also use `Devices.iPhones` (`iPads`, `watches`, `tvs`) to preview all of them:

```
static var previews: some View {
Devices(.iPhones) {
ContentView()
}
}
```

Please note that these can take a while to render though, so it's not something that's advisable for a screen you use a lot. But it's a great use for a separate file where you set up marketing shots and want them for the full set of devices.

## Name parameter

All iterators take an optional `name` parameter which will add a `previewDisplayName` with the `name` and a description of the attribute to the preview.

## Contributing
Expand Down
74 changes: 74 additions & 0 deletions Sources/Gala/Device.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// Device.swift
//
//
// Created by Sven A. Schmidt on 26/01/2020.
//

import SwiftUI


public enum Device: String, CaseIterable, CustomStringConvertible {
case iPadMini4 = "iPad mini 4"
case iPadAir2 = "iPad Air 2"
case iPadPro9·7inch = "iPad Pro (9.7-inch)"
case iPadPro12·9inch = "iPad Pro (12.9-inch)"
case iPad5thGen = "iPad (5th generation)"
case iPadPro12·9inch2ndGen = "iPad Pro (12.9-inch) (2nd generation)"
case iPadPro10·5inch = "iPad Pro (10.5-inch)"
case iPad6thGen = "iPad (6th generation)"
case iPad7thGen = "iPad (7th generation)"
case iPadPro11inch = "iPad Pro (11-inch)"
case iPadPro12·9inch3rdGen = "iPad Pro (12.9-inch) (3nd generation)"
// 2020-01-26 sas: this one failed to launch the preview for me:
// case iPadMini5thGen = "iPad mini (5th generation)"
case iPadAir3rdGen = "iPad Air (3rd generation)"

case iPhone6s = "iPhone 6s"
case iPhone6sPlus = "iPhone 6s Plus"
case iPhoneSE = "iPhone SE"
case iPhone7 = "iPhone 7"
case iPhone7Plus = "iPhone 7 Plus"
case iPhone8 = "iPhone 8"
case iPhone8Plus = "iPhone 8 Plus"
case iPhoneX = "iPhone X"
case iPhoneXs = "iPhone Xs"
case iPhoneXsMax = "iPhone Xs Max"
case iPhoneXʀ = "iPhone Xʀ"
case iPhone11 = "iPhone 11"
case iPhone11Pro = "iPhone 11 Pro"
case iPhone11ProMax = "iPhone Pro Max"

case appleWatchSeries2﹘38mm = "Apple Watch Series 2 - 38mm"
case appleWatchSeries2﹘42mm = "Apple Watch Series 2 - 42mm"
case appleWatchSeries3﹘38mm = "Apple Watch Series 3 - 38mm"
case appleWatchSeries3﹘42mm = "Apple Watch Series 3 - 42mm"
case appleWatchSeries4﹘40mm = "Apple Watch Series 4 - 40mm"
case appleWatchSeries4﹘44mm = "Apple Watch Series 4 - 44mm"
case appleWatchSeries5﹘40mm = "Apple Watch Series 5 - 40mm"
case appleWatchSeries5﹘44mm = "Apple Watch Series 5 - 44mm"

case appleTV4K = "Apple TV 4K"

public var previewDevice: PreviewDevice { PreviewDevice(stringLiteral: rawValue) }
public static var iPads: [Device] { allCases.filter { $0.rawValue.hasPrefix("iPad") } }
public static var iPhones: [Device] { allCases.filter { $0.rawValue.hasPrefix("iPhone") } }
public static var watches: [Device] { allCases.filter { $0.rawValue.hasPrefix("Apple Watch") } }
public static var tvs: [Device] { allCases.filter { $0.rawValue.hasPrefix("Apple TV") } }

public var description: String {
let trim = "Apple Watch "
if rawValue.hasPrefix(trim) {
return String(rawValue.dropFirst(trim.count))
}
return rawValue
}
}


extension Array where Element == Device {
public static var iPads: [Element] { Device.iPads }
public static var iPhones: [Element] { Device.iPhones }
public static var watches: [Element] { Device.watches }
public static var tvs: [Element] { Device.tvs }
}
8 changes: 8 additions & 0 deletions Sources/Gala/Gala.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,11 @@ public func ContentSizeCategories<A: View>(_ name: String? = nil, @ViewBuilder i
.environment(\.sizeCategory, item)
}
}

public func Devices<A: View>(_ devices: [Device], _ name: String? = nil, @ViewBuilder items: @escaping () -> A) -> some View {
ForEach(devices, id: \.self) { item in
items()
.previewDisplayName(name.map { "\($0) \(item)" } ?? "\(item)")
.previewDevice(item.previewDevice)
}
}

0 comments on commit bcef8b3

Please sign in to comment.