Give YogaKitSample some love, Convert it to a Swift Project

Summary:
To date, our sample project was lacking. There is still a lot of work that can be done to improve, but, this is a step in the right direction.

Here are the changes in this commit:
1. The project is written in Swift.
2. Created new CollectionView (via [IGListKit](https://github.com/instagram/iglistkit)), making it very easy to add new examples.
3. New examples for basic layouts, and including/excluding layouts on the fly.

Here's a video!

![](https://media.giphy.com/media/l0ExcvTLa0ADdawRa/giphy.gif)
Closes https://github.com/facebook/yoga/pull/392

Reviewed By: emilsjolander

Differential Revision: D4550379

Pulled By: dshahidehpour

fbshipit-source-id: 64a07acf96c1887f1d2ad0c54971fcedb64334a0
This commit is contained in:
Dustin Shahidehpour
2017-02-13 09:05:22 -08:00
committed by Facebook Github Bot
parent ad8c6225fd
commit 058761e16e
13 changed files with 390 additions and 130 deletions

View File

@@ -2,4 +2,5 @@ use_frameworks!
target 'YogaKitSample' do
pod 'YogaKit', :path => '../../YogaKit.podspec'
pod 'IGListKit', '~> 2.1.0'
end

View File

@@ -1,19 +1,26 @@
PODS:
- IGListKit (2.1.0):
- IGListKit/Default (= 2.1.0)
- IGListKit/Default (2.1.0):
- IGListKit/Diffing
- IGListKit/Diffing (2.1.0)
- Yoga (1.1.0)
- YogaKit (1.1.0):
- Yoga (~> 1.1)
DEPENDENCIES:
- IGListKit (~> 2.1.0)
- YogaKit (from `../../YogaKit.podspec`)
EXTERNAL SOURCES:
YogaKit:
:path: "../../YogaKit.podspec"
:path: ../../YogaKit.podspec
SPEC CHECKSUMS:
IGListKit: b826c68ef7a4ae1626c09d4d3e1ea7a169e6c36e
Yoga: 0bf083b7c485b20598020dbedcea869cbe53071e
YogaKit: 80df90de9ef2900baa111f2c93476a6f9e921385
PODFILE CHECKSUM: 9db3bdea7f1b4b715ad859a449b2dc87fb6226cc
PODFILE CHECKSUM: 216f8e7127767709e0e43f3711208d238fa5c404
COCOAPODS: 1.2.0

View File

@@ -7,14 +7,15 @@
objects = {
/* Begin PBXBuildFile section */
13687D481DF8748400E7C260 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13687D471DF8748400E7C260 /* main.m */; };
13687D4B1DF8748400E7C260 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13687D4A1DF8748400E7C260 /* AppDelegate.m */; };
13687D4E1DF8748400E7C260 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 13687D4D1DF8748400E7C260 /* ViewController.m */; };
13687D531DF8748400E7C260 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13687D521DF8748400E7C260 /* Assets.xcassets */; };
13687D851DF87D1E00E7C260 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13687D841DF87D1E00E7C260 /* UIKit.framework */; };
13687D871DF87D2400E7C260 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13687D861DF87D2400E7C260 /* Foundation.framework */; };
15A7CB5995C9DAB1C8803834 /* Pods_YogaKitSample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C80A931E90C7F3088CB86822 /* Pods_YogaKitSample.framework */; };
638A94481E1F06D100A726AD /* SwiftViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638A94471E1F06D100A726AD /* SwiftViewController.swift */; };
40BD9F461E477A09002790A9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40BD9F451E477A09002790A9 /* AppDelegate.swift */; };
40BD9F4B1E47850C002790A9 /* BasicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40BD9F4A1E47850C002790A9 /* BasicViewController.swift */; };
40BD9F501E479079002790A9 /* SingleLabelCollectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40BD9F4F1E479079002790A9 /* SingleLabelCollectionCell.swift */; };
40BD9F521E479173002790A9 /* LayoutInclusionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40BD9F511E479173002790A9 /* LayoutInclusionViewController.swift */; };
638A94481E1F06D100A726AD /* ExamplesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638A94471E1F06D100A726AD /* ExamplesViewController.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -52,17 +53,16 @@
/* Begin PBXFileReference section */
13687D431DF8748400E7C260 /* YogaKitSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YogaKitSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
13687D471DF8748400E7C260 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
13687D491DF8748400E7C260 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
13687D4A1DF8748400E7C260 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
13687D4C1DF8748400E7C260 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
13687D4D1DF8748400E7C260 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
13687D521DF8748400E7C260 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
13687D571DF8748400E7C260 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
13687D841DF87D1E00E7C260 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
13687D861DF87D2400E7C260 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1D2FF4D5FCA6A8C54A4074A3 /* Pods-YogaKitSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YogaKitSample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-YogaKitSample/Pods-YogaKitSample.debug.xcconfig"; sourceTree = "<group>"; };
638A94471E1F06D100A726AD /* SwiftViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftViewController.swift; sourceTree = "<group>"; };
40BD9F451E477A09002790A9 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
40BD9F4A1E47850C002790A9 /* BasicViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BasicViewController.swift; path = ViewControllers/BasicViewController.swift; sourceTree = "<group>"; };
40BD9F4F1E479079002790A9 /* SingleLabelCollectionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SingleLabelCollectionCell.swift; path = Views/SingleLabelCollectionCell.swift; sourceTree = "<group>"; };
40BD9F511E479173002790A9 /* LayoutInclusionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LayoutInclusionViewController.swift; path = ViewControllers/LayoutInclusionViewController.swift; sourceTree = "<group>"; };
638A94471E1F06D100A726AD /* ExamplesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExamplesViewController.swift; sourceTree = "<group>"; };
638A944F1E215CC800A726AD /* YogaKitSampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = YogaKitSampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
82F0896A88112E957EF37C7F /* Pods-YogaKitSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YogaKitSample.release.xcconfig"; path = "Pods/Target Support Files/Pods-YogaKitSample/Pods-YogaKitSample.release.xcconfig"; sourceTree = "<group>"; };
C80A931E90C7F3088CB86822 /* Pods_YogaKitSample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_YogaKitSample.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -111,26 +111,16 @@
13687D451DF8748400E7C260 /* YogaKitSample */ = {
isa = PBXGroup;
children = (
13687D491DF8748400E7C260 /* AppDelegate.h */,
13687D4A1DF8748400E7C260 /* AppDelegate.m */,
13687D4C1DF8748400E7C260 /* ViewController.h */,
13687D4D1DF8748400E7C260 /* ViewController.m */,
638A94471E1F06D100A726AD /* SwiftViewController.swift */,
40BD9F4E1E47902F002790A9 /* Views */,
40BD9F481E4784B3002790A9 /* ViewControllers */,
638A94471E1F06D100A726AD /* ExamplesViewController.swift */,
13687D521DF8748400E7C260 /* Assets.xcassets */,
13687D571DF8748400E7C260 /* Info.plist */,
13687D461DF8748400E7C260 /* Supporting Files */,
40BD9F451E477A09002790A9 /* AppDelegate.swift */,
);
path = YogaKitSample;
sourceTree = "<group>";
};
13687D461DF8748400E7C260 /* Supporting Files */ = {
isa = PBXGroup;
children = (
13687D471DF8748400E7C260 /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
13687D831DF87D1E00E7C260 /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -141,6 +131,23 @@
name = Frameworks;
sourceTree = "<group>";
};
40BD9F481E4784B3002790A9 /* ViewControllers */ = {
isa = PBXGroup;
children = (
40BD9F4A1E47850C002790A9 /* BasicViewController.swift */,
40BD9F511E479173002790A9 /* LayoutInclusionViewController.swift */,
);
name = ViewControllers;
sourceTree = "<group>";
};
40BD9F4E1E47902F002790A9 /* Views */ = {
isa = PBXGroup;
children = (
40BD9F4F1E479079002790A9 /* SingleLabelCollectionCell.swift */,
);
name = Views;
sourceTree = "<group>";
};
E1C759E3C8E84821213ECE8D /* Pods */ = {
isa = PBXGroup;
children = (
@@ -304,10 +311,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
638A94481E1F06D100A726AD /* SwiftViewController.swift in Sources */,
13687D4E1DF8748400E7C260 /* ViewController.m in Sources */,
13687D4B1DF8748400E7C260 /* AppDelegate.m in Sources */,
13687D481DF8748400E7C260 /* main.m in Sources */,
40BD9F501E479079002790A9 /* SingleLabelCollectionCell.swift in Sources */,
40BD9F521E479173002790A9 /* LayoutInclusionViewController.swift in Sources */,
638A94481E1F06D100A726AD /* ExamplesViewController.swift in Sources */,
40BD9F4B1E47850C002790A9 /* BasicViewController.swift in Sources */,
40BD9F461E477A09002790A9 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -1,15 +0,0 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@@ -1,27 +0,0 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [ViewController new];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
@end

View File

@@ -0,0 +1,27 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
import Foundation
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func applicationDidFinishLaunching(_ application: UIApplication) {
self.window = UIWindow(frame: UIScreen.main.bounds)
if let window = self.window {
let navigationController = UINavigationController(rootViewController: ExamplesViewController())
navigationController.navigationBar.isTranslucent = false
window.rootViewController = navigationController
window.backgroundColor = .white
window.makeKeyAndVisible()
}
}
}

View File

@@ -0,0 +1,100 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
import UIKit
import IGListKit
private final class ExampleModel {
let title: String
let controllerClass: UIViewController.Type
init(title: String, controllerClass: UIViewController.Type) {
self.title = title
self.controllerClass = controllerClass
}
}
extension ExampleModel: IGListDiffable {
fileprivate func diffIdentifier() -> NSObjectProtocol {
return title as NSString
}
fileprivate func isEqual(toDiffableObject object: IGListDiffable?) -> Bool {
guard let otherObj = object as? ExampleModel else { return false }
return (title == otherObj.title) &&
(controllerClass == otherObj.controllerClass)
}
}
final class ExamplesViewController: UIViewController, IGListAdapterDataSource, IGListSingleSectionControllerDelegate {
private lazy var adapter: IGListAdapter = {
return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0)
}()
private let collectionView = IGListCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
// Update this to array to create more examples.
private let models: [ExampleModel] = [ExampleModel(title: "Basic Layout", controllerClass: BasicViewController.self),
ExampleModel(title: "Exclude Views in Layout", controllerClass: LayoutInclusionViewController.self)]
//MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
title = "Examples"
view.addSubview(collectionView)
adapter.collectionView = collectionView
adapter.dataSource = self
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.frame = view.bounds
}
//MARK: IGListAdapterDataSource
func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] {
return models as [IGListDiffable]
}
func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController {
let sizeBlock: IGListSingleSectionCellSizeBlock = { (model, context) in
return CGSize(width: (context?.containerSize.width)!, height: 75.0)
}
let configureBlock: IGListSingleSectionCellConfigureBlock = { (model, cell) in
guard let m = model as? ExampleModel, let c = cell as? SingleLabelCollectionCell else {
return
}
c.label.text = m.title
}
let sectionController = IGListSingleSectionController(cellClass: SingleLabelCollectionCell.self,
configureBlock: configureBlock,
sizeBlock: sizeBlock)
sectionController.selectionDelegate = self
return sectionController
}
func emptyView(for listAdapter: IGListAdapter) -> UIView? { return nil }
//MARK: IGListSingleSectionControllerDelegate
func didSelect(_ sectionController: IGListSingleSectionController) {
let section = adapter.section(for: sectionController)
let model = models[section]
let controller = model.controllerClass.init()
controller.title = model.title
self.navigationController?.pushViewController(controller, animated: true)
}
}

