Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,5 @@
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ struct ButtonPreview: View {
Text("Leading").tag(ButtonVM.ImageLocation.leading)
Text("Trailing").tag(ButtonVM.ImageLocation.trailing)
}
Picker("Image Rendering Mode", selection: self.$model.imageRenderingMode) {
Text("Default").tag(Optional<ImageRenderingMode>.none)
Text("Template").tag(ImageRenderingMode.template)
Text("Original").tag(ImageRenderingMode.original)
}
Picker("Image Source", selection: self.$model.imageSrc) {
Text("SF Symbol").tag(ButtonVM.ImageSource.sfSymbol("camera.fill"))
Text("Local").tag(ButtonVM.ImageSource.local("avatar_placeholder"))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Defines the image source options for a button.
extension ButtonVM {
/// Defines the image source options for a button.
public enum ImageSource: Hashable {
/// An image loaded from a system SF Symbol.
///
Expand Down
14 changes: 8 additions & 6 deletions Sources/ComponentsKit/Components/Button/Models/ButtonVM.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public struct ButtonVM: ComponentVM {
/// Defaults to `.leading`.
public var imageLocation: ImageLocation = .leading

/// Defines how image is rendered.
public var imageRenderingMode: ImageRenderingMode?

/// The source of the image to be displayed.
public var imageSrc: ImageSource?

Expand Down Expand Up @@ -184,15 +187,14 @@ extension ButtonVM {
extension ButtonVM {
var image: UIImage? {
guard let imageSrc else { return nil }
switch imageSrc {

let image = switch imageSrc {
case .sfSymbol(let name):
return UIImage(systemName: name)?.withTintColor(
self.foregroundColor.uiColor,
renderingMode: .alwaysOriginal
)
UIImage(systemName: name)
case .local(let name, let bundle):
return UIImage(named: name, in: bundle, compatibleWith: nil)
UIImage(named: name, in: bundle, compatibleWith: nil)
}
return image?.withRenderingMode(self.imageRenderingMode)
}
}

Expand Down
50 changes: 50 additions & 0 deletions Sources/ComponentsKit/Shared/Types/ImageRenderingMode.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import SwiftUI
import UIKit

/// A type that indicates how images are rendered.
public enum ImageRenderingMode {
/// A mode that renders all non-transparent pixels as the foreground
/// color.
case template
/// A mode that renders pixels of bitmap images as-is.
///
/// For system images created from the SF Symbol set, multicolor symbols
/// respect the current foreground and accent colors.
case original
}

// MARK: - UIKit Helpers

extension ImageRenderingMode {
var uiImageRenderingMode: UIImage.RenderingMode {
switch self {
case .template:
return .alwaysTemplate
case .original:
return .alwaysOriginal
}
}
}

extension UIImage {
func withRenderingMode(_ mode: ImageRenderingMode?) -> UIImage {
if let mode {
return self.withRenderingMode(mode.uiImageRenderingMode)
} else {
return self
}
}
}

// MARK: - SwiftUI Helpers

extension ImageRenderingMode {
var imageRenderingModel: Image.TemplateRenderingMode {
switch self {
case .template:
return .template
case .original:
return .original
}
}
}