ソースを参照

Initial commit

xcbosa mbp16 2 年 前
コミット
7ced50f3b0

+ 36 - 0
.gitignore

@@ -0,0 +1,36 @@
+# macOS
+.DS_Store
+
+# Xcode
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata/
+*.xccheckout
+*.moved-aside
+DerivedData
+*.hmap
+*.ipa
+
+# Bundler
+.bundle
+
+# Add this line if you want to avoid checking in source code from Carthage dependencies.
+# Carthage/Checkouts
+
+Carthage/Build
+
+# We recommend against adding the Pods directory to your .gitignore. However
+# you should judge for yourself, the pros and cons are mentioned at:
+# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
+# 
+# Note: if you ignore the Pods directory, make sure to uncomment
+# `pod install` in .travis.yml
+#
+# Pods/

+ 14 - 0
.travis.yml

@@ -0,0 +1,14 @@
+# references:
+# * https://www.objc.io/issues/6-build-tools/travis-ci/
+# * https://github.com/supermarin/xcpretty#usage
+
+osx_image: xcode7.3
+language: objective-c
+# cache: cocoapods
+# podfile: Example/Podfile
+# before_install:
+# - gem install cocoapods # Since Travis is not always on latest version
+# - pod install --project-directory=Example
+script:
+- set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/FastLayout.xcworkspace -scheme FastLayout-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty
+- pod lib lint

+ 377 - 0
Example/FastLayout.xcodeproj/project.pbxproj

@@ -0,0 +1,377 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; };
+		607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; };
+		607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; };
+		607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
+		607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
+		607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
+		607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
+		607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+		607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
+		607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
+		607FACE51AFB9204008FA782 /* FastLayout_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FastLayout_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = "<group>"; };
+		885738E17F531080B8B243EB /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; name = README.md; path = ../README.md; sourceTree = "<group>"; };
+		9B6BD1B578E85F60162E4CD7 /* FastLayout.podspec */ = {isa = PBXFileReference; includeInIndex = 1; name = FastLayout.podspec; path = ../FastLayout.podspec; sourceTree = "<group>"; };
+		FBDD570C50F6B7F25EBC7419 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		607FACE21AFB9204008FA782 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		607FACC71AFB9204008FA782 = {
+			isa = PBXGroup;
+			children = (
+				607FACF51AFB993E008FA782 /* Podspec Metadata */,
+				607FACE81AFB9204008FA782 /* Tests */,
+				607FACD11AFB9204008FA782 /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		607FACD11AFB9204008FA782 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				607FACE51AFB9204008FA782 /* FastLayout_Tests.xctest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		607FACE81AFB9204008FA782 /* Tests */ = {
+			isa = PBXGroup;
+			children = (
+				607FACEB1AFB9204008FA782 /* Tests.swift */,
+				607FACE91AFB9204008FA782 /* Supporting Files */,
+			);
+			path = Tests;
+			sourceTree = "<group>";
+		};
+		607FACE91AFB9204008FA782 /* Supporting Files */ = {
+			isa = PBXGroup;
+			children = (
+				607FACEA1AFB9204008FA782 /* Info.plist */,
+			);
+			name = "Supporting Files";
+			sourceTree = "<group>";
+		};
+		607FACF51AFB993E008FA782 /* Podspec Metadata */ = {
+			isa = PBXGroup;
+			children = (
+				9B6BD1B578E85F60162E4CD7 /* FastLayout.podspec */,
+				885738E17F531080B8B243EB /* README.md */,
+				FBDD570C50F6B7F25EBC7419 /* LICENSE */,
+			);
+			name = "Podspec Metadata";
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		607FACE41AFB9204008FA782 /* FastLayout_Tests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "FastLayout_Tests" */;
+			buildPhases = (
+				607FACE11AFB9204008FA782 /* Sources */,
+				607FACE21AFB9204008FA782 /* Frameworks */,
+				607FACE31AFB9204008FA782 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = FastLayout_Tests;
+			productName = Tests;
+			productReference = 607FACE51AFB9204008FA782 /* FastLayout_Tests.xctest */;
+			productType = "com.apple.product-type.bundle.unit-test";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		607FACC81AFB9204008FA782 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastSwiftUpdateCheck = 0830;
+				LastUpgradeCheck = 0830;
+				ORGANIZATIONNAME = CocoaPods;
+				TargetAttributes = {
+					607FACCF1AFB9204008FA782 = {
+						CreatedOnToolsVersion = 6.3.1;
+						LastSwiftMigration = 0900;
+					};
+					607FACE41AFB9204008FA782 = {
+						CreatedOnToolsVersion = 6.3.1;
+						LastSwiftMigration = 0900;
+						TestTargetID = 607FACCF1AFB9204008FA782;
+					};
+				};
+			};
+			buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "PROJECT" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = 607FACC71AFB9204008FA782;
+			productRefGroup = 607FACD11AFB9204008FA782 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				607FACE41AFB9204008FA782 /* FastLayout_Tests */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		607FACE31AFB9204008FA782 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		607FACE11AFB9204008FA782 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				607FACEC1AFB9204008FA782 /* Tests.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+		607FACD91AFB9204008FA782 /* Main.storyboard */ = {
+			isa = PBXVariantGroup;
+			children = (
+				607FACDA1AFB9204008FA782 /* Base */,
+			);
+			name = Main.storyboard;
+			sourceTree = "<group>";
+		};
+		607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = {
+			isa = PBXVariantGroup;
+			children = (
+				607FACDF1AFB9204008FA782 /* Base */,
+			);
+			name = LaunchScreen.xib;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		607FACED1AFB9204008FA782 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = iphoneos;
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+			};
+			name = Debug;
+		};
+		607FACEE1AFB9204008FA782 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = iphoneos;
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
+		607FACF01AFB9204008FA782 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				INFOPLIST_FILE = FastLayout/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				MODULE_NAME = ExampleApp;
+				PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_SWIFT3_OBJC_INFERENCE = Default;
+				SWIFT_VERSION = 4.0;
+			};
+			name = Debug;
+		};
+		607FACF11AFB9204008FA782 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				INFOPLIST_FILE = FastLayout/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+				MODULE_NAME = ExampleApp;
+				PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_SWIFT3_OBJC_INFERENCE = Default;
+				SWIFT_VERSION = 4.0;
+			};
+			name = Release;
+		};
+		607FACF31AFB9204008FA782 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(PLATFORM_DIR)/Developer/Library/Frameworks",
+					"$(inherited)",
+				);
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = Tests/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_SWIFT3_OBJC_INFERENCE = Default;
+				SWIFT_VERSION = 4.0;
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/FastLayout_Example.app/FastLayout_Example";
+			};
+			name = Debug;
+		};
+		607FACF41AFB9204008FA782 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(PLATFORM_DIR)/Developer/Library/Frameworks",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = Tests/Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_SWIFT3_OBJC_INFERENCE = Default;
+				SWIFT_VERSION = 4.0;
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/FastLayout_Example.app/FastLayout_Example";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "PROJECT" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				607FACED1AFB9204008FA782 /* Debug */,
+				607FACEE1AFB9204008FA782 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "FastLayout_Tests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				607FACF31AFB9204008FA782 /* Debug */,
+				607FACF41AFB9204008FA782 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 607FACC81AFB9204008FA782 /* Project object */;
+}