View File

@@ -7,35 +7,60 @@
*/
import UIKit
import IGListKit
import YogaKit
class SwiftViewController: UIViewController {
override func viewDidLoad() {
let root = self.view!
root.backgroundColor = .red
root.yoga.isEnabled = true
root.yoga.width = self.view.bounds.size.width
root.yoga.height = self.view.bounds.size.height
root.yoga.alignItems = .center
root.yoga.justifyContent = .center
let child1 = UIView()
child1.backgroundColor = .blue
child1.yoga.isEnabled = true
child1.yoga.width = 100
child1.yoga.height = 10
let child2 = UIView()
child2.backgroundColor = .green
child2.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
let child3 = UIView()
child3.backgroundColor = .yellow
child3.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
child2.addSubview(child3)
root.addSubview(child1)
root.addSubview(child2)
root.yoga.applyLayout(preservingOrigin: false)
}
struct DemoItem {
let name: String
}
final class SwiftViewController: UIViewController, IGListAdapterDataSource {
lazy var adapter: IGListAdapter = {
return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0)
}()
let collectionView = IGListCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
//MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
title = "YogaKit Examples"
view.addSubview(collectionView)
adapter.collectionView = collectionView
adapter.dataSource = self
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.frame = view.bounds
}
//MARK: IGListAdapterDataSource
func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] {
return ["Dustin" as IGListDiffable, "Ryan" as IGListDiffable]
}
func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController {
let sizeBlock: IGListSingleSectionCellSizeBlock = { (model, context) in
return CGSize(width: (context?.containerSize.width)!, height: 100.0)
}
let configureBlock: IGListSingleSectionCellConfigureBlock = { (model, cell) in
guard let m = model as? String else {
return
}
cell.backgroundColor = (m == "Dustin") ? .blue : .red
}
return IGListSingleSectionController(cellClass: UICollectionViewCell.self,
configureBlock: configureBlock,
sizeBlock: sizeBlock)
}
func emptyView(for listAdapter: IGListAdapter) -> UIView? {
return nil
}
}

