Skip to content

Commit

Permalink
Add Content model and list display (#63)
Browse files Browse the repository at this point in the history
* Abstract centered label, remove unnecessary button boilerplate, and add spacing view

* No longer excluding colors.txt from project in Xcode

* Add alternate body text color

* Adding content / food enum for testing

* Display contents in detail view

* Further abstract contents list creation and add unit test

* Refactor contents list to be more reactive

* Changes per PR review

* Remove centeredLabel extension in favor of UILabelStyle additions

* Use container stackView instead of spacingView
  • Loading branch information
lokae0 committed Jan 28, 2019
1 parent 2c4fc39 commit d423271
Show file tree
Hide file tree
Showing 20 changed files with 191 additions and 84 deletions.
64 changes: 29 additions & 35 deletions Application/Source/Detail/View/DetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,40 @@ import SnapKit

class DetailView: UIView {

let title: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.numberOfLines = 0
return label
}()
let title = UILabel()
let button = UIButton()
let selectionResult = UILabel()

let button: UIButton = {
let button = UIButton()
button.setTitleColor(.blue, for: .normal)
return button
}()
let foodListTitle = UILabel()
let foodList = UILabel()
let foodInfoButton = UIButton()

let selectionResult: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.numberOfLines = 0
return label
}()

let contentsListTitle: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.numberOfLines = 0
return label
private(set) lazy var selectionStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [
title,
button,
selectionResult
])
stackView.axis = .vertical
stackView.alignment = .center
return stackView
}()

let contentsButton: UIButton = {
let button = UIButton()
button.setTitleColor(.blue, for: .normal)
return button
private(set) lazy var foodStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [
foodListTitle,
foodList,
foodInfoButton
])
stackView.axis = .vertical
stackView.alignment = .center
return stackView
}()

private(set) lazy var stackView: UIStackView = {
private(set) lazy var containerStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [
title,
button,
selectionResult,
contentsListTitle,
contentsButton
selectionStackView,
foodStackView
])
stackView.axis = .vertical
stackView.alignment = .center
Expand All @@ -54,8 +48,8 @@ class DetailView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)