+ 7 - 0
Example/FastLayout.xcodeproj/project.xcworkspace/contents.xcworkspacedata

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:FastLayout.xcodeproj">
+   </FileRef>
+</Workspace>

+ 117 - 0
Example/FastLayout.xcodeproj/xcshareddata/xcschemes/FastLayout-Example.xcscheme

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0900"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "607FACCF1AFB9204008FA782"
+               BuildableName = "FastLayout_Example.app"
+               BlueprintName = "FastLayout_Example"
+               ReferencedContainer = "container:FastLayout.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "NO"
+            buildForArchiving = "NO"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "607FACE41AFB9204008FA782"
+               BuildableName = "FastLayout_Tests.xctest"
+               BlueprintName = "FastLayout_Tests"
+               ReferencedContainer = "container:FastLayout.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      language = ""
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+         <TestableReference
+            skipped = "NO">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "607FACE41AFB9204008FA782"
+               BuildableName = "FastLayout_Tests.xctest"
+               BlueprintName = "FastLayout_Tests"
+               ReferencedContainer = "container:FastLayout.xcodeproj">
+            </BuildableReference>
+         </TestableReference>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "607FACCF1AFB9204008FA782"
+            BuildableName = "FastLayout_Example.app"
+            BlueprintName = "FastLayout_Example"
+            ReferencedContainer = "container:FastLayout.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      language = ""
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "607FACCF1AFB9204008FA782"
+            BuildableName = "FastLayout_Example.app"
+            BlueprintName = "FastLayout_Example"
+            ReferencedContainer = "container:FastLayout.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "607FACCF1AFB9204008FA782"
+            BuildableName = "FastLayout_Example.app"
+            BlueprintName = "FastLayout_Example"
+            ReferencedContainer = "container:FastLayout.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 6 - 0
Example/Podfile

@@ -0,0 +1,6 @@
+use_frameworks!
+target 'FastLayout_Tests' do
+  pod 'FastLayout', :path => '../'
+  
+  
+end

+ 22 - 0
Example/Pods/Local Podspecs/FastLayout.podspec.json

@@ -0,0 +1,22 @@
+{
+  "name": "FastLayout",
+  "version": "0.1.0",
+  "summary": "A short description of FastLayout.",
+  "description": "TODO: Add long description of the pod here.",
+  "homepage": "https://github.com/xcbosa mbp16/FastLayout",
+  "license": {
+    "type": "MIT",
+    "file": "LICENSE"
+  },
+  "authors": {
+    "xcbosa mbp16": "xcbosa@forgetive.org"
+  },
+  "source": {
+    "git": "https://github.com/xcbosa mbp16/FastLayout.git",
+    "tag": "0.1.0"
+  },
+  "platforms": {
+    "ios": "10.0"
+  },
+  "source_files": "FastLayout/Classes/**/*"
+}

+ 24 - 0
Example/Tests/Info.plist

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+</dict>
+</plist>

+ 28 - 0
Example/Tests/Tests.swift

@@ -0,0 +1,28 @@
+import XCTest
+import FastLayout
+
+class Tests: XCTestCase {
+    
+    override func setUp() {
+        super.setUp()
+        // Put setup code here. This method is called before the invocation of each test method in the class.
+    }
+    
+    override func tearDown() {
+        // Put teardown code here. This method is called after the invocation of each test method in the class.
+        super.tearDown()
+    }
+    
+    func testExample() {
+        // This is an example of a functional test case.
+        XCTAssert(true, "Pass")
+    }
+    
+    func testPerformanceExample() {
+        // This is an example of a performance test case.
+        self.measure() {
+            // Put the code you want to measure the time of here.
+        }
+    }
+    
+}

+ 43 - 0
FastLayout.podspec

@@ -0,0 +1,43 @@
+#
+# Be sure to run `pod lib lint FastLayout.podspec' to ensure this is a
+# valid spec before submitting.
+#
+# Any lines starting with a # are optional, but their use is encouraged
+# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
+#
+
+Pod::Spec.new do |s|
+  s.name             = 'FastLayout'
+  s.version          = '0.1.0'
+  s.summary          = 'A powerful layout framework'
+
+# This description is used to generate tags and improve search results.
+#   * Think: What does it do? Why did you write it? What is the focus?
+#   * Try to keep it short, snappy and to the point.
+#   * Write the description between the DESC delimiters below.
+#   * Finally, don't worry about the indent, CocoaPods strips it!
+
+  s.description      = <<-DESC
+  A powerful layout framework: NSLayoutConstraint operator package
+                       DESC
+
+  s.homepage         = 'https://git.forgetive.org/XCAppCollection/FastLayout'
+  # s.screenshots     = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
+  s.license          = { :type => 'MIT', :file => 'LICENSE' }
+  s.author           = { 'xcbosa mbp16' => 'xcbosa@forgetive.org' }
+  s.source           = { :git => 'https://git.forgetive.org/XCAppCollection/FastLayout.git', :tag => s.version.to_s }
+  # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
+
+  s.ios.deployment_target = '14.0'
+  s.swift_version = '5.0'
+
+  s.source_files = 'FastLayout/Classes/**/*'
+  
+  # s.resource_bundles = {
+  #   'FastLayout' => ['FastLayout/Assets/*.png']
+  # }
+
+  # s.public_header_files = 'Pod/Classes/**/*.h'
+  # s.frameworks = 'UIKit', 'MapKit'
+  # s.dependency 'AFNetworking', '~> 2.3'
+end