View File

@@ -1,13 +0,0 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

View File

@@ -0,0 +1,48 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
import UIKit
import YogaKit
final class BasicViewController: UIViewController {
override func viewDidLoad() {
let containerSize = self.view.bounds.size
let root = self.view!
root.backgroundColor = .white
root.yoga.isEnabled = true
root.yoga.width = containerSize.width
root.yoga.height = containerSize.height
root.yoga.alignItems = .center
root.yoga.justifyContent = .center
let child1 = UIView()
child1.backgroundColor = .blue
child1.yoga.isEnabled = true
child1.yoga.width = 100
child1.yoga.height = 10
child1.yoga.marginBottom = 25
root.addSubview(child1)
let child2 = UIView()
child2.yoga.isEnabled = true
child2.yoga.alignSelf = .flexEnd
child2.backgroundColor = .green
child2.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
root.addSubview(child2)
let child3 = UIView()
child3.yoga.isEnabled = true
child3.yoga.alignSelf = .flexStart
child3.backgroundColor = .yellow
child3.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
root.addSubview(child3)
root.yoga.applyLayout(preservingOrigin: true)
}
}

View File

@@ -0,0 +1,70 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
import UIKit
import YogaKit
final class LayoutInclusionViewController: UIViewController {
private let button: UIButton = UIButton(type: .system)
private let disappearingView: UIView = UIView(frame: .zero)
private let contentView: UIView = UIView(frame: .zero)
override func viewDidLoad() {
let root = self.view!
root.backgroundColor = .white
root.yoga.isEnabled = true
root.yoga.flexDirection = .column
root.yoga.justifyContent = .spaceAround
contentView.backgroundColor = .clear
contentView.layer.borderColor = UIColor.lightGray.cgColor
contentView.layer.borderWidth = 1.0
contentView.yoga.isEnabled = true
contentView.yoga.height = 300
contentView.yoga.width = self.view.bounds.size.width
contentView.yoga.flexDirection = .row
contentView.yoga.justifyContent = .center
contentView.yoga.paddingHorizontal = 25
self.view.addSubview(contentView)
let redView = UIView(frame: .zero)
redView.backgroundColor = .red
redView.yoga.isEnabled = true
redView.yoga.flexGrow = 1
redView.yoga.flexShrink = 1
contentView.addSubview(redView)
disappearingView.backgroundColor = .blue
disappearingView.yoga.isEnabled = true
disappearingView.yoga.flexGrow = 1
contentView.addSubview(disappearingView)
button.setTitle("Add Blue View", for: UIControlState.selected)
button.setTitle("Remove Blue View", for: UIControlState.normal)
button.addTarget(self, action: #selector(buttonWasTapped), for: UIControlEvents.touchUpInside)
button.yoga.isEnabled = true
button.yoga.height = 300
button.yoga.width = 300
button.yoga.alignSelf = .center
root.addSubview(button)
root.yoga.applyLayout(preservingOrigin: false)
}
// MARK - UIButton Action
func buttonWasTapped() {
button.isSelected = !button.isSelected
button.isUserInteractionEnabled = false
disappearingView.yoga.isIncludedInLayout = !disappearingView.yoga.isIncludedInLayout
disappearingView.isHidden = !disappearingView.isHidden
contentView.yoga.applyLayout(preservingOrigin: true)
button.isUserInteractionEnabled = true
}
}

View File

@@ -0,0 +1,45 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
import UIKit
import YogaKit
final class SingleLabelCollectionCell: UICollectionViewCell {
let label: UILabel = UILabel(frame: .zero)
override init(frame: CGRect) {
super.init(frame: frame)
contentView.yoga.isEnabled = true
contentView.yoga.flexDirection = .column
contentView.yoga.justifyContent = .flexEnd
label.textAlignment = .center
label.numberOfLines = 1
label.yoga.isIncludedInLayout = false
contentView.addSubview(label)
let border = UIView(frame: .zero)
border.backgroundColor = .lightGray
border.yoga.isEnabled = true
border.yoga.height = 0.5
border.yoga.marginHorizontal = 25
contentView.addSubview(border)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
contentView.yoga.applyLayout(preservingOrigin: false)
label.frame = contentView.bounds
}
}

View File

@@ -1,16 +0,0 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}