Skip to content

Commit

Permalink
Added collection view for categories and corresponding products view
Browse files Browse the repository at this point in the history
  • Loading branch information
craigtweedy committed May 23, 2018
1 parent f29e751 commit 9b2e92b
Show file tree
Hide file tree
Showing 9 changed files with 396 additions and 96 deletions.
39 changes: 33 additions & 6 deletions Examples/moltin tvOS Example/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="13771" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="49e-Tb-3d3">
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="14109" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="49e-Tb-3d3">
<device id="appleTV" orientation="landscape">
<adaptation id="light"/>
</device>
<dependencies>
<deployment identifier="tvOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Products-->
<scene sceneID="Ajz-0m-JVc">
<objects>
<collectionViewController id="VWd-Xz-XsT" customClass="ProductsViewController" customModule="moltin_tvOS_Example" customModuleProvider="target" sceneMemberID="viewController">
<collectionViewController id="VWd-Xz-XsT" customClass="CategoriesViewController" customModule="moltin_tvOS_Example" customModuleProvider="target" sceneMemberID="viewController">
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" id="WPt-yc-IFW">
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="dtZ-cg-0Hf">
<size key="itemSize" width="300" height="300"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="ydW-Ak-RpU">
<size key="itemSize" width="50" height="50"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="10" minY="10" maxX="0.0" maxY="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
<cells/>
<connections>
Expand All @@ -32,11 +32,38 @@
<extendedEdge key="edgesForExtendedLayout" bottom="YES"/>
<tabBarItem key="tabBarItem" title="Products" id="YB6-d2-RQ6"/>
<simulatedTabBarMetrics key="simulatedTopBarMetrics"/>
<connections>
<segue destination="Ih9-hK-Lhu" kind="show" identifier="CategoryToProducts" id="aYg-4A-MHB"/>
</connections>
</collectionViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="bdt-Tu-xdp" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2246" y="-855"/>
</scene>
<!--Products Collection View Controller-->
<scene sceneID="VNA-7q-ZxG">
<objects>
<collectionViewController id="Ih9-hK-Lhu" customClass="ProductsCollectionViewController" customModule="moltin_tvOS_Example" customModuleProvider="target" sceneMemberID="viewController">
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" id="f3b-gn-WN8">
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="RyZ-ko-rM3">
<size key="itemSize" width="300" height="300"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
<cells/>
<connections>
<outlet property="dataSource" destination="Ih9-hK-Lhu" id="r0n-eH-QBs"/>
<outlet property="delegate" destination="Ih9-hK-Lhu" id="YER-9A-wOR"/>
</connections>
</collectionView>
</collectionViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="JWA-pU-2eX" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="4593" y="-855"/>
</scene>
<!--Carts-->
<scene sceneID="wg7-f3-ORb">
<objects>
Expand Down
147 changes: 147 additions & 0 deletions Examples/moltin tvOS Example/CategoriesViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
//
// ProductsViewController.swift
// moltin tvOS Example
//
// Created by Craig Tweedy on 21/03/2018.
//

import UIKit
import moltin

extension UIImageView {

func load(urlString string: String?) {
guard let imageUrl = string,
let url = URL(string: imageUrl) else { return }

URLSession.shared.dataTask(with: url) { data, _, _ in
if let data = data {
DispatchQueue.main.async {
self.image = UIImage(data: data)
}
}
}.resume()
}
}

extension UIColor {
convenience init(hexString: String, alpha: CGFloat = 1.0) {
let hexString: String = hexString.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
let scanner = Scanner(string: hexString)
if hexString.hasPrefix("#") {
scanner.scanLocation = 1
}
var color: UInt32 = 0
scanner.scanHexInt32(&color)
let mask = 0x000000FF
let r = Int(color >> 16) & mask
let g = Int(color >> 8) & mask
let b = Int(color) & mask
let red = CGFloat(r) / 255.0
let green = CGFloat(g) / 255.0
let blue = CGFloat(b) / 255.0
self.init(red: red, green: green, blue: blue, alpha: alpha)
}
func toHexString() -> String {
var r: CGFloat = 0
var g: CGFloat = 0
var b: CGFloat = 0
var a: CGFloat = 0
getRed(&r, green: &g, blue: &b, alpha: &a)
let rgb: Int = (Int)(r*255)<<16 | (Int)(g*255)<<8 | (Int)(b*255)<<0
return String(format: "#%06x", rgb)
}
}

class ProductCategory: moltin.Category {
var backgroundColor: UIColor?
var backgroundImage: String?

enum ProductCategoryCodingKeys: String, CodingKey {
case backgroundColor = "background_colour"
case backgroundImage = "background_image"
}

required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: ProductCategoryCodingKeys.self)
if let color: String = try container.decodeIfPresent(String.self, forKey: .backgroundColor) {
self.backgroundColor = UIColor(hexString: color)
}
self.backgroundImage = try container.decodeIfPresent(String.self, forKey: .backgroundImage)
try super.init(from: decoder)
}
}