+ 0 - 0
FastLayout/Assets/.gitkeep


+ 0 - 0
FastLayout/Classes/.gitkeep


+ 214 - 0
FastLayout/Classes/FLAnchorGroup.swift

@@ -0,0 +1,214 @@
+//
+//  File.swift
+//  
+//
+//  Created by XCBOSA on 2021/12/6.
+//
+
+import UIKit
+
+public class FLAnchorGroup {
+    
+    public private(set) var anchors: [FLAnchorWithOffsetBaseClass]
+    
+    init (withAnchors anchors: [FLAnchorWithOffsetBaseClass]) {
+        self.anchors = anchors
+    }
+    
+    public static func & (lhs: FLAnchorGroup, rhs: NSLayoutDimension) -> FLAnchorGroup {
+        var anchors = lhs.anchors
+        anchors.append(FLAnchorWithOffset<NSLayoutDimension>(withAnchor: rhs))
+        return FLAnchorGroup(withAnchors: anchors)
+    }
+    
+    public static func & (lhs: FLAnchorGroup, rhs: NSLayoutXAxisAnchor) -> FLAnchorGroup {
+        var anchors = lhs.anchors
+        anchors.append(FLAnchorWithOffset<NSLayoutXAxisAnchor>(withAnchor: rhs))
+        return FLAnchorGroup(withAnchors: anchors)
+    }
+    
+    public static func & (lhs: FLAnchorGroup, rhs: NSLayoutYAxisAnchor) -> FLAnchorGroup {
+        var anchors = lhs.anchors
+        anchors.append(FLAnchorWithOffset<NSLayoutYAxisAnchor>(withAnchor: rhs))
+        return FLAnchorGroup(withAnchors: anchors)
+    }
+    
+    public static func & (lhs: FLAnchorGroup, rhs: FLAnchorWithOffsetBaseClass) -> FLAnchorGroup {
+        var anchors = lhs.anchors
+        anchors.append(rhs)
+        return FLAnchorGroup(withAnchors: anchors)
+    }
+    
+    @discardableResult
+    public static func == (lhs: FLAnchorGroup, rhs: FLAnchorGroup) -> [NSLayoutConstraint] {
+        if lhs.anchors.count != rhs.anchors.count {
+            fatalError("Constraint expression specified \(lhs.anchors.count) anchors left doesn't match \(rhs.anchors.count) in right.")
+        }
+        var constraints = [NSLayoutConstraint]()
+        for it in 0..<lhs.anchors.count {
+            let leftAnchor = lhs.anchors[it]
+            let rightAnchor = rhs.anchors[it]
+            constraints.append(leftAnchor == rightAnchor)
+        }
+        return constraints
+    }
+    
+}
+
+extension NSLayoutDimension {
+    
+    public static func & (lhs: NSLayoutDimension, rhs: NSLayoutDimension) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutDimension>(withAnchor: lhs),
+            FLAnchorWithOffset<NSLayoutDimension>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: NSLayoutDimension, rhs: NSLayoutXAxisAnchor) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutDimension>(withAnchor: lhs),
+            FLAnchorWithOffset<NSLayoutXAxisAnchor>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: NSLayoutDimension, rhs: NSLayoutYAxisAnchor) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutDimension>(withAnchor: lhs),
+            FLAnchorWithOffset<NSLayoutYAxisAnchor>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: NSLayoutDimension, rhs: FLAnchorWithOffsetBaseClass) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutDimension>(withAnchor: lhs),
+            rhs
+        ])
+    }
+    
+}
+
+extension NSLayoutXAxisAnchor {
+    
+    public static func & (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutDimension) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutXAxisAnchor>(withAnchor: lhs),
+            FLAnchorWithOffset<NSLayoutDimension>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutXAxisAnchor) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutXAxisAnchor>(withAnchor: lhs),
+            FLAnchorWithOffset<NSLayoutXAxisAnchor>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutYAxisAnchor) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutXAxisAnchor>(withAnchor: lhs),
+            FLAnchorWithOffset<NSLayoutYAxisAnchor>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: NSLayoutXAxisAnchor, rhs: FLAnchorWithOffsetBaseClass) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutXAxisAnchor>(withAnchor: lhs),
+            rhs
+        ])
+    }
+    
+}
+
+extension NSLayoutYAxisAnchor {
+    
+    public static func & (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutDimension) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutYAxisAnchor>(withAnchor: lhs),
+            FLAnchorWithOffset<NSLayoutDimension>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutXAxisAnchor) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutYAxisAnchor>(withAnchor: lhs),
+            FLAnchorWithOffset<NSLayoutXAxisAnchor>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutYAxisAnchor) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutYAxisAnchor>(withAnchor: lhs),
+            FLAnchorWithOffset<NSLayoutYAxisAnchor>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: NSLayoutYAxisAnchor, rhs: FLAnchorWithOffsetBaseClass) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            FLAnchorWithOffset<NSLayoutYAxisAnchor>(withAnchor: lhs),
+            rhs
+        ])
+    }
+    
+}
+
+extension FLAnchorWithOffsetBaseClass {
+    
+    public static func & (lhs: FLAnchorWithOffsetBaseClass, rhs: NSLayoutDimension) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            lhs,
+            FLAnchorWithOffset<NSLayoutDimension>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: FLAnchorWithOffsetBaseClass, rhs: NSLayoutXAxisAnchor) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            lhs,
+            FLAnchorWithOffset<NSLayoutXAxisAnchor>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: FLAnchorWithOffsetBaseClass, rhs: NSLayoutYAxisAnchor) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            lhs,
+            FLAnchorWithOffset<NSLayoutYAxisAnchor>(withAnchor: rhs)
+        ])
+    }
+    
+    public static func & (lhs: FLAnchorWithOffsetBaseClass, rhs: FLAnchorWithOffsetBaseClass) -> FLAnchorGroup {
+        FLAnchorGroup(withAnchors: [
+            lhs,
+            rhs
+        ])
+    }
+    
+}
+
+extension FLAnchorWithOffsetBaseClass {
+    
+    @discardableResult
+    public static func == (lhs: FLAnchorWithOffsetBaseClass, rhs: FLAnchorWithOffsetBaseClass) -> NSLayoutConstraint {
+        lhs.makeSureDefaultMultiplier()
+        let offset = rhs.offset - lhs.offset
+        let multiplier = rhs.multiplier
+        if let lhsAnchor = lhs.anchorObject as? NSLayoutDimension {
+            guard let rhsAnchor = rhs.anchorObject as? NSLayoutDimension else {
+                fatalError("Constraint expression left is NSLayoutDimesion, but right isn't.")
+            }
+            return lhsAnchor == rhsAnchor * multiplier + offset
+        }
+        if let lhsAnchor = lhs.anchorObject as? NSLayoutXAxisAnchor {
+            guard let rhsAnchor = rhs.anchorObject as? NSLayoutXAxisAnchor else {
+                fatalError("Constraint expression left is NSLayoutXAxisAnchor, but right isn't.")
+            }
+            return lhsAnchor == rhsAnchor * multiplier + offset
+        }
+        if let lhsAnchor = lhs.anchorObject as? NSLayoutYAxisAnchor {
+            guard let rhsAnchor = rhs.anchorObject as? NSLayoutYAxisAnchor else {
+                fatalError("Constraint expression left is NSLayoutYAxisAnchor, but right isn't.")
+            }
+            return lhsAnchor == rhsAnchor * multiplier + offset
+        }
+        fatalError("Constraint expression left is not a vaild anchor.")
+    }
+    
+}

