Add Image component (#45)
* Init Image * Fix RenderingMode, merge Tokamak renaming * Add image props * Add image example * Format comment * Switch image to implicit member expression
This commit is contained in:
parent
7f0373d8c1
commit
cac728b7b5
|
@ -12,6 +12,7 @@
|
|||
607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; };
|
||||
607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
|
||||
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
|
||||
A6D5AF87221B131400DBF186 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6D5AF86221B131400DBF186 /* Image.swift */; };
|
||||
C449B806DFEE55B6CEE6478C /* libPods-TokamakDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B96B435A9D67621D318616E /* libPods-TokamakDemo.a */; };
|
||||
D11DB6432219C03000013FC3 /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D11DB6422219C03000013FC3 /* Timer.swift */; };
|
||||
D1BFAF772215795900845EA0 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BFAF762215795900845EA0 /* Router.swift */; };
|
||||
|
@ -38,6 +39,7 @@
|
|||
607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
8CADEBB8BFF6F2621CA49E8F /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
|
||||
A6D5AF86221B131400DBF186 /* Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = "<group>"; };
|
||||
A9EEF813955DAEEFE1D52ED4 /* Pods-TokamakDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TokamakDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TokamakDemo/Pods-TokamakDemo.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
C6DA99382B6892EAB361742F /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
|
||||
D11DB6422219C03000013FC3 /* Timer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timer.swift; sourceTree = "<group>"; };
|
||||
|
@ -159,6 +161,7 @@
|
|||
D1DEEC2822009E8000C525EE /* ModalRouter.swift */,
|
||||
D1F2C3262214407B008358DC /* TableModal.swift */,
|
||||
D11DB6422219C03000013FC3 /* Timer.swift */,
|
||||
A6D5AF86221B131400DBF186 /* Image.swift */,
|
||||
);
|
||||
path = Components;
|
||||
sourceTree = "<group>";
|
||||
|
@ -274,6 +277,7 @@
|
|||
D11DB6432219C03000013FC3 /* Timer.swift in Sources */,
|
||||
D1F7185322159E09004E5951 /* Controls.swift in Sources */,
|
||||
D1DEEC2922009E8000C525EE /* ModalRouter.swift in Sources */,
|
||||
A6D5AF87221B131400DBF186 /* Image.swift in Sources */,
|
||||
D1BFAF772215795900845EA0 /* Router.swift in Sources */,
|
||||
607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */,
|
||||
D1F7185D2215A4A1004E5951 /* LayerProps.swift in Sources */,
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Image.swift
|
||||
// TokamakDemo
|
||||
//
|
||||
// Created by Matvii Hodovaniuk on 2/18/19.
|
||||
// Copyright © 2019 Tokamak. All rights reserved.
|
||||
//
|
||||
|
||||
import Tokamak
|
||||
|
||||
struct ImageExample: LeafComponent {
|
||||
typealias Props = Null
|
||||
|
||||
static func render(props: Null, hooks: Hooks) -> AnyNode {
|
||||
return StackView.node(.init(
|
||||
alignment: .center,
|
||||
axis: .vertical,
|
||||
distribution: .fillEqually,
|
||||
Edges.equal(to: .safeArea)
|
||||
), [
|
||||
Image.node(.init(name: "tokamak")),
|
||||
])
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "tokamak.jpg",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
|
@ -17,6 +17,7 @@ enum AppRoute: String, CaseIterable {
|
|||
case datePicker = "Date Picker"
|
||||
case layerProps = "Layer Props"
|
||||
case timer
|
||||
case image
|
||||
}
|
||||
|
||||
extension AppRoute: CustomStringConvertible {
|
||||
|
@ -56,6 +57,8 @@ struct Router: NavigationRouter {
|
|||
result = LayerProps.node()
|
||||
case .timer:
|
||||
result = TimerCounter.node()
|
||||
case .image:
|
||||
result = ImageExample.node()
|
||||
}
|
||||
|
||||
return NavigationItem.node(
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// Image.swift
|
||||
// Tokamak
|
||||
//
|
||||
// Created by Matvii Hodovaniuk on 2/17/19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct Image: HostComponent {
|
||||
public typealias Children = [AnyNode]
|
||||
|
||||
public struct Props: Equatable, StyleProps {
|
||||
public enum RenderingMode {
|
||||
case automatic
|
||||
case alwaysOriginal
|
||||
case alwaysTemplate
|
||||
}
|
||||
|
||||
public enum Source: Equatable {
|
||||
case name(String)
|
||||
case data(Data)
|
||||
}
|
||||
|
||||
// when changed initializes new image with `UIImage(named:)`
|
||||
// or `UIImage(data:)`
|
||||
public let source: Source
|
||||
|
||||
// when changed creates new image with `withRenderingMode`
|
||||
public let renderingMode: RenderingMode
|
||||
|
||||
// when changed initializes new image with given scale
|
||||
public let scale: Double
|
||||
|
||||
// mirrors `flipsForRightToLeftLayoutDirection`
|
||||
public let flipsForRTL: Bool
|
||||
|
||||
public let style: Style?
|
||||
|
||||
public init(
|
||||
flipsForRTL: Bool = false,
|
||||
name: String,
|
||||
renderingMode: RenderingMode = .automatic,
|
||||
scale: Double = 1.0,
|
||||
_ style: Style? = nil
|
||||
) {
|
||||
source = .name(name)
|
||||
self.renderingMode = renderingMode
|
||||
self.scale = scale
|
||||
self.flipsForRTL = flipsForRTL
|
||||
self.style = style
|
||||
}
|
||||
|
||||
public init(
|
||||
data: Data,
|
||||
flipsForRTL: Bool = false,
|
||||
renderingMode: RenderingMode = .automatic,
|
||||
scale: Double = 1.0,
|
||||
_ style: Style? = nil
|
||||
) {
|
||||
source = .data(data)
|
||||
self.renderingMode = renderingMode
|
||||
self.scale = scale
|
||||
self.flipsForRTL = flipsForRTL
|
||||
self.style = style
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// Image.swift
|
||||
// TokamakUIKit
|
||||
//
|
||||
// Created by Matvii Hodovaniuk on 2/17/19.
|
||||
//
|
||||
|
||||
import Tokamak
|
||||
import UIKit
|
||||
|
||||
final class TokamakImage: UIImageView, Default {
|
||||
public static var defaultValue: TokamakImage {
|
||||
return TokamakImage()
|
||||
}
|
||||
}
|
||||
|
||||
extension UIImage.RenderingMode {
|
||||
public init(_ rawValue: Image.Props.RenderingMode) {
|
||||
switch rawValue {
|
||||
case .automatic:
|
||||
self = .automatic
|
||||
case .alwaysOriginal:
|
||||
self = .alwaysOriginal
|
||||
case .alwaysTemplate:
|
||||
self = .alwaysTemplate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Image: UIViewComponent {
|
||||
static func update(
|
||||
view box: ViewBox<TokamakImage>,
|
||||
_ props: Image.Props,
|
||||
_ children: [AnyNode]
|
||||
) {
|
||||
var image: UIImage?
|
||||
|
||||
switch props.source {
|
||||
case let .name(name):
|
||||
image = UIImage(named: name)
|
||||
case let .data(data):
|
||||
image = UIImage(data: data, scale: CGFloat(props.scale))
|
||||
}
|
||||
|
||||
if props.flipsForRTL {
|
||||
image = image?.imageFlippedForRightToLeftLayoutDirection()
|
||||
}
|
||||
|
||||
box.view.image = image?.withRenderingMode(.init(props.renderingMode))
|
||||
}
|
||||
}
|
|
@ -21,6 +21,8 @@
|
|||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
D1B4F8DB221AFB0E00C53C42 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4F8D9221AFB0800C53C42 /* Image.swift */; };
|
||||
D1B4F8DD221AFB2B00C53C42 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4F8DC221AFB2B00C53C42 /* Image.swift */; };
|
||||
OBJ_153 /* AnyEquatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_66 /* AnyEquatable.swift */; };
|
||||
OBJ_154 /* AnyNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_67 /* AnyNode.swift */; };
|
||||
OBJ_155 /* Components.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_68 /* Components.swift */; };
|
||||
|
@ -180,6 +182,8 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
D1B4F8D9221AFB0800C53C42 /* Image.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = "<group>"; };
|
||||
D1B4F8DC221AFB2B00C53C42 /* Image.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = "<group>"; };
|
||||
OBJ_10 /* ContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerViewController.swift; sourceTree = "<group>"; };
|
||||
OBJ_100 /* FirstBaseline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstBaseline.swift; sourceTree = "<group>"; };
|
||||
OBJ_101 /* Height.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Height.swift; sourceTree = "<group>"; };
|
||||
|
@ -406,6 +410,7 @@
|
|||
OBJ_17 /* Host */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D1B4F8D9221AFB0800C53C42 /* Image.swift */,
|
||||
OBJ_18 /* Button.swift */,
|
||||
OBJ_19 /* DatePicker.swift */,
|
||||
OBJ_20 /* Label.swift */,
|
||||
|
@ -460,7 +465,7 @@
|
|||
path = Constraint;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
OBJ_5 /* */ = {
|
||||
OBJ_5 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_6 /* Package.swift */,
|
||||
|
@ -472,7 +477,6 @@
|
|||
OBJ_142 /* tokamakui.org */,
|
||||
OBJ_143 /* Products */,
|
||||
);
|
||||
name = "";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
OBJ_55 /* Protocols */ = {
|
||||
|
@ -502,8 +506,8 @@
|
|||
OBJ_66 /* AnyEquatable.swift */,
|
||||
OBJ_67 /* AnyNode.swift */,
|
||||
OBJ_68 /* Components.swift */,
|
||||
OBJ_69 /* Components */,
|
||||
OBJ_117 /* Default.swift */,
|
||||
OBJ_69 /* Components */,
|
||||
OBJ_118 /* Hooks */,
|
||||
OBJ_123 /* MountedComponents */,
|
||||
OBJ_128 /* Null.swift */,
|
||||
|
@ -539,6 +543,7 @@
|
|||
OBJ_70 /* Host */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D1B4F8DC221AFB2B00C53C42 /* Image.swift */,
|
||||
OBJ_71 /* Alert.swift */,
|
||||
OBJ_72 /* Animated.swift */,
|
||||
OBJ_73 /* Button.swift */,
|
||||
|
@ -733,7 +738,7 @@
|
|||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = OBJ_5 /* */;
|
||||
mainGroup = OBJ_5;
|
||||
productRefGroup = OBJ_143 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
|
@ -778,6 +783,7 @@
|
|||
OBJ_175 /* Color.swift in Sources */,
|
||||
OBJ_176 /* Bottom.swift in Sources */,
|
||||
OBJ_177 /* Center.swift in Sources */,
|
||||
D1B4F8DD221AFB2B00C53C42 /* Image.swift in Sources */,
|
||||
OBJ_178 /* CenterX.swift in Sources */,
|
||||
OBJ_179 /* CenterY.swift in Sources */,
|
||||
OBJ_180 /* Constraint.swift in Sources */,
|
||||
|
@ -873,6 +879,7 @@
|
|||
OBJ_276 /* CenterX.swift in Sources */,
|
||||
OBJ_277 /* CenterY.swift in Sources */,
|
||||
OBJ_278 /* Constrainable.swift in Sources */,
|
||||
D1B4F8DB221AFB0E00C53C42 /* Image.swift in Sources */,
|
||||
OBJ_279 /* Constraint.swift in Sources */,
|
||||
OBJ_280 /* FirstBaseline.swift in Sources */,
|
||||
OBJ_281 /* Height.swift in Sources */,
|
||||
|
|
Loading…
Reference in New Issue