class CategoriesViewController: UICollectionViewController {

var data: [ProductCategory] = []
let moltin: Moltin = Moltin(withClientID: "j6hSilXRQfxKohTndUuVrErLcSJWP15P347L6Im0M4", withLocale: Locale(identifier: "en_US"))

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

self.collectionView?.register(UINib(nibName: "ProductCategoryCollectionViewCell", bundle: Bundle.main), forCellWithReuseIdentifier: "Cell")

let flowLayout = UICollectionViewFlowLayout()
flowLayout.itemSize = CGSize(width: self.view.frame.width, height: self.view.frame.height * 0.8)
flowLayout.minimumLineSpacing = 0
flowLayout.minimumInteritemSpacing = 0
self.collectionView?.setCollectionViewLayout(flowLayout, animated: false)

self.moltin.category.all { (response: Result<PaginatedResponse<[ProductCategory]>>) in
switch response {
case .success(let categories):
DispatchQueue.main.async {
self.view.backgroundColor = categories.data?.first?.backgroundColor
self.data = categories.data ?? []
self.collectionView?.reloadData()
}
case .failure(let error):
print(error)
}
}
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "CategoryToProducts",
let viewController = segue.destination as? ProductsCollectionViewController,
let category = sender as? ProductCategory {
viewController.category = category
}
}

}

// MARK: - Data Source
extension CategoriesViewController {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.data.count
}
}

// MARK: - Delegate
extension CategoriesViewController {
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell: ProductCategoryCollectionViewCell =
collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? ProductCategoryCollectionViewCell else {
return UICollectionViewCell()
}
let product = self.data[indexPath.row]
cell.backgroundColor = product.backgroundColor
cell.image.load(urlString: product.backgroundImage)
cell.label.text = product.name

return cell
}

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let category = self.data[indexPath.row]
self.performSegue(withIdentifier: "CategoryToProducts", sender: category)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// ProductCollectionViewCell.swift
// moltin tvOS Example
//
// Created by Craig Tweedy on 21/03/2018.
//

import UIKit

class ProductCategoryCollectionViewCell: UICollectionViewCell {

@IBOutlet var label: UILabel!
@IBOutlet var image: UIImageView!
}
53 changes: 53 additions & 0 deletions Examples/moltin tvOS Example/ProductCategoryCollectionViewCell.xib
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder.AppleTV.XIB" version="3.0" toolsVersion="14109" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="appleTV" orientation="landscape">
<adaptation id="light"/>
</device>
<dependencies>
<deployment identifier="tvOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" multipleTouchEnabled="YES" contentMode="center" id="Rz2-K0-ksD" customClass="ProductCategoryCollectionViewCell" customModule="moltin_tvOS_Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="1184" height="793"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="1184" height="793"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ak9-D0-qvS">
<rect key="frame" x="545" y="160" width="94" height="47"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
<color key="shadowColor" red="0.5273903998957411" green="0.5339013924870466" blue="0.5339013924870466" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<size key="shadowOffset" width="1" height="1"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="jVl-cX-aCn">
<rect key="frame" x="213" y="136" width="432" height="524"/>
</imageView>
</subviews>
</view>
<constraints>
<constraint firstItem="ak9-D0-qvS" firstAttribute="leading" secondItem="jVl-cX-aCn" secondAttribute="trailing" constant="-100" id="8Vm-cT-KWT"/>
<constraint firstItem="7PP-Ag-gPX" firstAttribute="bottom" secondItem="jVl-cX-aCn" secondAttribute="bottom" constant="73" id="Nh9-4x-7rp"/>
<constraint firstItem="jVl-cX-aCn" firstAttribute="leading" secondItem="7PP-Ag-gPX" secondAttribute="leading" multiplier="2" constant="33" id="UfQ-fU-yui"/>
<constraint firstItem="ak9-D0-qvS" firstAttribute="centerX" secondItem="7PP-Ag-gPX" secondAttribute="centerX" id="a3O-tO-2iN"/>
<constraint firstItem="jVl-cX-aCn" firstAttribute="top" secondItem="7PP-Ag-gPX" secondAttribute="top" constant="76" id="kxw-Hi-2Ge"/>
<constraint firstItem="ak9-D0-qvS" firstAttribute="top" secondItem="7PP-Ag-gPX" secondAttribute="top" constant="100" id="woD-xf-OJc"/>
</constraints>
<viewLayoutGuide key="safeArea" id="7PP-Ag-gPX"/>
<size key="customSize" width="1184" height="793"/>
<connections>
<outlet property="image" destination="jVl-cX-aCn" id="C9I-5b-flZ"/>
<outlet property="label" destination="ak9-D0-qvS" id="0t8-dk-XSY"/>
</connections>
<point key="canvasLocation" x="8" y="82.5"/>
</collectionViewCell>
</objects>
</document>
4 changes: 2 additions & 2 deletions Examples/moltin tvOS Example/ProductCollectionViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
// ProductCollectionViewCell.swift
// moltin tvOS Example
//
// Created by Craig Tweedy on 21/03/2018.
// Created by Craig Tweedy on 23/05/2018.
//

import UIKit

class ProductCollectionViewCell: UICollectionViewCell {

@IBOutlet var label: UILabel!
@IBOutlet weak var productImage: UIImageView!

}
Loading

0 comments on commit 9b2e92b

Please sign in to comment.