+ 129 - 0
FastLayout/Classes/FLAnchorWithOffset.swift

@@ -0,0 +1,129 @@
+//
+//  File.swift
+//  
+//
+//  Created by XCBOSA on 2021/12/4.
+//
+
+import UIKit
+
+public class FLAnchorWithOffsetBaseClass: NSObject {
+    public private(set) var offset: CGFloat
+    public private(set) var multiplier: CGFloat
+    public private(set) var anchorObject: NSObject
+    
+    init (anchorObject: NSObject, offset: CGFloat, multiplier: CGFloat) {
+        self.anchorObject = anchorObject
+        self.offset = offset
+        self.multiplier = multiplier
+    }
+    
+    func makeSureDefaultMultiplier() {
+        if multiplier != 1 {
+            fatalError("Constraint with NSLayoutXAxisAnchor or NSLayoutYAxisAnchor can't use multiplier or div operator.")
+        }
+    }
+}
+
+public class FLAnchorWithOffset<AnchorType>: FLAnchorWithOffsetBaseClass where AnchorType: NSObject {
+    public private(set) var baseAnchor: NSLayoutAnchor<AnchorType>
+    
+    init (withAnchor anchor: NSLayoutAnchor<AnchorType>) {
+        self.baseAnchor = anchor
+        super.init(anchorObject: anchor, offset: 0, multiplier: 1)
+    }
+    
+    init (withAnchor anchor: NSLayoutAnchor<AnchorType>, offset: CGFloat, multiplier: CGFloat) {
+        self.baseAnchor = anchor
+        super.init(anchorObject: anchor, offset: offset, multiplier: multiplier)
+    }
+    
+    func getAnchor<AsType>() -> AsType {
+        guard let anchor = baseAnchor as? AsType else {
+            var classA = "[Not Objc Class]", classB = NSStringFromClass(AnchorType.self)
+            if let type = AsType.self as? AnyClass {
+                classA = NSStringFromClass(type)
+            }
+            fatalError("Constraint require \(classA), but got \(classB)")
+        }
+        return anchor
+    }
+    
+    public static func + (lhs: FLAnchorWithOffset, rhs: CGFloat) -> FLAnchorWithOffset<AnchorType> {
+        FLAnchorWithOffset(withAnchor: lhs.baseAnchor, offset: lhs.offset + rhs, multiplier: lhs.multiplier)
+    }
+    
+    public static func - (lhs: FLAnchorWithOffset, rhs: CGFloat) -> FLAnchorWithOffset<AnchorType> {
+        FLAnchorWithOffset(withAnchor: lhs.baseAnchor, offset: lhs.offset - rhs, multiplier: lhs.multiplier)
+    }
+    
+    public static func * (lhs: FLAnchorWithOffset, rhs: CGFloat) -> FLAnchorWithOffset<AnchorType> {
+        FLAnchorWithOffset(withAnchor: lhs.baseAnchor, offset: lhs.offset, multiplier: lhs.multiplier * rhs)
+    }
+    
+    public static func / (lhs: FLAnchorWithOffset, rhs: CGFloat) -> FLAnchorWithOffset<AnchorType> {
+        FLAnchorWithOffset(withAnchor: lhs.baseAnchor, offset: lhs.offset, multiplier: lhs.multiplier / rhs)
+    }
+}
+
+public func FLCreateAndActiveConstraint<AnchorType>(_ lhs: AnchorType, _ rhs: FLAnchorWithOffset<AnchorType>, method: (AnchorType, FLAnchorWithOffset<AnchorType>) -> NSLayoutConstraint) -> NSLayoutConstraint {
+    let constraint = method(lhs, rhs)
+    constraint.isActive = true
+    FLConstraintRecorder.standard.add(constraint: constraint)
+    return constraint
+}
+
+extension NSLayoutDimension {
+    public static func + (lhs: NSLayoutDimension, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutDimension> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: rhs, multiplier: 1)
+    }
+    
+    public static func - (lhs: NSLayoutDimension, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutDimension> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: -rhs, multiplier: 1)
+    }
+    
+    public static func * (lhs: NSLayoutDimension, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutDimension> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: 0, multiplier: rhs)
+    }
+    
+    public static func / (lhs: NSLayoutDimension, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutDimension> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: 0, multiplier: 1 / rhs)
+    }
+}
+
+extension NSLayoutXAxisAnchor {
+    public static func + (lhs: NSLayoutXAxisAnchor, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutXAxisAnchor> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: rhs, multiplier: 1)
+    }
+    
+    public static func - (lhs: NSLayoutXAxisAnchor, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutXAxisAnchor> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: -rhs, multiplier: 1)
+    }
+    
+    public static func * (lhs: NSLayoutXAxisAnchor, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutXAxisAnchor> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: 0, multiplier: rhs)
+    }
+    
+    public static func / (lhs: NSLayoutXAxisAnchor, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutXAxisAnchor> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: 0, multiplier: 1 / rhs)
+    }
+}
+
+extension NSLayoutYAxisAnchor {
+    public static func + (lhs: NSLayoutYAxisAnchor, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutYAxisAnchor> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: rhs, multiplier: 1)
+    }
+    
+    public static func - (lhs: NSLayoutYAxisAnchor, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutYAxisAnchor> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: -rhs, multiplier: 1)
+    }
+    
+    public static func * (lhs: NSLayoutYAxisAnchor, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutYAxisAnchor> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: 0, multiplier: rhs)
+    }
+    
+    public static func / (lhs: NSLayoutYAxisAnchor, rhs: CGFloat) -> FLAnchorWithOffset<NSLayoutYAxisAnchor> {
+        FLAnchorWithOffset(withAnchor: lhs, offset: 0, multiplier: 1 / rhs)
+    }
+}
+