addSubview(stackView)
stackView.snp.makeConstraints { make in
addSubview(containerStackView)
containerStackView.snp.makeConstraints { make in
make.center.equalTo(self)
}
}
Expand Down
14 changes: 9 additions & 5 deletions Application/Source/Detail/View/DetailViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,19 @@ class DetailViewController: UIViewController, ViewController {
viewModel.selectionResult
.bind(to: detailView.selectionResult.rx.text)
.disposed(by: disposeBag)
viewModel.contentsListTitle
.bind(to: detailView.contentsListTitle.rx.text)

viewModel.foodListTitle
.bind(to: detailView.foodListTitle.rx.text)
.disposed(by: disposeBag)
viewModel.foodListText
.bind(to: detailView.foodList.rx.text)
.disposed(by: disposeBag)
viewModel.contentsButtonTitle
.bind(to: detailView.contentsButton.rx.title())
viewModel.foodInfoButtonTitle
.bind(to: detailView.foodInfoButton.rx.title())
.disposed(by: disposeBag)

detailView.button.rx.bind(to: viewModel.presentSelection, input: true)
detailView.contentsButton.rx.bind(to: viewModel.presentContents, input: ())
detailView.foodInfoButton.rx.bind(to: viewModel.presentContents, input: ())

rx.isAppeared
.bind(to: viewModel.isActive)
Expand Down
27 changes: 17 additions & 10 deletions Application/Source/Detail/View/DetailViewControllerStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,38 @@ import UIKit
import Core

struct DetailViewControllerStyle: Style {

let theme: Theme
let background: BackgroundViewStyle
let title: LabelStyle
let selectionResult: LabelStyle
let label: LabelStyle
let alternateLabel: AlternateLabelStyle
let button: ButtonStyle

init(theme: Theme) {
self.theme = theme
background = BackgroundViewStyle(theme: theme)
title = LabelStyle(theme: theme)
selectionResult = LabelStyle(theme: theme)
label = LabelStyle(theme: theme)
alternateLabel = AlternateLabelStyle(theme: theme)
button = ButtonStyle(theme: theme)
}

func apply(to styleable: DetailViewController) {
let view = styleable.detailView

background.apply(to: view)
title.apply(to: view.title)
title.apply(to: view.contentsListTitle)
selectionResult.apply(to: view.selectionResult)

label.apply(to: view.title)
label.apply(to: view.foodListTitle)

alternateLabel.apply(to: view.selectionResult)
alternateLabel.apply(to: view.foodList)

button.apply(to: view.button)
button.apply(to: view.contentsButton)
button.apply(to: view.foodInfoButton)

view.selectionStackView.spacing = theme.layout.interitemSpacing
view.foodStackView.spacing = theme.layout.interitemSpacing

view.stackView.spacing = theme.layout.interitemSpacing
view.containerStackView.spacing = theme.layout.containerSpacing
}

}
15 changes: 13 additions & 2 deletions Application/Source/Detail/View/DetailViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,25 @@ class DetailViewModel: ViewModel, SelectionPresentingViewModel {

let presentSelectionTitle = Property(L10n.Detail.Select.title)

let contentsListTitle = Property(L10n.Detail.ContentsList.title)
let contentsButtonTitle = Property(L10n.Detail.ContentsButton.title)
let foodListTitle = Property(L10n.Detail.FoodList.title)
let foodInfoButtonTitle = Property(L10n.Detail.FoodButton.title)

let presentContents = CocoaAction { _ in
print("Content button pressed")
return .empty()
}

let foods: BehaviorRelay<[Food]> = BehaviorRelay(value: [.beans, .greens, .potatoes, .tomatoes])

private(set) lazy var foodListText: Property<String> = {
let observable = foods.map { foods -> String in
return foods
.map { $0.name }
.joined(separator: ", ")
}
return Property(observable, initial: "")
}()

private(set) lazy var presentSelection = makePresentSelection(
withFactory: selectionFactory,
defaultValue: { [weak self] in
Expand Down
13 changes: 2 additions & 11 deletions Application/Source/Home/View/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ import SnapKit

class HomeView: UIView {

let label: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.numberOfLines = 0
return label
}()
let label = UILabel()

let imageView: UIImageView = {
let imageView = UIImageView()
Expand All @@ -17,11 +12,7 @@ class HomeView: UIView {
return imageView
}()

let detailButton: UIButton = {
let button = UIButton()
button.setTitleColor(.blue, for: .normal)
return button
}()
let detailButton = UIButton()

private(set) lazy var stackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [
Expand Down
22 changes: 22 additions & 0 deletions Application/Source/Models/Food.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Foundation
import RxCocoa

/**
It's not a side project if you can't have some fun, right?
- [Original.](https://www.youtube.com/watch?v=amONEHAhLHY)
- [Crispy.](https://www.youtube.com/watch?v=1BC1G33-fNY)
*/
enum Food {

case beans, greens, potatoes, tomatoes

var name: String {
switch self {
case .beans: return L10n.Food.beans
case .greens: return L10n.Food.greens
case .potatoes: return L10n.Food.potatoes
case .tomatoes: return L10n.Food.tomatoes
}
}

}
7 changes: 1 addition & 6 deletions Application/Source/Selection/SelectionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ import SnapKit
class SelectionView: UIView {

let textField = UITextField()

let submitButton: UIButton = {
let button = UIButton()
button.setTitleColor(.blue, for: .normal)
return button
}()
let submitButton = UIButton()

private(set) lazy var stackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import UIKit
import Core

struct SelectionViewControllerStyle: Style {

let theme: Theme
let background: BackgroundViewStyle
let textField: TextFieldStyle
Expand Down
23 changes: 17 additions & 6 deletions Application/Source/SwiftGen/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ internal enum L10n {
internal enum Detail {
/// Details
internal static let title = L10n.tr("Localizable", "detail.title")
internal enum ContentsButton {
/// Contents Info
internal static let title = L10n.tr("Localizable", "detail.contents_button.title")
internal enum FoodButton {
/// Food Info
internal static let title = L10n.tr("Localizable", "detail.food_button.title")
}
internal enum ContentsList {
/// Contents
internal static let title = L10n.tr("Localizable", "detail.contents_list.title")
internal enum FoodList {
/// Ingredients
internal static let title = L10n.tr("Localizable", "detail.food_list.title")
}
internal enum Select {
/// Select Text
Expand All @@ -36,6 +36,17 @@ internal enum L10n {
}
}

internal enum Food {
/// Beans
internal static let beans = L10n.tr("Localizable", "food.beans")
/// Greens
internal static let greens = L10n.tr("Localizable", "food.greens")
/// Potatoes
internal static let potatoes = L10n.tr("Localizable", "food.potatoes")
/// Tomatoes
internal static let tomatoes = L10n.tr("Localizable", "food.tomatoes")
}

internal enum Home {
/// It works!
internal static let testText = L10n.tr("Localizable", "home.test_text")
Expand Down
20 changes: 16 additions & 4 deletions Application/Supporting Files/Base.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
/* The title of the tab bar item for the detail navigation flow. */
"detail_navigation.tab_bar_item.title" = "Detail";

/* Title for the contents list on the details view. */
"detail.contents_list.title" = "Contents";
/* Title for the food list on the details view. */
"detail.food_list.title" = "Ingredients";

/* Title for the contents button that presents the contents view. */
"detail.contents_button.title" = "Contents Info";
/* Title for the food button that presents the contents view. */
"detail.food_button.title" = "Food Info";

/* The title of the button that presents the detail view. */
"home.present_detail.title" = "Details";
Expand All @@ -30,3 +30,15 @@

/* The title of the tab bar item for the settings navigation flow. */
"settings_navigation.tab_bar_item.title" = "Settings";

/* Name of Food: beans. */
"food.beans" = "Beans";

/* Name of Food: greens. */
"food.greens" = "Greens";

/* Name of Food: potatoes. */
"food.potatoes" = "Potatoes";

/* Name of Food: tomatoes. */
"food.tomatoes" = "Tomatoes";
10 changes: 9 additions & 1 deletion Application/Tests/DetailViewModelSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,16 @@ class DetailViewModelSpec: QuickSpec {
expect(viewModel.title.value).to(equal(L10n.Detail.title))
}
}
}

describe("foodListText") {
it("should return a String list from the array of Contents") {
viewModel.foods.accept([.tomatoes, .potatoes])
let expected = L10n.Food.tomatoes + ", " + L10n.Food.potatoes

expect(viewModel.foodListText.value).to(equal(expected))
}
}
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions Core/Resources/Colors.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
LightContent : #000000
LightContentAlt : #7b7b7b
LightBackground : #FFFFFF
LightActionColor : #11A4D6
DarkContent : #D3D3D3
DarkContentAlt : #7b7b7b
DarkBackground : #000000
DarkActionColor : #15B7ED
6 changes: 6 additions & 0 deletions Core/Source/SwiftGen/Colors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public struct Color {
/// <span style="display:block;width:3em;height:2em;border:1px solid black;background:#d3d3d3"></span>
/// Alpha: 100% <br/> (0xd3d3d3ff)
public static let darkContent = Color(rgbaValue: 0xd3d3d3ff)
/// <span style="display:block;width:3em;height:2em;border:1px solid black;background:#7b7b7b"></span>
/// Alpha: 100% <br/> (0x7b7b7bff)
public static let darkContentAlt = Color(rgbaValue: 0x7b7b7bff)
/// <span style="display:block;width:3em;height:2em;border:1px solid black;background:#11a4d6"></span>
/// Alpha: 100% <br/> (0x11a4d6ff)
public static let lightActionColor = Color(rgbaValue: 0x11a4d6ff)
Expand All @@ -37,6 +40,9 @@ public struct Color {
/// <span style="display:block;width:3em;height:2em;border:1px solid black;background:#000000"></span>
/// Alpha: 100% <br/> (0x000000ff)
public static let lightContent = Color(rgbaValue: 0x000000ff)
/// <span style="display:block;width:3em;height:2em;border:1px solid black;background:#7b7b7b"></span>
/// Alpha: 100% <br/> (0x7b7b7bff)
public static let lightContentAlt = Color(rgbaValue: 0x7b7b7bff)
}
// swiftlint:enable identifier_name line_length type_body_length

Expand Down
14 changes: 14 additions & 0 deletions Core/Source/Themes/Styles/LabelStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,23 @@ import UIKit
public struct LabelStyle: UILabelStyle {

public let textColor: UIColor
public let numberOfLines: Int = 0
public let textAlignment: NSTextAlignment = .center

public init(theme: Theme) {
textColor = theme.color.bodyText
}

}

public struct AlternateLabelStyle: UILabelStyle {

public let textColor: UIColor
public let numberOfLines: Int = 0
public let textAlignment: NSTextAlignment = .center

public init(theme: Theme) {
textColor = theme.color.alternateBodyText
}

}
Loading

0 comments on commit d423271

Please sign in to comment.