Skip to content

Commit

Permalink
Merge pull request #147 from Shopify/ftd-cells
Browse files Browse the repository at this point in the history
Simple Cell Examples
  • Loading branch information
raulriera authored Apr 30, 2019
2 parents e2d2964 + a66ba75 commit 353217e
Show file tree
Hide file tree
Showing 21 changed files with 905 additions and 57 deletions.
113 changes: 106 additions & 7 deletions FunctionalTableData.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,20 @@
17E57FF5208A404800BFCC3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 17E57FF3208A404800BFCC3D /* LaunchScreen.storyboard */; };
17E57FFA208A415900BFCC3D /* FunctionalTableData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C7A26FC1F2FA0F800360E9B /* FunctionalTableData.framework */; };
17E57FFB208A415900BFCC3D /* FunctionalTableData.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4C7A26FC1F2FA0F800360E9B /* FunctionalTableData.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
17E58000208A425F00BFCC3D /* LabelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17E57FFF208A425F00BFCC3D /* LabelCell.swift */; };
3624340420D2F40100A75787 /* Array+TableSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3624340320D2F40100A75787 /* Array+TableSection.swift */; };
36C9208D20D3EB7500DA4251 /* TableSectionsValidationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36C9208C20D3EB7500DA4251 /* TableSectionsValidationTests.swift */; };
4C1A850B2254FDC900066633 /* SpacerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A84FA2254FDC900066633 /* SpacerState.swift */; };
4C1A850C2254FDC900066633 /* SpacerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A84FB2254FDC900066633 /* SpacerView.swift */; };
4C1A850D2254FDC900066633 /* LabelState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A84FD2254FDC900066633 /* LabelState.swift */; };
4C1A850E2254FDC900066633 /* ImageState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A84FE2254FDC900066633 /* ImageState.swift */; };
4C1A850F2254FDC900066633 /* CombinedState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A85002254FDC900066633 /* CombinedState.swift */; };
4C1A85102254FDC900066633 /* CombinedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A85012254FDC900066633 /* CombinedView.swift */; };
4C1A85112254FDC900066633 /* SubtitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A85032254FDC900066633 /* SubtitleView.swift */; };
4C1A85122254FDC900066633 /* SubtitleState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A85042254FDC900066633 /* SubtitleState.swift */; };
4C1A85132254FDC900066633 /* SwitchState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A85062254FDC900066633 /* SwitchState.swift */; };
4C1A85142254FDC900066633 /* UIControl+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A85072254FDC900066633 /* UIControl+Extensions.swift */; };
4C1A85152254FDC900066633 /* ControlText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A85082254FDC900066633 /* ControlText.swift */; };
4C1A85162254FDC900066633 /* ButtonState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A850A2254FDC900066633 /* ButtonState.swift */; };
4C63250B1F8AA89B00B2B74B /* TableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CCCE8441F8AA7CD00C73258 /* TableCell.swift */; };
4C63250C1F8AA89D00B2B74B /* TableItemConfigType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CCCE8451F8AA7CD00C73258 /* TableItemConfigType.swift */; };
4C63250D1F8AA8A000B2B74B /* UITableView+Reusable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CCCE8461F8AA7CD00C73258 /* UITableView+Reusable.swift */; };
Expand Down Expand Up @@ -97,9 +108,20 @@
17E57FF1208A404800BFCC3D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
17E57FF4208A404800BFCC3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
17E57FF6208A404800BFCC3D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
17E57FFF208A425F00BFCC3D /* LabelCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelCell.swift; sourceTree = "<group>"; };
3624340320D2F40100A75787 /* Array+TableSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+TableSection.swift"; sourceTree = "<group>"; };
36C9208C20D3EB7500DA4251 /* TableSectionsValidationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableSectionsValidationTests.swift; sourceTree = "<group>"; };
4C1A84FA2254FDC900066633 /* SpacerState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpacerState.swift; sourceTree = "<group>"; };
4C1A84FB2254FDC900066633 /* SpacerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpacerView.swift; sourceTree = "<group>"; };
4C1A84FD2254FDC900066633 /* LabelState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelState.swift; sourceTree = "<group>"; };
4C1A84FE2254FDC900066633 /* ImageState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImageState.swift; path = ../ImageState.swift; sourceTree = "<group>"; };
4C1A85002254FDC900066633 /* CombinedState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CombinedState.swift; sourceTree = "<group>"; };
4C1A85012254FDC900066633 /* CombinedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CombinedView.swift; sourceTree = "<group>"; };
4C1A85032254FDC900066633 /* SubtitleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubtitleView.swift; sourceTree = "<group>"; };
4C1A85042254FDC900066633 /* SubtitleState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubtitleState.swift; sourceTree = "<group>"; };
4C1A85062254FDC900066633 /* SwitchState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchState.swift; sourceTree = "<group>"; };
4C1A85072254FDC900066633 /* UIControl+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIControl+Extensions.swift"; sourceTree = "<group>"; };
4C1A85082254FDC900066633 /* ControlText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlText.swift; sourceTree = "<group>"; };
4C1A850A2254FDC900066633 /* ButtonState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonState.swift; sourceTree = "<group>"; };
4C7A26FC1F2FA0F800360E9B /* FunctionalTableData.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FunctionalTableData.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4C7A26FF1F2FA0F800360E9B /* FunctionalTableData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FunctionalTableData.h; sourceTree = "<group>"; };
4C7A27001F2FA0F800360E9B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -181,6 +203,65 @@
path = FunctionalTableDataDemo;
sourceTree = "<group>";
};
4C1A84F92254FDC900066633 /* Spacer */ = {
isa = PBXGroup;
children = (
4C1A84FA2254FDC900066633 /* SpacerState.swift */,
4C1A84FB2254FDC900066633 /* SpacerView.swift */,
);
path = Spacer;
sourceTree = "<group>";
};
4C1A84FC2254FDC900066633 /* Label */ = {
isa = PBXGroup;
children = (
4C1A84FD2254FDC900066633 /* LabelState.swift */,
);
path = Label;
sourceTree = "<group>";
};
4C1A84FF2254FDC900066633 /* Combined */ = {
isa = PBXGroup;
children = (
4C1A85002254FDC900066633 /* CombinedState.swift */,
4C1A85012254FDC900066633 /* CombinedView.swift */,
);
path = Combined;
sourceTree = "<group>";
};
4C1A85022254FDC900066633 /* Subtitle */ = {
isa = PBXGroup;
children = (
4C1A85032254FDC900066633 /* SubtitleView.swift */,
4C1A85042254FDC900066633 /* SubtitleState.swift */,
);
path = Subtitle;
sourceTree = "<group>";
};
4C1A85052254FDC900066633 /* Switch */ = {
isa = PBXGroup;
children = (
4C1A85062254FDC900066633 /* SwitchState.swift */,
);
path = Switch;
sourceTree = "<group>";
};
4C1A85092254FDC900066633 /* Button */ = {
isa = PBXGroup;
children = (
4C1A850A2254FDC900066633 /* ButtonState.swift */,
);
path = Button;
sourceTree = "<group>";
};
4C1A85172255017A00066633 /* Image */ = {
isa = PBXGroup;
children = (
4C1A84FE2254FDC900066633 /* ImageState.swift */,
);
path = Image;
sourceTree = "<group>";
};
4C7A26F21F2FA0F800360E9B = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -300,7 +381,15 @@
4CCFDFF520B2230E00584343 /* Cells */ = {
isa = PBXGroup;
children = (
17E57FFF208A425F00BFCC3D /* LabelCell.swift */,
4C1A85092254FDC900066633 /* Button */,
4C1A84FF2254FDC900066633 /* Combined */,
4C1A85172255017A00066633 /* Image */,
4C1A84FC2254FDC900066633 /* Label */,
4C1A84F92254FDC900066633 /* Spacer */,
4C1A85022254FDC900066633 /* Subtitle */,
4C1A85052254FDC900066633 /* Switch */,
4C1A85082254FDC900066633 /* ControlText.swift */,
4C1A85072254FDC900066633 /* UIControl+Extensions.swift */,
);
path = Cells;
sourceTree = "<group>";
Expand Down Expand Up @@ -390,7 +479,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0930;
LastUpgradeCheck = 0930;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = Shopify;
TargetAttributes = {
17E57FE5208A404700BFCC3D = {
Expand All @@ -412,10 +501,9 @@
};
buildConfigurationList = 4C7A26F61F2FA0F800360E9B /* Build configuration list for PBXProject "FunctionalTableData" */;
compatibilityVersion = "Xcode 8.0";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
Expand Down Expand Up @@ -463,10 +551,21 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4C1A850F2254FDC900066633 /* CombinedState.swift in Sources */,
4C1A850D2254FDC900066633 /* LabelState.swift in Sources */,
4C1A85102254FDC900066633 /* CombinedView.swift in Sources */,
17E57FED208A404700BFCC3D /* CollectionExampleController.swift in Sources */,
4C1A85122254FDC900066633 /* SubtitleState.swift in Sources */,
17E57FE9208A404700BFCC3D /* AppDelegate.swift in Sources */,
17E58000208A425F00BFCC3D /* LabelCell.swift in Sources */,
4C1A85152254FDC900066633 /* ControlText.swift in Sources */,
17E57FEB208A404700BFCC3D /* TableExampleController.swift in Sources */,
4C1A85132254FDC900066633 /* SwitchState.swift in Sources */,
4C1A85112254FDC900066633 /* SubtitleView.swift in Sources */,
4C1A85142254FDC900066633 /* UIControl+Extensions.swift in Sources */,
4C1A85162254FDC900066633 /* ButtonState.swift in Sources */,
4C1A850C2254FDC900066633 /* SpacerView.swift in Sources */,
4C1A850E2254FDC900066633 /* ImageState.swift in Sources */,
4C1A850B2254FDC900066633 /* SpacerState.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
6 changes: 6 additions & 0 deletions FunctionalTableDataDemo/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@
//

import UIKit
import FunctionalTableData

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

Separator.appearance().backgroundColor = UITableView().separatorColor
UIButton.appearance().setTitleColor(.blue, for: .normal)
UIButton.appearance().setTitleColor(UIColor.blue.withAlphaComponent(0.5), for: .highlighted)

return true
}

Expand Down
45 changes: 45 additions & 0 deletions FunctionalTableDataDemo/Cells/Button/ButtonState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// ButtonState.swift
// Shopify
//
// Created by Raul Riera on 2017-05-02.
// Copyright © 2017 Shopify. All rights reserved.
//

import UIKit
import FunctionalTableData

typealias ButtonCell = HostCell<UIButton, ButtonState, LayoutMarginsTableItemLayout>

public struct ButtonState: Equatable {
public let title: String
public let isEnabled: Bool
public let alignment: UIControl.ContentHorizontalAlignment
public let action: (UIButton) -> Void

public init(title: String, isEnabled: Bool = true, alignment: UIControl.ContentHorizontalAlignment = .center, action: @escaping (UIButton) -> Void) {
self.title = title
self.isEnabled = isEnabled
self.alignment = alignment
self.action = action
}

public static func updateView(_ view: UIButton, state: ButtonState?) {
guard let state = state else {
view.setTitle(nil, for: .normal)
view.isEnabled = true
view.contentHorizontalAlignment = .center
view.setActions([])
return
}

view.setTitle(state.title, for: .normal)
view.isEnabled = state.isEnabled
view.contentHorizontalAlignment = state.alignment
view.setAction(for: .touchUpInside, action: state.action)
}

public static func ==(lhs: ButtonState, rhs: ButtonState) -> Bool {
return lhs.title == rhs.title && lhs.isEnabled == rhs.isEnabled && lhs.alignment == rhs.alignment
}
}
38 changes: 38 additions & 0 deletions FunctionalTableDataDemo/Cells/Combined/CombinedState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// CombinedState.swift
// Shopify
//
// Created by Geoffrey Foster on 2017-01-18.
// Copyright © 2017 Shopify. All rights reserved.
//

import UIKit
import FunctionalTableData

public typealias CombinedCell<View1: UIView, State1: Equatable, View2: UIView, State2: Equatable, Layout: TableItemLayout> = HostCell<CombinedView<View1, View2>, CombinedState<State1, State2>, Layout>

public struct CombinedState<S1: Equatable, S2: Equatable>: Equatable {
public let state1: S1
public let state2: S2
public init(state1: S1, state2: S2) {
self.state1 = state1
self.state2 = state2
}

public static func ==(lhs: CombinedState, rhs: CombinedState) -> Bool {
return lhs.state1 == rhs.state1 && lhs.state2 == rhs.state2
}
}

extension CombinedState: Encodable where S1: Encodable, S2: Encodable {
enum CodingKeys: CodingKey {
case state1
case state2
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(state1, forKey: .state1)
try container.encode(state2, forKey: .state2)
}
}
37 changes: 37 additions & 0 deletions FunctionalTableDataDemo/Cells/Combined/CombinedView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// CombinedView.swift
// Shopify
//
// Created by Geoffrey Foster on 2017-01-18.
// Copyright © 2017 Shopify. All rights reserved.
//

import UIKit
import FunctionalTableData

public class CombinedView<View1: UIView, View2: UIView>: UIView {
public let view1 = View1()
public let view2 = View2()
public let stackView: UIStackView

public override init(frame: CGRect) {
stackView = UIStackView(frame: frame)
super.init(frame: frame)
stackView.addArrangedSubview(view1)
stackView.addArrangedSubview(view2)

stackView.translatesAutoresizingMaskIntoConstraints = false
addSubview(stackView)

NSLayoutConstraint.activate([
stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
stackView.topAnchor.constraint(equalTo: topAnchor),
stackView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor)
])
}

public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Loading

0 comments on commit 353217e

Please sign in to comment.