+ 32 - 0
FastLayout/Classes/FLConstraintRecorder.swift

@@ -0,0 +1,32 @@
+//
+//  File.swift
+//  
+//
+//  Created by XCBOSA on 2021/12/7.
+//
+
+import UIKit
+
+public class FLConstraintRecorder {
+    
+    public static let standard = FLConstraintRecorder()
+    
+    var constraints: [NSLayoutConstraint]?
+    
+    func add(constraint: NSLayoutConstraint) {
+        guard constraints != nil else { return }
+        constraints!.append(constraint)
+    }
+    
+    public func beginRecord() {
+        constraints = [NSLayoutConstraint]()
+    }
+    
+    public func endRecord() -> [NSLayoutConstraint] {
+        let copyConstraints = self.constraints
+        self.constraints = [NSLayoutConstraint]()
+        return copyConstraints ?? [NSLayoutConstraint]()
+    }
+    
+}
+

+ 128 - 0
FastLayout/Classes/FLSubviewArranger.swift

@@ -0,0 +1,128 @@
+//
+//  File.swift
+//  
+//
+//  Created by XCBOSA on 2021/12/6.
+//
+
+import UIKit
+
+public class FLUIViewWithConstraint {
+    
+    public private(set) var view: UIView
+    public private(set) var constraintExpressions: (UIView) -> Void
+    
+    init (view: UIView, expression: @escaping (UIView) -> Void) {
+        self.view = view
+        self.constraintExpressions = expression
+    }
+    
+}
+
+public class FLSubviewArranger {
+    
+    public private(set) var subviews = [FLUIViewWithConstraint]()
+    public private(set) var constraintExpressions = [() -> Void]()
+    public private(set) weak var view: UIView?
+    
+    init (view: UIView) {
+        self.view = view
+    }
+    
+    @discardableResult
+    public func add(subviewWithConstraint subview: FLUIViewWithConstraint) -> FLSubviewArranger {
+        subviews.append(subview)
+        return self
+    }
+    
+    @discardableResult
+    public func addSubview(_ subview: UIView) -> FLSubviewArranger {
+        add(subviewWithConstraint: FLUIViewWithConstraint(view: subview, expression: { _ in }))
+    }
+    
+    @discardableResult
+    public func addSubview(_ subview: UIView, _ constraintExpression: @escaping (UIView) -> Void) -> FLSubviewArranger {
+        add(subviewWithConstraint: FLUIViewWithConstraint(view: subview, expression: constraintExpression))
+    }
+    
+    @discardableResult
+    public func addConstraintExpression(_ expression: @escaping () -> Void) -> FLSubviewArranger {
+        self.constraintExpressions.append(expression)
+        return self
+    }
+    
+    public func finish() {
+        guard let view = view else { return }
+        _ = subviews.map({ $0.view.translatesAutoresizingMaskIntoConstraints = false })
+        view.addSubViews(subviews.map({ $0.view }))
+        let _: [Void] = subviews.map({ $0.constraintExpressions($0.view) })
+        let _: [Void] = constraintExpressions.map({ $0() })
+    }
+    
+}
+
+fileprivate var globalViewArrangerTable = [UIView : FLSubviewArranger]()
+
+extension UIView {
+    
+    /// 获取一个Arranger,如果当前UIView未进行beginArrangeSubviews()或已经调用endArrangeSubviews(),则返回一个新的Arranger,否则返回当前UIView的Arranger
+    public var arranger: FLSubviewArranger {
+        if let arranger = globalViewArrangerTable[self] {
+            return arranger
+        }
+        return FLSubviewArranger(view: self)
+    }
+    
+    /// 开始为当前UIView布局,将此UIView附加一个新的Arranger
+    public func beginArrangeSubviews() {
+        if globalViewArrangerTable[self] != nil {
+            fatalError("View has been already begin arranged, but call beginArrangeSubviews() again.")
+        }
+        globalViewArrangerTable[self] = FLSubviewArranger(view: self)
+    }
+    
+    /// 结束当前UIView布局,应用布局并删除当前UIView的Arranger
+    public func endArrangeSubviews() {
+        if let arranger = globalViewArrangerTable[self] {
+            arranger.finish()
+            globalViewArrangerTable.removeValue(forKey: self)
+        } else {
+            fatalError("View was not begin arranged, need call beginArrangeSubviews() first.")
+        }
+    }
+    
+    @discardableResult
+    /// 如果当前UIView未进行beginArrangeSubviews()或已经调用endArrangeSubviews(),则创建一个新的Arranger并添加组件,否则使用当前UIView的Arranger添加组件
+    /// - Parameter subview: 要添加的组件
+    /// - Returns: Arranger
+    public func arrangerAdd(subviewWithConstraint subview: FLUIViewWithConstraint) -> FLSubviewArranger {
+        arranger.add(subviewWithConstraint: subview)
+    }
+    
+    @discardableResult
+    /// 如果当前UIView未进行beginArrangeSubviews()或已经调用endArrangeSubviews(),则创建一个新的Arranger并添加组件,否则使用当前UIView的Arranger添加组件
+    /// - Parameter subview: 要添加的组件
+    /// - Returns: Arranger
+    public func arrangerAddSubview(_ subview: UIView) -> FLSubviewArranger {
+        arranger.add(subviewWithConstraint: FLUIViewWithConstraint(view: subview, expression: { _ in }))
+    }
+    
+    @discardableResult
+    /// 如果当前UIView未进行beginArrangeSubviews()或已经调用endArrangeSubviews(),则创建一个新的Arranger并添加约束表达式,否则使用当前UIView的Arranger添加约束表达式
+    /// - Parameter expression: 约束表达式
+    /// - Returns: Arranger
+    public func arrangerAddConstraintExpression(_ expression: @escaping () -> Void) -> FLSubviewArranger {
+        arranger.addConstraintExpression(expression)
+    }
+    
+    @discardableResult
+    /// 如果当前UIView未进行beginArrangeSubviews()或已经调用endArrangeSubviews(),则创建一个新的Arranger并添加组件,否则使用当前UIView的Arranger添加组件
+    /// - Parameters:
+    ///   - subview: 要添加的组件
+    ///   - constraintExpression: 约束函数
+    /// - Returns: Arranger
+    public func arrangerAddSubview(_ subview: UIView, _ constraintExpression: @escaping (UIView) -> Void) -> FLSubviewArranger {
+        arranger.add(subviewWithConstraint: FLUIViewWithConstraint(view: subview, expression: constraintExpression))
+    }
+    
+}

