Skip to content

Commit cea9def

Browse files
devkaranCTMark Pospesel
andauthored
[Issue-50] Support scalable system image. (#57)
* [CM-1245] Support scalable system image. * Fix tvOS compile error. Minor cleanup. * Update README --------- Co-authored-by: Mark Pospesel <[email protected]>
1 parent b7fd931 commit cea9def

File tree

3 files changed

+58
-4
lines changed

3 files changed

+58
-4
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,9 @@ Easily load system images (SF Symbols) from any string-based `Enum`. All you nee
271271

272272
Why bother doing this when it just wraps `UIImage(systemName:)`? Because
273273
1. `UIImage(systemName:)` returns `UIImage?` while `SystemImage.image` returns `UIImage`.
274-
2. Organizing your system images into enums encourages better architecture (and helps avoid stringly-typed errors).
275-
3. Easier to unit test.
274+
2. By default `SystemImage.image` returns images that scale with Dynamic Type.
275+
3. Organizing your system images into enums encourages better architecture (and helps avoid stringly-typed errors).
276+
4. Easier to unit test.
276277

277278
```swift
278279
// Conform your Enum to SystemImage

Sources/YCoreUI/Protocols/SystemImage.swift

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,37 @@ public protocol SystemImage: RawRepresentable where RawValue == String {
2121
///
2222
/// Default implementation calls `loadImage` and nil-coalesces to `fallbackImage`.
2323
var image: UIImage { get }
24+
25+
/// Image will scale according to the specified text style.
26+
///
27+
/// Default implementation is `.body`.
28+
static var textStyle: UIFont.TextStyle? { get }
29+
30+
/// Image configuration to be used in `loadImage()`.
31+
///
32+
/// Default implementation is `UIImage.SymbolConfiguration(textStyle: textStyle)`.
33+
/// Returns `nil` when `textStyle` is `nil`.
34+
static var configuration: UIImage.Configuration? { get }
2435

2536
/// Loads the named system image.
2637
/// - Returns: The named system image or else `nil` if the system image cannot be loaded.
2738
func loadImage() -> UIImage?
2839
}
2940

3041
extension SystemImage {
42+
/// Image will scale according to the specified text style.
43+
public static var textStyle: UIFont.TextStyle? { .body }
44+
45+
/// Image configuration to be used in `loadImage()`.
46+
///
47+
/// Returns `nil` when `textStyle` is `nil`.
48+
public static var configuration: UIImage.Configuration? {
49+
guard let textStyle = textStyle else {
50+
return nil
51+
}
52+
return UIImage.SymbolConfiguration(textStyle: textStyle)
53+
}
54+
3155
/// Fallback image to use in case a system image cannot be loaded.
3256
/// (default is a 16 x 16 square filled with `.systemPink`)
3357
public static var fallbackImage: UIImage {
@@ -44,7 +68,7 @@ extension SystemImage {
4468
/// Default implementation uses `UIImage(systemName:)` passing in the associated `rawValue`.
4569
/// - Returns: The named system image or else `nil` if the system image cannot be loaded.
4670
public func loadImage() -> UIImage? {
47-
UIImage(systemName: rawValue)
71+
UIImage(systemName: rawValue, withConfiguration: Self.configuration)
4872
}
4973

5074
/// A system image for this name value.

Tests/YCoreUITests/Protocols/SystemImageTests.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,22 @@ final class SystemImageTests: XCTestCase {
3232

3333
YCoreUI.isLoggingEnabled = true
3434
}
35-
35+
36+
func test_defaultImageScaling() {
37+
XCTAssertEqual(Symbols.textStyle, .body)
38+
XCTAssertEqual(Symbols.configuration, UIImage.SymbolConfiguration(textStyle: .body))
39+
}
40+
41+
func test_imageWithoutScaling() {
42+
XCTAssertNil(SymbolWithoutScaling.textStyle)
43+
XCTAssertNil(SymbolWithoutScaling.configuration)
44+
}
45+
46+
func test_customImageScaling() {
47+
XCTAssertEqual(SymbolCustomScaling.textStyle, .title1)
48+
XCTAssertEqual(SymbolCustomScaling.configuration, UIImage.SymbolConfiguration(textStyle: .title1))
49+
}
50+
3651
func test_systemImage_deliversDefaultFallback() {
3752
XCTAssertEqual(DefaultSymbols.defaultCase.image.pngData(), DefaultSymbols.fallbackImage.pngData())
3853
}
@@ -59,4 +74,18 @@ extension SystemImageTests {
5974
enum DefaultSymbols: String, CaseIterable, SystemImage {
6075
case defaultCase
6176
}
77+
78+
enum SymbolWithoutScaling: String, CaseIterable, SystemImage {
79+
case checked = "checkmark.square"
80+
case unchecked = "square"
81+
82+
static var textStyle: UIFont.TextStyle? { nil }
83+
}
84+
85+
enum SymbolCustomScaling: String, CaseIterable, SystemImage {
86+
case checked = "checkmark.square"
87+
case unchecked = "square"
88+
89+
static var textStyle: UIFont.TextStyle? { .title1 }
90+
}
6291
}

0 commit comments

Comments
 (0)