diff --git a/LayoutFrameworkBenchmark.xcodeproj/project.pbxproj b/LayoutFrameworkBenchmark.xcodeproj/project.pbxproj index bcd6acf..369add4 100644 --- a/LayoutFrameworkBenchmark.xcodeproj/project.pbxproj +++ b/LayoutFrameworkBenchmark.xcodeproj/project.pbxproj @@ -24,6 +24,7 @@ 24661D001F4EFFF5002CB883 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24661CFF1F4EFFF5002CB883 /* AppDelegate.swift */; }; 24661D071F4EFFF5002CB883 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 24661D061F4EFFF5002CB883 /* Assets.xcassets */; }; 24661D0A1F4EFFF5002CB883 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24661D081F4EFFF5002CB883 /* LaunchScreen.storyboard */; }; + 639E5A2020DF62D700C6BCEA /* NKFrameLayoutKitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639E5A1F20DF62D700C6BCEA /* NKFrameLayoutKitView.swift */; }; BF3DC69820B560A400536177 /* FeedItemNotAutoLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3DC69720B560A400536177 /* FeedItemNotAutoLayoutView.swift */; }; /* End PBXBuildFile section */ @@ -48,6 +49,7 @@ 24661D091F4EFFF5002CB883 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 24661D0B1F4EFFF5002CB883 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4F34489CA12B845548D7F17E /* Pods_LayoutFrameworkBenchmark.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LayoutFrameworkBenchmark.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 639E5A1F20DF62D700C6BCEA /* NKFrameLayoutKitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NKFrameLayoutKitView.swift; sourceTree = ""; }; 73BD901DE3512A23A7603899 /* Pods-LayoutFrameworkBenchmark.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LayoutFrameworkBenchmark.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LayoutFrameworkBenchmark/Pods-LayoutFrameworkBenchmark.debug.xcconfig"; sourceTree = ""; }; BF3DC69720B560A400536177 /* FeedItemNotAutoLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedItemNotAutoLayoutView.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -74,6 +76,7 @@ BF3DC69620B5608000536177 /* NotAutoLayout */, 2401BC911F4F020600788998 /* PinLayout */, 2401BC9F1F4F043800788998 /* UIStackView */, + 639E5A1E20DF620D00C6BCEA /* NKFrameLayoutKit */, 2401BC751F4F018C00788998 /* BenchmarkViewController.swift */, 2401BC761F4F018C00788998 /* CollectionViewController.swift */, 2401BC771F4F018C00788998 /* DataBinder.swift */, @@ -171,6 +174,15 @@ path = LayoutFrameworkBenchmark; sourceTree = ""; }; + 639E5A1E20DF620D00C6BCEA /* NKFrameLayoutKit */ = { + isa = PBXGroup; + children = ( + 639E5A1F20DF62D700C6BCEA /* NKFrameLayoutKitView.swift */, + ); + name = NKFrameLayoutKit; + path = Benchmarks/NKFrameLayoutKit; + sourceTree = ""; + }; 768A1E2833724B1530888DF2 /* Pods */ = { isa = PBXGroup; children = ( @@ -229,7 +241,7 @@ TargetAttributes = { 24661CFB1F4EFFF5002CB883 = { CreatedOnToolsVersion = 8.3.2; - DevelopmentTeam = 4Q596JWQC5; + DevelopmentTeam = 385YL4KG69; LastSwiftMigration = 0920; ProvisioningStyle = Automatic; }; @@ -275,14 +287,16 @@ "${SRCROOT}/Pods/Target Support Files/Pods-LayoutFrameworkBenchmark/Pods-LayoutFrameworkBenchmark-frameworks.sh", "${BUILT_PRODUCTS_DIR}/FlexLayout/FlexLayout.framework", "${BUILT_PRODUCTS_DIR}/LayoutKit/LayoutKit.framework", + "${BUILT_PRODUCTS_DIR}/NKFrameLayoutKit/NKFrameLayoutKit.framework", "${BUILT_PRODUCTS_DIR}/NotAutoLayout/NotAutoLayout.framework", "${BUILT_PRODUCTS_DIR}/PinLayout/PinLayout.framework", - "${PODS_ROOT}/Reveal-SDK/RevealServer-14/iOS/RevealServer.framework", + "${PODS_ROOT}/Reveal-SDK/RevealServer-16/iOS/RevealServer.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FlexLayout.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LayoutKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NKFrameLayoutKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NotAutoLayout.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PinLayout.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RevealServer.framework", @@ -327,6 +341,7 @@ 2401BC9E1F4F042700788998 /* FeedItemManualView.swift in Sources */, 2401BC811F4F018C00788998 /* BenchmarkViewController.swift in Sources */, BF3DC69820B560A400536177 /* FeedItemNotAutoLayoutView.swift in Sources */, + 639E5A2020DF62D700C6BCEA /* NKFrameLayoutKitView.swift in Sources */, 2401BC9B1F4F03B300788998 /* ProfileCardLayout.swift in Sources */, 2401BC941F4F021F00788998 /* FeedItemFlexLayoutView.swift in Sources */, 2401BCA41F4F045F00788998 /* FeedItemAutoLayoutView.swift in Sources */, @@ -466,7 +481,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 4Q596JWQC5; + DEVELOPMENT_TEAM = 385YL4KG69; INFOPLIST_FILE = LayoutFrameworkBenchmark/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.lucdion.LayoutFrameworkBenchmark; @@ -483,7 +498,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 4Q596JWQC5; + DEVELOPMENT_TEAM = 385YL4KG69; INFOPLIST_FILE = LayoutFrameworkBenchmark/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.lucdion.LayoutFrameworkBenchmark; diff --git a/LayoutFrameworkBenchmark.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/LayoutFrameworkBenchmark.xcodeproj/project.xcworkspace/contents.xcworkspacedata old mode 100644 new mode 100755 diff --git a/LayoutFrameworkBenchmark.xcodeproj/project.xcworkspace/xcuserdata/dionlu.xcuserdatad/UserInterfaceState.xcuserstate b/LayoutFrameworkBenchmark.xcodeproj/project.xcworkspace/xcuserdata/dionlu.xcuserdatad/UserInterfaceState.xcuserstate old mode 100644 new mode 100755 diff --git a/LayoutFrameworkBenchmark.xcodeproj/xcshareddata/xcschemes/LayoutFrameworkBenchmark.xcscheme b/LayoutFrameworkBenchmark.xcodeproj/xcshareddata/xcschemes/LayoutFrameworkBenchmark.xcscheme old mode 100644 new mode 100755 diff --git a/LayoutFrameworkBenchmark.xcworkspace/contents.xcworkspacedata b/LayoutFrameworkBenchmark.xcworkspace/contents.xcworkspacedata old mode 100644 new mode 100755 diff --git a/LayoutFrameworkBenchmark/Benchmarks/BenchmarkViewController.swift b/LayoutFrameworkBenchmark/Benchmarks/BenchmarkViewController.swift index e0b9833..2885bba 100755 --- a/LayoutFrameworkBenchmark/Benchmarks/BenchmarkViewController.swift +++ b/LayoutFrameworkBenchmark/Benchmarks/BenchmarkViewController.swift @@ -38,6 +38,11 @@ class BenchmarkViewController: UITableViewController { let data = FeedItemData.generate(count: viewCount) return CollectionViewControllerFeedItemManualView(data: data) }), + + ViewControllerData(title: "NKFrameLayoutKit", factoryBlock: { viewCount in + let data = FeedItemData.generate(count: viewCount) + return CollectionViewControllerFeedItemNKFrameLayoutKitView(data: data) + }), ViewControllerData(title: "NotAutoLayout", factoryBlock: { viewCount in let data = FeedItemData.generate(count: viewCount) diff --git a/LayoutFrameworkBenchmark/Benchmarks/CollectionViewController.swift b/LayoutFrameworkBenchmark/Benchmarks/CollectionViewController.swift index 685bd04..b6eb61f 100755 --- a/LayoutFrameworkBenchmark/Benchmarks/CollectionViewController.swift +++ b/LayoutFrameworkBenchmark/Benchmarks/CollectionViewController.swift @@ -28,6 +28,7 @@ class CollectionViewControllerFeedItemManualView: CollectionViewController {} class CollectionViewControllerFeedItemPinLayoutView: CollectionViewController {} class CollectionViewControllerFeedItemFlexLayoutView: CollectionViewController {} +class CollectionViewControllerFeedItemNKFrameLayoutKitView: CollectionViewController {} /// A UICollectionView controller where each cell's content view is a DataBinder. class CollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout where ContentViewType: DataBinder { diff --git a/LayoutFrameworkBenchmark/Benchmarks/NKFrameLayoutKit/NKFrameLayoutKitView.swift b/LayoutFrameworkBenchmark/Benchmarks/NKFrameLayoutKit/NKFrameLayoutKitView.swift new file mode 100644 index 0000000..d2cca52 --- /dev/null +++ b/LayoutFrameworkBenchmark/Benchmarks/NKFrameLayoutKit/NKFrameLayoutKitView.swift @@ -0,0 +1,171 @@ +// +// NKFrameLayoutKitView.swift +// LayoutFrameworkBenchmark +// +// Created by Nam Kennic on 6/24/18. +// + +import UIKit +import NKFrameLayoutKit + +/// A LinkedIn feed item that is implemented with NKFrameLayoutKit code. +class NKFrameLayoutKitView: UIView, DataBinder { + + var mainFrameLayout: NKGridFrameLayout! + + let actionLabel: UILabel = { + let l = UILabel() + l.backgroundColor = UIColor.blue + return l + }() + + let optionsLabel: UILabel = { + let l = UILabel() + l.text = "..." + return l + }() + + let posterImageView: UIImageView = { + let i = UIImageView() + i.image = UIImage(named: "50x50.png") + i.backgroundColor = UIColor.orange + i.contentMode = .scaleToFill + return i + }() + + let posterNameLabel: UILabel = UILabel() + + let posterHeadlineLabel: UILabel = { + let l = UILabel() + l.numberOfLines = 3 + return l + }() + + let posterTimeLabel: UILabel = UILabel() + let posterCommentLabel: UILabel = UILabel() + + let contentImageView: UIImageView = { + let i = UIImageView() + i.image = UIImage(named: "350x200.png") + i.contentMode = .scaleToFill + return i + }() + + let contentTitleLabel: UILabel = UILabel() + let contentDomainLabel: UILabel = UILabel() + + let likeLabel: UILabel = { + let l = UILabel() + l.backgroundColor = UIColor(red: 0, green: 0.9, blue: 0, alpha: 1) + l.text = "Like" + return l + }() + + let commentLabel: UILabel = { + let l = UILabel() + l.text = "Comment" + l.backgroundColor = UIColor(red: 0, green: 1.0, blue: 0, alpha: 1) + l.textAlignment = .center + return l + }() + + let shareLabel: UILabel = { + let l = UILabel() + l.text = "Share" + l.backgroundColor = UIColor(red: 0, green: 0.8, blue: 0, alpha: 1) + l.textAlignment = .right + return l + }() + + let actorImageView: UIImageView = { + let i = UIImageView() + i.image = UIImage(named: "50x50.png") + return i + }() + + let actorCommentLabel: UILabel = UILabel() + + lazy var topBar: NKDoubleFrameLayout = { + let v = NKDoubleFrameLayout(direction: .horizontal, andViews: [self.actionLabel, self.optionsLabel])! + v.rightFrameLayout.contentHorizontalAlignment = .right + return v + }() + + lazy var posters: NKDoubleFrameLayout = { + let labels = NKGridFrameLayout(direction: .vertical, andViews: [self.posterNameLabel, self.posterHeadlineLabel, self.posterTimeLabel])! + let v = NKDoubleFrameLayout(direction: .horizontal, andViews: [self.posterImageView, labels])! + v.leftFrameLayout.contentVerticalAlignment = .center + v.spacing = 5 + v.edgeInsets = UIEdgeInsets(top: 5, left: 0, bottom: 0, right: 0) + return v + }() + + lazy var actions: NKGridFrameLayout = { + let v = NKGridFrameLayout(direction: .horizontal)! // andViews: [self.likeLabel, self.commentLabel, self.shareLabel] + v.add(withTargetView: self.likeLabel).contentHorizontalAlignment = .left + v.add(withTargetView: self.commentLabel).contentHorizontalAlignment = .center + v.add(withTargetView: self.shareLabel).contentHorizontalAlignment = .right + v.layoutAlignment = .split + return v + }() + + lazy var comment: NKDoubleFrameLayout = { + let v = NKDoubleFrameLayout(direction: .horizontal, andViews: [self.actorImageView, self.actorCommentLabel])! + v.edgeInsets = UIEdgeInsets(top: 5, left: 0, bottom: 0, right: 0) + v.spacing = 5 + return v + }() + + override init(frame: CGRect) { + super.init(frame: frame) + addSubview(actionLabel) + addSubview(optionsLabel) + addSubview(posterImageView) + addSubview(posterNameLabel) + addSubview(posterHeadlineLabel) + addSubview(posterTimeLabel) + addSubview(posterCommentLabel) + addSubview(contentImageView) + addSubview(contentTitleLabel) + addSubview(contentDomainLabel) + addSubview(likeLabel) + addSubview(commentLabel) + addSubview(shareLabel) + addSubview(actorImageView) + addSubview(actorCommentLabel) + backgroundColor = UIColor.white + + mainFrameLayout = NKGridFrameLayout(direction: .vertical, andViews: [topBar, posters, posterCommentLabel, contentImageView, contentTitleLabel, contentDomainLabel, actions, comment]) + mainFrameLayout.edgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5) + addSubview(mainFrameLayout) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func setData(_ data: FeedItemData) { + actionLabel.text = data.actionText + posterNameLabel.text = data.posterName + posterHeadlineLabel.text = data.posterHeadline + posterTimeLabel.text = data.posterTimestamp + posterCommentLabel.text = data.posterComment + contentTitleLabel.text = data.contentTitle + contentDomainLabel.text = data.contentDomain + actorCommentLabel.text = data.actorComment + setNeedsLayout() + } + + override func layoutSubviews() { + super.layoutSubviews() + mainFrameLayout.frame = self.bounds + } + + override func sizeThatFits(_ size: CGSize) -> CGSize { + return mainFrameLayout.sizeThatFits(size) + } + + override var intrinsicContentSize: CGSize { + return mainFrameLayout.sizeThatFits(CGSize(width: frame.width, height: CGFloat.greatestFiniteMagnitude)) + } +} diff --git a/Podfile b/Podfile index 8c851cc..a13273c 100755 --- a/Podfile +++ b/Podfile @@ -14,4 +14,5 @@ target 'LayoutFrameworkBenchmark' do pod 'PinLayout' pod 'Reveal-SDK' pod 'NotAutoLayout' + pod 'NKFrameLayoutKit' end diff --git a/Podfile.lock b/Podfile.lock index 982096e..94770e2 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,6 +1,7 @@ PODS: - - FlexLayout (1.3.6) - - LayoutKit (7.0.2) + - FlexLayout (1.3.9) + - LayoutKit (8.0.1) + - NKFrameLayoutKit (2.1) - NotAutoLayout (3.1.1) - PinLayout (1.7.9) - Reveal-SDK (14) @@ -8,6 +9,7 @@ PODS: DEPENDENCIES: - FlexLayout - LayoutKit + - NKFrameLayoutKit - NotAutoLayout - PinLayout - Reveal-SDK @@ -16,17 +18,19 @@ SPEC REPOS: https://github.com/cocoapods/specs.git: - FlexLayout - LayoutKit + - NKFrameLayoutKit - NotAutoLayout - PinLayout - Reveal-SDK SPEC CHECKSUMS: - FlexLayout: bcdde388eaf826cfb6f801c8a507e2dca70412fa - LayoutKit: 183c513f8322f4e22321499e54163864bcdf7d97 + FlexLayout: dbe4b2da72ee63d7145cf32bb5bfba375aeeb9e6 + LayoutKit: dab1c2eea7a0bf9d8d755a8a793f87a929768455 + NKFrameLayoutKit: 6a2f6ac34f85d495e683ea0f7f1605903a4d3e00 NotAutoLayout: 2e6e82146dcb556cb61fcfd638b202639c167e84 PinLayout: 21ce87a865407a7a3c8a38a326611c476095fedf Reveal-SDK: 55b5c5545233b680c2f8da734f202acc15d422b7 -PODFILE CHECKSUM: 8558b640c2bd1d253536da517991c188d0d44fed +PODFILE CHECKSUM: 9565083f4813952a5a640666616b259832defa8b COCOAPODS: 1.5.3 diff --git a/README.md b/README.md index a16463f..36022d0 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,10 @@ LayoutKit is a fast view layout library for iOS, macOS, and tvOS. Layout is done by setting UIView's frame property directly. This implementation comes directly from the LayoutKit benchmark. [Manual layout benchmark's source code](https://github.com/layoutBox/LayoutFrameworkBenchmark/blob/master/LayoutFrameworkBenchmark/Benchmarks/ManualLayout/FeedItemManualView.swift) +* [**NKFrameLayoutKit**](https://github.com/kennic/NKFrameLayoutKit) +NKFrameLayoutKit is a fast and easy to use layout library +[NKFrameLayoutKit benchmark's source code](https://github.com/layoutBox/LayoutFrameworkBenchmark/blob/master/LayoutFrameworkBenchmark/Benchmarks/NKFrameLayoutKit/NKFrameLayoutKitView.swift) + * [**NotAutoLayout**](https://github.com/el-hoshino/NotAutoLayout) Layout your views without Auto Layout constraints, in a much more swifty way. [NotAutoLayout benchmark's source code](https://github.com/layoutBox/LayoutFrameworkBenchmark/blob/master/LayoutFrameworkBenchmark/Benchmarks/NotAutoLayout/FeedItemNotAutoLayoutView.swift) @@ -80,6 +84,7 @@ Here are the benchmark rendering results to compare visual results: * [FlexLayout rendering result](docs_markdown/benchmark_result_FlexLayout.png) * [PinLayout rendering result](docs_markdown/benchmark_result_PinLayout.png) * [LayoutKit rendering result](docs_markdown/benchmark_result_LayoutKit.png) +* [NKFrameLayoutKit rendering result](docs_markdown/benchmark_result_NKFrameLayoutKit.png) :pushpin: Some work would be required to adjust the layout so that they all match perfectly. diff --git a/docs_markdown/benchmark_comparison.png b/docs_markdown/benchmark_comparison.png index ab99bb9..3b8db20 100644 Binary files a/docs_markdown/benchmark_comparison.png and b/docs_markdown/benchmark_comparison.png differ diff --git a/docs_markdown/benchmark_comparison_all.png b/docs_markdown/benchmark_comparison_all.png index 7b6068e..d67b641 100644 Binary files a/docs_markdown/benchmark_comparison_all.png and b/docs_markdown/benchmark_comparison_all.png differ diff --git a/docs_markdown/benchmark_comparison_all_small.png b/docs_markdown/benchmark_comparison_all_small.png index fbd2baf..f492726 100644 Binary files a/docs_markdown/benchmark_comparison_all_small.png and b/docs_markdown/benchmark_comparison_all_small.png differ diff --git a/docs_markdown/benchmark_result_NKFrameLayoutKit.png b/docs_markdown/benchmark_result_NKFrameLayoutKit.png new file mode 100644 index 0000000..12ac171 Binary files /dev/null and b/docs_markdown/benchmark_result_NKFrameLayoutKit.png differ