+ 114 - 0
FastLayout/Classes/FLViewState.swift

@@ -0,0 +1,114 @@
+//
+//  File.swift
+//  
+//
+//  Created by XCBOSA on 2021/12/7.
+//
+
+import UIKit
+
+public typealias FLViewStateCheckerBlock = (CGFloat, CGFloat) -> Bool
+
+public let FLViewStateCheckerBlockHorizontal: FLViewStateCheckerBlock = { $0 > $1 }
+public let FLViewStateCheckerBlockPortrait: FLViewStateCheckerBlock = { $0 < $1 }
+
+public class FLViewState {
+    public private(set) var constraintGroup = [NSLayoutConstraint]()
+    public private(set) var checker: FLViewStateCheckerBlock
+    public private(set) var recorder: FLConstraintRecorder?
+    
+    fileprivate var isExtensionCreated: Bool = false
+    
+    public init (checkerBlock: @escaping FLViewStateCheckerBlock) {
+        self.checker = checkerBlock
+    }
+    
+    public init (configureWithRecorder recorder: FLConstraintRecorder, checkerBlock: @escaping FLViewStateCheckerBlock) {
+        self.checker = checkerBlock
+        self.recorder = recorder
+        self.recorder!.beginRecord()
+    }
+    
+    public func append(_ constraintObject: NSLayoutConstraint) {
+        constraintObject.isActive = isActive
+        self.constraintGroup.append(constraintObject)
+    }
+    
+    public func append(contentsOf contents: [NSLayoutConstraint]) {
+        _ = contents.map({ self.append($0) })
+    }
+    
+    public func remove(content: NSLayoutConstraint) {
+        self.constraintGroup.removeAll(where: { $0 == content })
+    }
+    
+    public func finishRecorder() {
+        guard let recorder = self.recorder else {
+            fatalError("FLViewState.finishRecorder() must called on object which init with init(configureWithRecorder: checkerBlock:), or FLViewState.finishRecorder() has already called on this object.")
+        }
+        self.append(contentsOf: recorder.endRecord())
+        self.recorder = nil
+    }
+    
+    public var isActive: Bool = false {
+        didSet {
+            _ = constraintGroup.map({ $0.isActive = isActive })
+        }
+    }
+}
+
+public class FLViewStateManager {
+    public init () { }
+    
+    public private(set) var viewStates = [FLViewState]()
+    
+    public func register(viewState: FLViewState) {
+        self.viewStates.append(viewState)
+    }
+    
+    public func triggerViewSizeChanged(width: CGFloat, height: CGFloat) {
+        _ = self.viewStates.map({ $0.isActive = $0.checker(width, height) })
+    }
+}
+
+extension FLViewStateManager {
+    
+    public typealias ConstraintLoader = () -> Void
+    
+    public func configure(withHorizontal horizontal: ConstraintLoader, portrait: ConstraintLoader, horizontalBlock: FLViewStateCheckerBlock? = nil, portraitBlock: FLViewStateCheckerBlock? = nil) {
+        if self.viewStates.count > 0 {
+            fatalError("FLViewStateManager.configureWith(horizontal: portrait:) can't called after register(viewState:) called.")
+        }
+        let horizontalState = FLViewState(configureWithRecorder: .standard, checkerBlock: horizontalBlock ?? FLViewStateCheckerBlockHorizontal)
+        horizontalState.isExtensionCreated = true
+        horizontal()
+        horizontalState.finishRecorder()
+        let portraitState = FLViewState(configureWithRecorder: .standard, checkerBlock: portraitBlock ?? FLViewStateCheckerBlockPortrait)
+        portraitState.isExtensionCreated = true
+        portrait()
+        portraitState.finishRecorder()
+        self.register(viewState: horizontalState)
+        self.register(viewState: portraitState)
+    }
+    
+    public var horizontalState: FLViewState {
+        if self.viewStates.count < 2 {
+            fatalError("FLViewStateManager.horizontalState can't called before FLViewStateManager.configureWith(horizontal: portrait:)")
+        }
+        if !self.viewStates[0].isExtensionCreated {
+            fatalError("FLViewStateManager.horizontalState can't called on FLViewStateManager instance where created by register(viewState:)")
+        }
+        return self.viewStates[0]
+    }
+    
+    public var portraitState: FLViewState {
+        if self.viewStates.count < 2 {
+            fatalError("FLViewStateManager.portraitState can't called before FLViewStateManager.configureWith(horizontal: portrait:)")
+        }
+        if !self.viewStates[1].isExtensionCreated {
+            fatalError("FLViewStateManager.portraitState can't called on FLViewStateManager instance where created by register(viewState:)")
+        }
+        return self.viewStates[1]
+    }
+    
+}

+ 115 - 0
FastLayout/Classes/FastLayout.swift

@@ -0,0 +1,115 @@
+//
+//  FastLayout.swift
+//
+//
+//  Created by XCBOSA on 2021/12/4.
+//
+
+import UIKit
+
+extension NSLayoutDimension {
+    @discardableResult
+    public static func == (lhs: NSLayoutDimension, rhs: NSLayoutDimension) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(equalTo: $1) }
+    }
+    
+    @discardableResult
+    public static func == (lhs: NSLayoutDimension, rhs: FLAnchorWithOffset<NSLayoutDimension>) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(equalTo: $1.getAnchor(), multiplier: rhs.multiplier, constant: $1.offset) }
+    }
+    
+    @discardableResult
+    public static func == (lhs: NSLayoutDimension, rhs: CGFloat) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint__(lhs, rhs) { $0.constraint(equalToConstant: $1) }
+    }
+    
+    @discardableResult
+    public static func <= (lhs: NSLayoutDimension, rhs: NSLayoutDimension) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(lessThanOrEqualTo: $1) }
+    }
+    
+    @discardableResult
+    public static func <= (lhs: NSLayoutDimension, rhs: FLAnchorWithOffset<NSLayoutDimension>) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(lessThanOrEqualTo: $1.getAnchor(), multiplier: rhs.multiplier, constant: $1.offset) }
+    }
+    
+    @discardableResult
+    public static func >= (lhs: NSLayoutDimension, rhs: NSLayoutDimension) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(greaterThanOrEqualTo: $1) }
+    }
+    
+    @discardableResult
+    public static func >= (lhs: NSLayoutDimension, rhs: FLAnchorWithOffset<NSLayoutDimension>) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(greaterThanOrEqualTo: $1.getAnchor(), multiplier: rhs.multiplier, constant: $1.offset) }
+    }
+}
+
+extension NSLayoutXAxisAnchor {
+    @discardableResult
+    public static func == (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutXAxisAnchor) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(equalTo: $1) }
+    }
+    
+    @discardableResult
+    public static func == (lhs: NSLayoutXAxisAnchor, rhs: FLAnchorWithOffset<NSLayoutXAxisAnchor>) -> NSLayoutConstraint {
+        rhs.makeSureDefaultMultiplier()
+        return FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(equalTo: $1.baseAnchor, constant: $1.offset) }
+    }
+    
+    @discardableResult
+    public static func <= (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutXAxisAnchor) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(lessThanOrEqualTo: $1) }
+    }
+    
+    @discardableResult
+    public static func <= (lhs: NSLayoutXAxisAnchor, rhs: FLAnchorWithOffset<NSLayoutXAxisAnchor>) -> NSLayoutConstraint {
+        rhs.makeSureDefaultMultiplier()
+        return FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(lessThanOrEqualTo: $1.baseAnchor, constant: $1.offset) }
+    }
+    
+    @discardableResult
+    public static func >= (lhs: NSLayoutXAxisAnchor, rhs: NSLayoutXAxisAnchor) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(greaterThanOrEqualTo: $1) }
+    }
+    
+    @discardableResult
+    public static func >= (lhs: NSLayoutXAxisAnchor, rhs: FLAnchorWithOffset<NSLayoutXAxisAnchor>) -> NSLayoutConstraint {
+        rhs.makeSureDefaultMultiplier()
+        return FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(greaterThanOrEqualTo: $1.baseAnchor, constant: $1.offset) }
+    }
+}
+
+extension NSLayoutYAxisAnchor {
+    @discardableResult
+    public static func == (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutYAxisAnchor) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(equalTo: $1) }
+    }
+    
+    @discardableResult
+    public static func == (lhs: NSLayoutYAxisAnchor, rhs: FLAnchorWithOffset<NSLayoutYAxisAnchor>) -> NSLayoutConstraint {
+        rhs.makeSureDefaultMultiplier()
+        return FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(equalTo: $1.baseAnchor, constant: $1.offset) }
+    }
+    
+    @discardableResult
+    public static func <= (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutYAxisAnchor) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(lessThanOrEqualTo: $1) }
+    }
+    
+    @discardableResult
+    public static func <= (lhs: NSLayoutYAxisAnchor, rhs: FLAnchorWithOffset<NSLayoutYAxisAnchor>) -> NSLayoutConstraint {
+        rhs.makeSureDefaultMultiplier()
+        return FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(lessThanOrEqualTo: $1.baseAnchor, constant: $1.offset) }
+    }
+    
+    @discardableResult
+    public static func >= (lhs: NSLayoutYAxisAnchor, rhs: NSLayoutYAxisAnchor) -> NSLayoutConstraint {
+        FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(greaterThanOrEqualTo: $1) }
+    }
+    
+    @discardableResult
+    public static func >= (lhs: NSLayoutYAxisAnchor, rhs: FLAnchorWithOffset<NSLayoutYAxisAnchor>) -> NSLayoutConstraint {
+        rhs.makeSureDefaultMultiplier()
+        return FLCreateAndActiveConstraint(lhs, rhs) { $0.constraint(greaterThanOrEqualTo: $1.baseAnchor, constant: $1.offset) }
+    }
+}

+ 180 - 0
FastLayout/Classes/Utils.swift

@@ -0,0 +1,180 @@
+//
+//  Utils.swift
+//  
+//
+//  Created by XCBOSA on 2021/12/4.
+//
+
+import UIKit
+
+extension UIView {
+    
+    public var left: NSLayoutXAxisAnchor {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.leftAnchor
+    }
+    
+    public var right: NSLayoutXAxisAnchor {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.rightAnchor
+    }
+    
+    public var leading: NSLayoutXAxisAnchor {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.leadingAnchor
+    }
+    
+    public var trailing: NSLayoutXAxisAnchor {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.trailingAnchor
+    }
+    
+    public var top: NSLayoutYAxisAnchor {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.topAnchor
+    }
+    
+    public var bottom: NSLayoutYAxisAnchor {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.bottomAnchor
+    }
+    
+    public var width: NSLayoutDimension {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.widthAnchor
+    }
+    
+    public var height: NSLayoutDimension {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.heightAnchor
+    }
+    
+    public var centerX: NSLayoutXAxisAnchor {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.centerXAnchor
+    }
+    
+    public var centerY: NSLayoutYAxisAnchor {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.centerYAnchor
+    }
+    
+    public var centerXY: FLAnchorGroup { self.centerX & self.centerY }
+    public var centerYX: FLAnchorGroup { self.centerY & self.centerX }
+    public var leftTop: FLAnchorGroup { self.left & self.top }
+    public var rightTop: FLAnchorGroup { self.right & self.top }
+    public var leftBottom: FLAnchorGroup { self.left & self.bottom }
+    public var rightBottom: FLAnchorGroup { self.right & self.bottom }
+    public var topLeft: FLAnchorGroup { self.top & self.left }
+    public var topRight: FLAnchorGroup { self.top & self.right }
+    public var bottomLeft: FLAnchorGroup { self.bottom & self.left }
+    public var bottomRight: FLAnchorGroup { self.bottom & self.right }
+    public var leftRight: FLAnchorGroup { self.left & self.right }
+    public var rightLeft: FLAnchorGroup { self.right & self.left }
+    public var topBottom: FLAnchorGroup { self.top & self.bottom }
+    public var bottomTop: FLAnchorGroup { self.bottom & self.top }
+    public var size: FLAnchorGroup { self.width & self.height }
+    
+    public var safeArea: UILayoutGuide {
+        if #available(iOS 11.0, *) {
+            return self.safeAreaLayoutGuide
+        } else {
+            fatalError("Not support before iOS11.")
+        }
+    }
+    
+    public var firstBaseLine: NSLayoutYAxisAnchor {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.firstBaselineAnchor
+    }
+    
+    public var lastBaseLine: NSLayoutYAxisAnchor {
+        self.translatesAutoresizingMaskIntoConstraints = false
+        return self.lastBaselineAnchor
+    }
+    
+    public func addSubViews(_ views: [UIView]) {
+        for view in views {
+            self.addSubview(view)
+        }
+    }
+    
+    public func configureSubView(_ views: UIView ...) {
+        self.addSubViews(views)
+    }
+    
+}
+
+extension UILayoutGuide {
+    
+    public var left: NSLayoutXAxisAnchor {
+        return self.leftAnchor
+    }
+    
+    public var right: NSLayoutXAxisAnchor {
+        return self.rightAnchor
+    }
+    
+    public var leading: NSLayoutXAxisAnchor {
+        return self.leadingAnchor
+    }
+    
+    public var trailing: NSLayoutXAxisAnchor {
+        return self.trailingAnchor
+    }
+    
+    public var top: NSLayoutYAxisAnchor {
+        return self.topAnchor
+    }
+    
+    public var bottom: NSLayoutYAxisAnchor {
+        return self.bottomAnchor
+    }
+    
+    public var width: NSLayoutDimension {
+        return self.widthAnchor
+    }
+    
+    public var height: NSLayoutDimension {
+        return self.heightAnchor
+    }
+    
+    public var centerX: NSLayoutXAxisAnchor {
+        return self.centerXAnchor
+    }
+    
+    public var centerY: NSLayoutYAxisAnchor {
+        return self.centerYAnchor
+    }
+    
+    public var centerXY: FLAnchorGroup { self.centerX & self.centerY }
+    public var centerYX: FLAnchorGroup { self.centerY & self.centerX }
+    public var leftTop: FLAnchorGroup { self.left & self.top }
+    public var rightTop: FLAnchorGroup { self.right & self.top }
+    public var leftBottom: FLAnchorGroup { self.left & self.bottom }
+    public var rightBottom: FLAnchorGroup { self.right & self.bottom }
+    public var topLeft: FLAnchorGroup { self.top & self.left }
+    public var topRight: FLAnchorGroup { self.top & self.right }
+    public var bottomLeft: FLAnchorGroup { self.bottom & self.left }
+    public var bottomRight: FLAnchorGroup { self.bottom & self.right }
+    public var leftRight: FLAnchorGroup { self.left & self.right }
+    public var rightLeft: FLAnchorGroup { self.right & self.left }
+    public var topBottom: FLAnchorGroup { self.top & self.bottom }
+    public var bottomTop: FLAnchorGroup { self.bottom & self.top }
+    public var size: FLAnchorGroup { self.width & self.height }
+    
+}
+
+public func FLCreateAndActiveConstraint<AnchorType>(_ lhs: NSLayoutAnchor<AnchorType>, _ rhs: NSLayoutAnchor<AnchorType>, method: (NSLayoutAnchor<AnchorType>, NSLayoutAnchor<AnchorType>) -> NSLayoutConstraint) -> NSLayoutConstraint {
+    let constraint = method(lhs, rhs)
+    constraint.isActive = true
+    FLConstraintRecorder.standard.add(constraint: constraint)
+    return constraint
+}
+
+public func FLCreateAndActiveConstraint__<AnchorType>(_ lhs: AnchorType, _ rhs: CGFloat, method: (AnchorType, CGFloat) -> NSLayoutConstraint) -> NSLayoutConstraint {
+    let constraint = method(lhs, rhs)
+    constraint.isActive = true
+    FLConstraintRecorder.standard.add(constraint: constraint)
+    return constraint
+}

+ 19 - 0
LICENSE

@@ -0,0 +1,19 @@
+Copyright (c) 2023 xcbosa mbp16 <xcbosa@forgetive.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 29 - 0
README.md

@@ -0,0 +1,29 @@
+# FastLayout
+
+[![CI Status](https://img.shields.io/travis/xcbosa mbp16/FastLayout.svg?style=flat)](https://travis-ci.org/xcbosa mbp16/FastLayout)
+[![Version](https://img.shields.io/cocoapods/v/FastLayout.svg?style=flat)](https://cocoapods.org/pods/FastLayout)
+[![License](https://img.shields.io/cocoapods/l/FastLayout.svg?style=flat)](https://cocoapods.org/pods/FastLayout)
+[![Platform](https://img.shields.io/cocoapods/p/FastLayout.svg?style=flat)](https://cocoapods.org/pods/FastLayout)
+
+## Example
+
+To run the example project, clone the repo, and run `pod install` from the Example directory first.
+
+## Requirements
+
+## Installation
+
+FastLayout is available through [CocoaPods](https://cocoapods.org). To install
+it, simply add the following line to your Podfile:
+
+```ruby
+pod 'FastLayout'
+```
+
+## Author
+
+xcbosa mbp16, xcbosa@forgetive.org
+
+## License
+
+FastLayout is available under the MIT license. See the LICENSE file for more info.

+ 1 - 0
_Pods.xcodeproj

@@ -0,0 +1 @@
+Example/Pods/Pods.xcodeproj