From 9ffbed67b44507a39c01b268524c9634b3c87522 Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Thu, 5 Mar 2015 15:12:15 -0800 Subject: [PATCH 01/18] Simplify API Finally decided on a certain API style. --- ManualLayout.xcodeproj/project.pbxproj | 60 ++--- ManualLayout/CALayer+FastAccess.swift | 207 ---------------- ManualLayout/CALayer+ManualLayout.swift | 207 +++++++++++++++- ManualLayout/ManualLayout.swift | 31 --- .../{Operators.swift => SmartAssign.swift} | 2 +- ManualLayout/UIView+FastAccess.swift | 101 -------- ManualLayout/UIView+ManualLayout.swift | 94 ++++++- ManualLayoutTests/FastAccessTests.swift | 229 ------------------ ManualLayoutTests/ManualLayoutTests.swift | 229 ++++++++++++++++-- ...atorTests.swift => SmartAssignTests.swift} | 4 +- .../UIViewManualLayoutTests.swift | 38 --- 11 files changed, 525 insertions(+), 677 deletions(-) delete mode 100644 ManualLayout/CALayer+FastAccess.swift delete mode 100644 ManualLayout/ManualLayout.swift rename ManualLayout/{Operators.swift => SmartAssign.swift} (96%) delete mode 100644 ManualLayout/UIView+FastAccess.swift delete mode 100644 ManualLayoutTests/FastAccessTests.swift rename ManualLayoutTests/{OperatorTests.swift => SmartAssignTests.swift} (92%) delete mode 100644 ManualLayoutTests/UIViewManualLayoutTests.swift diff --git a/ManualLayout.xcodeproj/project.pbxproj b/ManualLayout.xcodeproj/project.pbxproj index 8ef7951..d7d5439 100644 --- a/ManualLayout.xcodeproj/project.pbxproj +++ b/ManualLayout.xcodeproj/project.pbxproj @@ -7,22 +7,17 @@ objects = { /* Begin PBXBuildFile section */ - 5F67BC0A1A9D43FE00347483 /* FastAccessTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC091A9D43FE00347483 /* FastAccessTests.swift */; }; + 5F67BC0A1A9D43FE00347483 /* ManualLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC091A9D43FE00347483 /* ManualLayoutTests.swift */; }; 5F67BC3F1A9E970300347483 /* UIViewController+LayoutGuides.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC3E1A9E970300347483 /* UIViewController+LayoutGuides.swift */; }; - 5F67BC4C1A9FAB4B00347483 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4B1A9FAB4B00347483 /* Operators.swift */; }; - 5F67BC4E1A9FB1A600347483 /* OperatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4D1A9FB1A600347483 /* OperatorTests.swift */; }; + 5F67BC4C1A9FAB4B00347483 /* SmartAssign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */; }; + 5F67BC4E1A9FB1A600347483 /* SmartAssignTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4D1A9FB1A600347483 /* SmartAssignTests.swift */; }; 5F67BC501A9FDDD900347483 /* HelperFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4F1A9FDDD900347483 /* HelperFunctions.swift */; }; 5F67BC521A9FE35C00347483 /* HelperFunctionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC511A9FE35C00347483 /* HelperFunctionTests.swift */; }; 5F875C581A9BC8BF003CACDD /* Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C571A9BC8BF003CACDD /* Enums.swift */; }; - 5F875C5B1A9BCBB2003CACDD /* UIView+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C5A1A9BCBB2003CACDD /* UIView+ManualLayout.swift */; }; - 5F875C5F1A9BD55D003CACDD /* ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C5E1A9BD55D003CACDD /* ManualLayout.swift */; }; - 5F875C651A9BE2D3003CACDD /* UIViewManualLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C641A9BE2D3003CACDD /* UIViewManualLayoutTests.swift */; }; - 5F875C691A9BE99F003CACDD /* CALayer+FastAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C681A9BE99F003CACDD /* CALayer+FastAccess.swift */; }; - 5F875C6D1A9BFC7E003CACDD /* UIView+FastAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C6C1A9BFC7E003CACDD /* UIView+FastAccess.swift */; }; - 5F875C6F1A9BFE01003CACDD /* CALayer+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C6E1A9BFE01003CACDD /* CALayer+ManualLayout.swift */; }; + 5F875C691A9BE99F003CACDD /* CALayer+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C681A9BE99F003CACDD /* CALayer+ManualLayout.swift */; }; + 5F875C6D1A9BFC7E003CACDD /* UIView+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C6C1A9BFC7E003CACDD /* UIView+ManualLayout.swift */; }; 5FB4CBEF1A9BBE7500C2FB4F /* ManualLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FB4CBEE1A9BBE7500C2FB4F /* ManualLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5FB4CBF51A9BBE7500C2FB4F /* ManualLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5FB4CBE91A9BBE7500C2FB4F /* ManualLayout.framework */; }; - 5FB4CBFC1A9BBE7500C2FB4F /* ManualLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FB4CBFB1A9BBE7500C2FB4F /* ManualLayoutTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -36,25 +31,20 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 5F67BC091A9D43FE00347483 /* FastAccessTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FastAccessTests.swift; sourceTree = ""; }; + 5F67BC091A9D43FE00347483 /* ManualLayoutTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManualLayoutTests.swift; sourceTree = ""; }; 5F67BC3E1A9E970300347483 /* UIViewController+LayoutGuides.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+LayoutGuides.swift"; sourceTree = ""; }; - 5F67BC4B1A9FAB4B00347483 /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = ""; }; - 5F67BC4D1A9FB1A600347483 /* OperatorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OperatorTests.swift; sourceTree = ""; }; + 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartAssign.swift; sourceTree = ""; }; + 5F67BC4D1A9FB1A600347483 /* SmartAssignTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartAssignTests.swift; sourceTree = ""; }; 5F67BC4F1A9FDDD900347483 /* HelperFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HelperFunctions.swift; sourceTree = ""; }; 5F67BC511A9FE35C00347483 /* HelperFunctionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HelperFunctionTests.swift; sourceTree = ""; }; 5F875C571A9BC8BF003CACDD /* Enums.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Enums.swift; sourceTree = ""; }; - 5F875C5A1A9BCBB2003CACDD /* UIView+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+ManualLayout.swift"; sourceTree = ""; }; - 5F875C5E1A9BD55D003CACDD /* ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManualLayout.swift; sourceTree = ""; }; - 5F875C641A9BE2D3003CACDD /* UIViewManualLayoutTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewManualLayoutTests.swift; sourceTree = ""; }; - 5F875C681A9BE99F003CACDD /* CALayer+FastAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CALayer+FastAccess.swift"; sourceTree = ""; }; - 5F875C6C1A9BFC7E003CACDD /* UIView+FastAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+FastAccess.swift"; sourceTree = ""; }; - 5F875C6E1A9BFE01003CACDD /* CALayer+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CALayer+ManualLayout.swift"; sourceTree = ""; }; + 5F875C681A9BE99F003CACDD /* CALayer+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CALayer+ManualLayout.swift"; sourceTree = ""; }; + 5F875C6C1A9BFC7E003CACDD /* UIView+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+ManualLayout.swift"; sourceTree = ""; }; 5FB4CBE91A9BBE7500C2FB4F /* ManualLayout.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ManualLayout.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5FB4CBED1A9BBE7500C2FB4F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5FB4CBEE1A9BBE7500C2FB4F /* ManualLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ManualLayout.h; sourceTree = ""; }; 5FB4CBF41A9BBE7500C2FB4F /* ManualLayoutTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ManualLayoutTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5FB4CBFA1A9BBE7500C2FB4F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5FB4CBFB1A9BBE7500C2FB4F /* ManualLayoutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualLayoutTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -99,13 +89,10 @@ children = ( 5FB4CBEE1A9BBE7500C2FB4F /* ManualLayout.h */, 5F875C571A9BC8BF003CACDD /* Enums.swift */, - 5F67BC4B1A9FAB4B00347483 /* Operators.swift */, + 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */, 5F67BC4F1A9FDDD900347483 /* HelperFunctions.swift */, - 5F875C5E1A9BD55D003CACDD /* ManualLayout.swift */, - 5F875C681A9BE99F003CACDD /* CALayer+FastAccess.swift */, - 5F875C6E1A9BFE01003CACDD /* CALayer+ManualLayout.swift */, - 5F875C6C1A9BFC7E003CACDD /* UIView+FastAccess.swift */, - 5F875C5A1A9BCBB2003CACDD /* UIView+ManualLayout.swift */, + 5F875C681A9BE99F003CACDD /* CALayer+ManualLayout.swift */, + 5F875C6C1A9BFC7E003CACDD /* UIView+ManualLayout.swift */, 5F67BC3E1A9E970300347483 /* UIViewController+LayoutGuides.swift */, 5FB4CBEC1A9BBE7500C2FB4F /* Supporting Files */, ); @@ -123,11 +110,9 @@ 5FB4CBF81A9BBE7500C2FB4F /* ManualLayoutTests */ = { isa = PBXGroup; children = ( - 5F67BC4D1A9FB1A600347483 /* OperatorTests.swift */, + 5F67BC4D1A9FB1A600347483 /* SmartAssignTests.swift */, 5F67BC511A9FE35C00347483 /* HelperFunctionTests.swift */, - 5F67BC091A9D43FE00347483 /* FastAccessTests.swift */, - 5FB4CBFB1A9BBE7500C2FB4F /* ManualLayoutTests.swift */, - 5F875C641A9BE2D3003CACDD /* UIViewManualLayoutTests.swift */, + 5F67BC091A9D43FE00347483 /* ManualLayoutTests.swift */, 5FB4CBF91A9BBE7500C2FB4F /* Supporting Files */, ); path = ManualLayoutTests; @@ -248,15 +233,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5F875C691A9BE99F003CACDD /* CALayer+FastAccess.swift in Sources */, + 5F875C691A9BE99F003CACDD /* CALayer+ManualLayout.swift in Sources */, 5F67BC3F1A9E970300347483 /* UIViewController+LayoutGuides.swift in Sources */, 5F67BC501A9FDDD900347483 /* HelperFunctions.swift in Sources */, - 5F875C5F1A9BD55D003CACDD /* ManualLayout.swift in Sources */, - 5F875C5B1A9BCBB2003CACDD /* UIView+ManualLayout.swift in Sources */, - 5F875C6D1A9BFC7E003CACDD /* UIView+FastAccess.swift in Sources */, - 5F67BC4C1A9FAB4B00347483 /* Operators.swift in Sources */, + 5F875C6D1A9BFC7E003CACDD /* UIView+ManualLayout.swift in Sources */, + 5F67BC4C1A9FAB4B00347483 /* SmartAssign.swift in Sources */, 5F875C581A9BC8BF003CACDD /* Enums.swift in Sources */, - 5F875C6F1A9BFE01003CACDD /* CALayer+ManualLayout.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -265,10 +247,8 @@ buildActionMask = 2147483647; files = ( 5F67BC521A9FE35C00347483 /* HelperFunctionTests.swift in Sources */, - 5F875C651A9BE2D3003CACDD /* UIViewManualLayoutTests.swift in Sources */, - 5F67BC4E1A9FB1A600347483 /* OperatorTests.swift in Sources */, - 5F67BC0A1A9D43FE00347483 /* FastAccessTests.swift in Sources */, - 5FB4CBFC1A9BBE7500C2FB4F /* ManualLayoutTests.swift in Sources */, + 5F67BC4E1A9FB1A600347483 /* SmartAssignTests.swift in Sources */, + 5F67BC0A1A9D43FE00347483 /* ManualLayoutTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ManualLayout/CALayer+FastAccess.swift b/ManualLayout/CALayer+FastAccess.swift deleted file mode 100644 index 396fc36..0000000 --- a/ManualLayout/CALayer+FastAccess.swift +++ /dev/null @@ -1,207 +0,0 @@ -// -// CALayer+FastAccesors.swift -// ManualLayout -// -// Created by Baris Sencan on 23/02/15. -// Copyright (c) 2015 Baris Sencan. All rights reserved. -// - -import UIKit - -public extension CALayer { - - // MARK: - Position - - public var origin: CGPoint { - get { - return frame.origin - } - set { - x = newValue.x - y = newValue.y - } - } - - public var x: CGFloat { - get { - return frame.origin.x - } - set { - frame.origin.x = ManualLayout.snapToPixel(pointCoordinate: newValue) - } - } - - public var y: CGFloat { - get { - return frame.origin.y - } - set { - frame.origin.y = ManualLayout.snapToPixel(pointCoordinate: newValue) - } - } - - public var center: CGPoint { - get { - return CGPoint(x: centerX, y: centerY) - } - set { - centerX = newValue.x - centerY = newValue.y - } - } - - public var centerX: CGFloat { - get { - return frame.origin.x + frame.size.width / 2 - } - set { - x = newValue - frame.size.width / 2 - } - } - - public var centerY: CGFloat { - get { - return frame.origin.y + frame.size.height / 2 - } - set { - y = newValue - frame.size.height / 2 - } - } - - // MARK: - Size - - public var size: CGSize { - get { - return frame.size - } - set { - width = newValue.width - height = newValue.height - } - } - - public var width: CGFloat { - get { - return frame.size.width - } - set { - frame.size.width = ManualLayout.snapToPixel(pointCoordinate: newValue) - } - } - - public var height: CGFloat { - get { - return frame.size.height - } - set { - frame.size.height = ManualLayout.snapToPixel(pointCoordinate: newValue) - } - } - - // MARK: - Edges - - public var top: CGFloat { - get { - return frame.origin.y - } - set { - y = newValue - } - } - - public var right: CGFloat { - get { - return frame.origin.x + frame.size.width - } - set { - x = newValue - frame.size.width - } - } - - public var bottom: CGFloat { - get { - return frame.origin.y + frame.size.height - } - set { - y = newValue - frame.size.height - } - } - - public var left: CGFloat { - get { - return frame.origin.x - } - set { - x = newValue - } - } - - // MARK: - Alternative Edges - - public var top2: CGFloat { - get { - return frame.origin.y - } - set { - if newValue <= bottom { - height += top - newValue - y = newValue - } else { - // Swap top with bottom. - let newTop = bottom - height = newValue - newTop - y = newTop - } - } - } - - public var right2: CGFloat { - get { - return frame.origin.x + frame.size.width - } - set { - if newValue >= left { - width += newValue - right - } else { - // Swap left with right. - let newRight = left - width = newRight - newValue - x = newValue - } - } - } - - public var bottom2: CGFloat { - get { - return frame.origin.y + frame.size.height - } - set { - if newValue >= top { - height += newValue - bottom - } else { - // Swap bottom with top. - let newBottom = top - height = newBottom - newValue - y = newValue - } - } - } - - public var left2: CGFloat { - get { - return frame.origin.x - } - set { - if newValue <= right { - width += left - newValue - x = newValue - } else { - // Orange is the new black. - // let newBlack = orange - let newLeft = right - width = newValue - newLeft - x = newLeft - } - } - } -} \ No newline at end of file diff --git a/ManualLayout/CALayer+ManualLayout.swift b/ManualLayout/CALayer+ManualLayout.swift index 151b534..4a58da6 100644 --- a/ManualLayout/CALayer+ManualLayout.swift +++ b/ManualLayout/CALayer+ManualLayout.swift @@ -1,5 +1,5 @@ // -// CALayer+ManualLayout.swift +// CALayer+FastAccesors.swift // ManualLayout // // Created by Baris Sencan on 23/02/15. @@ -8,18 +8,205 @@ import UIKit +internal func snapToPixel(pointCoordinate coordinate: CGFloat) -> CGFloat { + let screenScale = UIScreen.mainScreen().scale + return round(coordinate * screenScale) / screenScale +} + public extension CALayer { - public func centerInSuperlayer() { - frame.origin = ManualLayout.getOriginForCenteringRect(bounds, inRect: superlayer.bounds) + // MARK: - Position + + public var origin: CGPoint { + get { + return frame.origin + } + set { + x = newValue.x + y = newValue.y + } } - public func centerDimensionInSuperlayer(dimension: ManualLayoutDimension) { - let position = ManualLayout.getPositionForCenteringRect(bounds, dimension: dimension, inRect: superlayer.bounds) - if dimension == .X { - frame.origin.x = position - } else { - frame.origin.y = position + public var x: CGFloat { + get { + return frame.origin.x + } + set { + frame.origin.x = snapToPixel(pointCoordinate: newValue) } } -} + + public var y: CGFloat { + get { + return frame.origin.y + } + set { + frame.origin.y = snapToPixel(pointCoordinate: newValue) + } + } + + public var center: CGPoint { + get { + return CGPoint(x: centerX, y: centerY) + } + set { + centerX = newValue.x + centerY = newValue.y + } + } + + public var centerX: CGFloat { + get { + return frame.origin.x + frame.size.width / 2 + } + set { + x = newValue - frame.size.width / 2 + } + } + + public var centerY: CGFloat { + get { + return frame.origin.y + frame.size.height / 2 + } + set { + y = newValue - frame.size.height / 2 + } + } + + // MARK: - Size + + public var size: CGSize { + get { + return frame.size + } + set { + width = newValue.width + height = newValue.height + } + } + + public var width: CGFloat { + get { + return frame.size.width + } + set { + frame.size.width = snapToPixel(pointCoordinate: newValue) + } + } + + public var height: CGFloat { + get { + return frame.size.height + } + set { + frame.size.height = snapToPixel(pointCoordinate: newValue) + } + } + + // MARK: - Edges + + public var top: CGFloat { + get { + return frame.origin.y + } + set { + y = newValue + } + } + + public var right: CGFloat { + get { + return frame.origin.x + frame.size.width + } + set { + x = newValue - frame.size.width + } + } + + public var bottom: CGFloat { + get { + return frame.origin.y + frame.size.height + } + set { + y = newValue - frame.size.height + } + } + + public var left: CGFloat { + get { + return frame.origin.x + } + set { + x = newValue + } + } + + // MARK: - Alternative Edges + + public var top2: CGFloat { + get { + return frame.origin.y + } + set { + if newValue <= bottom { + height += top - newValue + y = newValue + } else { + // Swap top with bottom. + let newTop = bottom + height = newValue - newTop + y = newTop + } + } + } + + public var right2: CGFloat { + get { + return frame.origin.x + frame.size.width + } + set { + if newValue >= left { + width += newValue - right + } else { + // Swap left with right. + let newRight = left + width = newRight - newValue + x = newValue + } + } + } + + public var bottom2: CGFloat { + get { + return frame.origin.y + frame.size.height + } + set { + if newValue >= top { + height += newValue - bottom + } else { + // Swap bottom with top. + let newBottom = top + height = newBottom - newValue + y = newValue + } + } + } + + public var left2: CGFloat { + get { + return frame.origin.x + } + set { + if newValue <= right { + width += left - newValue + x = newValue + } else { + // Orange is the new black. + // let newBlack = orange + let newLeft = right + width = newValue - newLeft + x = newLeft + } + } + } +} \ No newline at end of file diff --git a/ManualLayout/ManualLayout.swift b/ManualLayout/ManualLayout.swift deleted file mode 100644 index ddf61f8..0000000 --- a/ManualLayout/ManualLayout.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// Centering.swift -// ManualLayout -// -// Created by Baris Sencan on 23/02/15. -// Copyright (c) 2015 Baris Sencan. All rights reserved. -// - -import UIKit - -public struct ManualLayout { - - public static func snapToPixel(pointCoordinate coordinate: CGFloat) -> CGFloat { - let screenScale = UIScreen.mainScreen().scale - return round(coordinate * screenScale) / screenScale - } - - public static func getOriginForCenteringRect(rect: CGRect, inRect container: CGRect) -> CGPoint { - return CGPoint( - x: getPositionForCenteringRect(rect, dimension: .X, inRect: container), - y: getPositionForCenteringRect(rect, dimension: .Y, inRect: container)) - } - - public static func getPositionForCenteringRect(rect: CGRect, dimension: ManualLayoutDimension, inRect container: CGRect) -> CGFloat { - if dimension == .X { - return container.origin.x + (container.size.width - rect.size.width) / 2 - } else { - return container.origin.y + (container.size.height - rect.size.height) / 2 - } - } -} diff --git a/ManualLayout/Operators.swift b/ManualLayout/SmartAssign.swift similarity index 96% rename from ManualLayout/Operators.swift rename to ManualLayout/SmartAssign.swift index 77107a2..fb2ec5b 100644 --- a/ManualLayout/Operators.swift +++ b/ManualLayout/SmartAssign.swift @@ -1,5 +1,5 @@ // -// OperatorOverloads.swift +// SmartAssign.swift // ManualLayout // // Created by Baris Sencan on 26/02/15. diff --git a/ManualLayout/UIView+FastAccess.swift b/ManualLayout/UIView+FastAccess.swift deleted file mode 100644 index d470225..0000000 --- a/ManualLayout/UIView+FastAccess.swift +++ /dev/null @@ -1,101 +0,0 @@ -// -// UIView+FastAccess.swift -// ManualLayout -// -// Created by Baris Sencan on 23/02/15. -// Copyright (c) 2015 Baris Sencan. All rights reserved. -// - -import UIKit - -// I wish there was an easier way to do this in Swift. -public extension UIView { - - // MARK: - Position - - public var origin: CGPoint { - get { return layer.origin } - set { layer.origin = newValue } - } - - public var x: CGFloat { - get { return layer.x } - set { layer.x = newValue } - } - - public var y: CGFloat { - get { return layer.y } - set { layer.y = newValue } - } - - public var centerX: CGFloat { - get { return layer.centerX } - set { layer.centerX = newValue } - } - - public var centerY: CGFloat { - get { return layer.centerY } - set { layer.centerY = newValue } - } - - // MARK: - Size - - public var size: CGSize { - get { return layer.size } - set { layer.size = newValue } - } - - public var width: CGFloat { - get { return layer.width } - set { layer.width = newValue } - } - - public var height: CGFloat { - get { return layer.height } - set { layer.height = newValue } - } - - // MARK: - Edges - - public var top: CGFloat { - get { return layer.top } - set { layer.top = newValue } - } - - public var right: CGFloat { - get { return layer.right } - set { layer.right = newValue } - } - - public var bottom: CGFloat { - get { return layer.bottom } - set { layer.bottom = newValue } - } - - public var left: CGFloat { - get { return layer.left } - set { layer.left = newValue } - } - - // MARK: - Alternative Edges - - public var top2: CGFloat { - get { return layer.top2 } - set { layer.top2 = newValue } - } - - public var right2: CGFloat { - get { return layer.right2 } - set { layer.right2 = newValue } - } - - public var bottom2: CGFloat { - get { return layer.bottom2 } - set { layer.bottom2 = newValue } - } - - public var left2: CGFloat { - get { return layer.left2 } - set { layer.left2 = newValue } - } -} diff --git a/ManualLayout/UIView+ManualLayout.swift b/ManualLayout/UIView+ManualLayout.swift index 663c41e..d470225 100644 --- a/ManualLayout/UIView+ManualLayout.swift +++ b/ManualLayout/UIView+ManualLayout.swift @@ -1,5 +1,5 @@ // -// UIView+ManualLayout.swift +// UIView+FastAccess.swift // ManualLayout // // Created by Baris Sencan on 23/02/15. @@ -8,8 +8,94 @@ import UIKit -// Proxy CALayer+ManualLayout methods for UIView. +// I wish there was an easier way to do this in Swift. public extension UIView { - public func centerInSuperview() { layer.centerInSuperlayer() } - public func centerDimensionInSuperview(dimension: ManualLayoutDimension) { layer.centerDimensionInSuperlayer(dimension) } + + // MARK: - Position + + public var origin: CGPoint { + get { return layer.origin } + set { layer.origin = newValue } + } + + public var x: CGFloat { + get { return layer.x } + set { layer.x = newValue } + } + + public var y: CGFloat { + get { return layer.y } + set { layer.y = newValue } + } + + public var centerX: CGFloat { + get { return layer.centerX } + set { layer.centerX = newValue } + } + + public var centerY: CGFloat { + get { return layer.centerY } + set { layer.centerY = newValue } + } + + // MARK: - Size + + public var size: CGSize { + get { return layer.size } + set { layer.size = newValue } + } + + public var width: CGFloat { + get { return layer.width } + set { layer.width = newValue } + } + + public var height: CGFloat { + get { return layer.height } + set { layer.height = newValue } + } + + // MARK: - Edges + + public var top: CGFloat { + get { return layer.top } + set { layer.top = newValue } + } + + public var right: CGFloat { + get { return layer.right } + set { layer.right = newValue } + } + + public var bottom: CGFloat { + get { return layer.bottom } + set { layer.bottom = newValue } + } + + public var left: CGFloat { + get { return layer.left } + set { layer.left = newValue } + } + + // MARK: - Alternative Edges + + public var top2: CGFloat { + get { return layer.top2 } + set { layer.top2 = newValue } + } + + public var right2: CGFloat { + get { return layer.right2 } + set { layer.right2 = newValue } + } + + public var bottom2: CGFloat { + get { return layer.bottom2 } + set { layer.bottom2 = newValue } + } + + public var left2: CGFloat { + get { return layer.left2 } + set { layer.left2 = newValue } + } } diff --git a/ManualLayoutTests/FastAccessTests.swift b/ManualLayoutTests/FastAccessTests.swift deleted file mode 100644 index 520abd3..0000000 --- a/ManualLayoutTests/FastAccessTests.swift +++ /dev/null @@ -1,229 +0,0 @@ -// -// FastAccessTests.swift -// ManualLayout -// -// Created by Baris Sencan on 24/02/15. -// Copyright (c) 2015 Baris Sencan. All rights reserved. -// - -import UIKit -import XCTest -import ManualLayout - -class FastAccessTests: XCTestCase { - let view = UIView(frame: CGRectZero) - let defaultFrame = CGRect(x: 1, y: 3, width: 6, height: 8) - - override func setUp() { - view.frame = defaultFrame - } - - func testOrigin() { - let newOrigin = CGPoint(x: 10, y: 10) - view.origin = newOrigin - XCTAssertEqual( - view.frame.origin, - newOrigin, - "origin changes should modify frame origin") - XCTAssertEqual( - view.frame.size, - defaultFrame.size, - "origin changes should not modify frame size") - } - - func testX() { - view.x = 10 - XCTAssertEqual( - view.frame.origin, - CGPoint(x: 10, y: defaultFrame.origin.y), - "x changes should just modify frame x") - XCTAssertEqual( - view.frame.size, - defaultFrame.size, - "x changes should not modify frame size") - } - - func testY() { - view.y = 10 - XCTAssertEqual( - view.frame.origin, - CGPoint(x: defaultFrame.origin.x, y: 10), - "y changes should just modify frame y") - XCTAssertEqual( - view.frame.size, - defaultFrame.size, - "y changes should not modify frame size") - } - - func testCenter() { - view.layer.center = CGPoint(x: 10, y: 10) - XCTAssertEqual( - view.frame.origin, - CGPoint(x: 7, y: 6), - "center changes should center frame") - XCTAssertEqual( - view.frame.size, - defaultFrame.size, - "center changes should not modify frame size") - } - - func testCenterX() { - view.centerX = 10 - XCTAssertEqual( - view.frame.origin, - CGPoint(x: 7, y: defaultFrame.origin.y), - "centerX changes should center frame") - XCTAssertEqual( - view.frame.size, - defaultFrame.size, - "centerX changes should not modify frame size") - } - - func testCenterY() { - view.centerY = 10 - XCTAssertEqual( - view.frame.origin, - CGPoint(x: defaultFrame.origin.x, y: 6), - "centerY changes should center frame") - XCTAssertEqual( - view.frame.size, - defaultFrame.size, - "centerY changes should not modify frame size") - } - - func testSize() { - view.size = CGSizeZero - XCTAssertEqual( - view.frame.origin, - defaultFrame.origin, - "size changes should not modify frame origin") - XCTAssertEqual( - view.frame.size, - CGSizeZero, - "size changes should modify frame size") - } - - func testWidth() { - view.width = 10 - XCTAssertEqual( - view.frame.origin, - defaultFrame.origin, - "width changes should not modify frame origin") - XCTAssertEqual( - view.frame.size, - CGSize(width: 10, height: defaultFrame.size.height), - "width changes should just modify frame width") - } - - func testHeight() { - view.height = 10 - XCTAssertEqual( - view.frame.origin, - defaultFrame.origin, - "height changes should not modify frame origin") - XCTAssertEqual( - view.frame.size, - CGSize(width: defaultFrame.size.width, height: 10), - "height changes should just modify frame height") - } - - func testTop() { - view.top = 10 - XCTAssertEqual( - view.frame.origin, - CGPoint(x: defaultFrame.origin.x, y: 10), - "top changes should just modify frame y") - XCTAssertEqual( - view.frame.size, - defaultFrame.size, - "top changes should not modify frame size") - } - - func testRight() { - view.right = 10 - XCTAssertEqual( - view.frame.origin, - CGPoint(x: 10 - defaultFrame.size.width, y: defaultFrame.origin.y), - "right changes should just modify frame x") - XCTAssertEqual( - view.frame.size, - defaultFrame.size, - "right changes should not modify frame size") - } - - func testBottom() { - view.bottom = 10 - XCTAssertEqual( - view.frame.origin, - CGPoint(x: defaultFrame.origin.x, y: 10 - defaultFrame.size.height), - "bottom changes should just modify frame y") - XCTAssertEqual( - view.frame.size, - defaultFrame.size, - "bottom changes should not modify frame size") - } - - func testLeft() { - view.left = 10 - XCTAssertEqual( - view.frame.origin, - CGPoint(x: 10, y: defaultFrame.origin.y), - "left changes should just modify frame x") - XCTAssertEqual( - view.frame.size, - defaultFrame.size, - "left changes should not modify frame size") - } - - func testTop2() { - view.top2 = 5 - XCTAssertEqual( - view.frame.origin, - CGPoint(x: defaultFrame.origin.x, y: 5), - "top2 changes without a swap should just modify frame y") - XCTAssertEqual( - view.frame.size, - CGSize(width: defaultFrame.size.width, height: 6), - "top2 changes without a swap should modify frame size") - // TODO: Test swap behavior. - } - - func testRight2() { - view.right2 = 5 - XCTAssertEqual( - view.frame.origin, - defaultFrame.origin, - "right2 changes without a swap should not modify frame origin") - XCTAssertEqual( - view.frame.size, - CGSize(width: 4, height: defaultFrame.size.height), - "right2 changes without a swap should modify frame size") - // TODO: Test swap behavior. - } - - func testBottom2() { - view.bottom2 = 5 - XCTAssertEqual( - view.frame.origin, - defaultFrame.origin, - "bottom2 changes without a swap should not modify frame origin") - XCTAssertEqual( - view.frame.size, - CGSize(width: defaultFrame.size.width, height: 2), - "bottom2 changes without a swap should modify frame size") - // TODO: Test swap behavior. - } - - func testLeft2() { - view.left2 = 5 - XCTAssertEqual( - view.frame.origin, - CGPoint(x: 5, y: defaultFrame.origin.y), - "left2 changes without a swap should just modify frame x") - XCTAssertEqual( - view.frame.size, - CGSize(width: 2, height: defaultFrame.size.height), - "left2 changes without a swap should modify frame size") - // TODO: Test swap behavior. - } -} \ No newline at end of file diff --git a/ManualLayoutTests/ManualLayoutTests.swift b/ManualLayoutTests/ManualLayoutTests.swift index 827fa15..9c9c509 100644 --- a/ManualLayoutTests/ManualLayoutTests.swift +++ b/ManualLayoutTests/ManualLayoutTests.swift @@ -1,8 +1,8 @@ // // ManualLayoutTests.swift -// ManualLayoutTests +// ManualLayout // -// Created by Baris Sencan on 23/02/15. +// Created by Baris Sencan on 24/02/15. // Copyright (c) 2015 Baris Sencan. All rights reserved. // @@ -10,19 +10,220 @@ import UIKit import XCTest import ManualLayout -internal class ManualLayoutTests: XCTestCase { - let otherRect = CGRect(x: 10, y: 20, width: 100, height: 100) - let rect = CGRect(x: 0, y: 0, width: 10, height: 10) +class ManualLayoutTests: XCTestCase { + let view = UIView(frame: CGRectZero) + let defaultFrame = CGRect(x: 1, y: 3, width: 6, height: 8) - func testGetOriginForCenteringRect() { - let o = ManualLayout.getOriginForCenteringRect(rect, inRect: otherRect) - XCTAssertEqual(o, CGPoint(x: 55, y: 65), "o should equal center point") + override func setUp() { + view.frame = defaultFrame } - func testGetPositionForCenteringRect() { - let x = ManualLayout.getPositionForCenteringRect(rect, dimension: .X, inRect: otherRect) - XCTAssert(x == 55, "x should be in center") - let y = ManualLayout.getPositionForCenteringRect(rect, dimension: .Y, inRect: otherRect) - XCTAssert(y == 65, "y should be in center") + func testOrigin() { + let newOrigin = CGPoint(x: 10, y: 10) + view.origin = newOrigin + XCTAssertEqual( + view.frame.origin, + newOrigin, + "origin changes should modify frame origin") + XCTAssertEqual( + view.frame.size, + defaultFrame.size, + "origin changes should not modify frame size") } -} + + func testX() { + view.x = 10 + XCTAssertEqual( + view.frame.origin, + CGPoint(x: 10, y: defaultFrame.origin.y), + "x changes should just modify frame x") + XCTAssertEqual( + view.frame.size, + defaultFrame.size, + "x changes should not modify frame size") + } + + func testY() { + view.y = 10 + XCTAssertEqual( + view.frame.origin, + CGPoint(x: defaultFrame.origin.x, y: 10), + "y changes should just modify frame y") + XCTAssertEqual( + view.frame.size, + defaultFrame.size, + "y changes should not modify frame size") + } + + func testCenter() { + view.layer.center = CGPoint(x: 10, y: 10) + XCTAssertEqual( + view.frame.origin, + CGPoint(x: 7, y: 6), + "center changes should center frame") + XCTAssertEqual( + view.frame.size, + defaultFrame.size, + "center changes should not modify frame size") + } + + func testCenterX() { + view.centerX = 10 + XCTAssertEqual( + view.frame.origin, + CGPoint(x: 7, y: defaultFrame.origin.y), + "centerX changes should center frame") + XCTAssertEqual( + view.frame.size, + defaultFrame.size, + "centerX changes should not modify frame size") + } + + func testCenterY() { + view.centerY = 10 + XCTAssertEqual( + view.frame.origin, + CGPoint(x: defaultFrame.origin.x, y: 6), + "centerY changes should center frame") + XCTAssertEqual( + view.frame.size, + defaultFrame.size, + "centerY changes should not modify frame size") + } + + func testSize() { + view.size = CGSizeZero + XCTAssertEqual( + view.frame.origin, + defaultFrame.origin, + "size changes should not modify frame origin") + XCTAssertEqual( + view.frame.size, + CGSizeZero, + "size changes should modify frame size") + } + + func testWidth() { + view.width = 10 + XCTAssertEqual( + view.frame.origin, + defaultFrame.origin, + "width changes should not modify frame origin") + XCTAssertEqual( + view.frame.size, + CGSize(width: 10, height: defaultFrame.size.height), + "width changes should just modify frame width") + } + + func testHeight() { + view.height = 10 + XCTAssertEqual( + view.frame.origin, + defaultFrame.origin, + "height changes should not modify frame origin") + XCTAssertEqual( + view.frame.size, + CGSize(width: defaultFrame.size.width, height: 10), + "height changes should just modify frame height") + } + + func testTop() { + view.top = 10 + XCTAssertEqual( + view.frame.origin, + CGPoint(x: defaultFrame.origin.x, y: 10), + "top changes should just modify frame y") + XCTAssertEqual( + view.frame.size, + defaultFrame.size, + "top changes should not modify frame size") + } + + func testRight() { + view.right = 10 + XCTAssertEqual( + view.frame.origin, + CGPoint(x: 10 - defaultFrame.size.width, y: defaultFrame.origin.y), + "right changes should just modify frame x") + XCTAssertEqual( + view.frame.size, + defaultFrame.size, + "right changes should not modify frame size") + } + + func testBottom() { + view.bottom = 10 + XCTAssertEqual( + view.frame.origin, + CGPoint(x: defaultFrame.origin.x, y: 10 - defaultFrame.size.height), + "bottom changes should just modify frame y") + XCTAssertEqual( + view.frame.size, + defaultFrame.size, + "bottom changes should not modify frame size") + } + + func testLeft() { + view.left = 10 + XCTAssertEqual( + view.frame.origin, + CGPoint(x: 10, y: defaultFrame.origin.y), + "left changes should just modify frame x") + XCTAssertEqual( + view.frame.size, + defaultFrame.size, + "left changes should not modify frame size") + } + + func testTop2() { + view.top2 = 5 + XCTAssertEqual( + view.frame.origin, + CGPoint(x: defaultFrame.origin.x, y: 5), + "top2 changes without a swap should just modify frame y") + XCTAssertEqual( + view.frame.size, + CGSize(width: defaultFrame.size.width, height: 6), + "top2 changes without a swap should modify frame size") + // TODO: Test swap behavior. + } + + func testRight2() { + view.right2 = 5 + XCTAssertEqual( + view.frame.origin, + defaultFrame.origin, + "right2 changes without a swap should not modify frame origin") + XCTAssertEqual( + view.frame.size, + CGSize(width: 4, height: defaultFrame.size.height), + "right2 changes without a swap should modify frame size") + // TODO: Test swap behavior. + } + + func testBottom2() { + view.bottom2 = 5 + XCTAssertEqual( + view.frame.origin, + defaultFrame.origin, + "bottom2 changes without a swap should not modify frame origin") + XCTAssertEqual( + view.frame.size, + CGSize(width: defaultFrame.size.width, height: 2), + "bottom2 changes without a swap should modify frame size") + // TODO: Test swap behavior. + } + + func testLeft2() { + view.left2 = 5 + XCTAssertEqual( + view.frame.origin, + CGPoint(x: 5, y: defaultFrame.origin.y), + "left2 changes without a swap should just modify frame x") + XCTAssertEqual( + view.frame.size, + CGSize(width: 2, height: defaultFrame.size.height), + "left2 changes without a swap should modify frame size") + // TODO: Test swap behavior. + } +} \ No newline at end of file diff --git a/ManualLayoutTests/OperatorTests.swift b/ManualLayoutTests/SmartAssignTests.swift similarity index 92% rename from ManualLayoutTests/OperatorTests.swift rename to ManualLayoutTests/SmartAssignTests.swift index 6a2a418..fe8b875 100644 --- a/ManualLayoutTests/OperatorTests.swift +++ b/ManualLayoutTests/SmartAssignTests.swift @@ -1,5 +1,5 @@ // -// OperatorTests.swift +// SmartAssignTests.swift // ManualLayout // // Created by Baris Sencan on 26/02/15. @@ -10,7 +10,7 @@ import Foundation import XCTest import ManualLayout -class OperatorTests: XCTestCase { +class SmartAssignTests: XCTestCase { var view = UIView(frame: CGRectZero) override func setUp() { diff --git a/ManualLayoutTests/UIViewManualLayoutTests.swift b/ManualLayoutTests/UIViewManualLayoutTests.swift deleted file mode 100644 index f3606b2..0000000 --- a/ManualLayoutTests/UIViewManualLayoutTests.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// UIViewManualLayoutTests.swift -// ManualLayout -// -// Created by Baris Sencan on 23/02/15. -// Copyright (c) 2015 Baris Sencan. All rights reserved. -// - -import UIKit -import XCTest -import ManualLayout - -class UIViewManualLayoutTests: XCTestCase { - let containerView = UIView(frame: CGRectZero) - let view = UIView(frame: CGRectZero) - - override func setUp() { - containerView.frame = CGRect(x: 0, y: 0, width: 100, height: 100) - containerView.addSubview(view) - view.frame = CGRect(x: 0, y: 0, width: 10, height: 10) - } - - override func tearDown() { - view.removeFromSuperview() - } - - func testCenterInSuperview() { - view.centerInSuperview() - XCTAssertEqual(view.center, containerView.center, "centers must be equal") - } - - func testCenterDimensionInSuperview() { - view.centerDimensionInSuperview(.X) - XCTAssertEqual(view.center.x, containerView.center.x, "centers must be aligned on x axis") - view.centerDimensionInSuperview(.Y) - XCTAssertEqual(view.center.y, containerView.center.y, "centers must be aligned on y axis") - } -} From d82aded66b7ccc72a74d1077a958b6f25ddc904e Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Thu, 5 Mar 2015 15:30:28 -0800 Subject: [PATCH 02/18] Ease UIView sizing --- ManualLayout/UIView+ManualLayout.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ManualLayout/UIView+ManualLayout.swift b/ManualLayout/UIView+ManualLayout.swift index d470225..a6ec38c 100644 --- a/ManualLayout/UIView+ManualLayout.swift +++ b/ManualLayout/UIView+ManualLayout.swift @@ -98,4 +98,16 @@ public extension UIView { get { return layer.left2 } set { layer.left2 = newValue } } + + // MARK: - Automatic Sizing + + public func sizeToFit(constrainedSizeTuple: (CGFloat, CGFloat)) { + sizeToFit(CGSize( + width: constrainedSizeTuple.0, + height: constrainedSizeTuple.1)) + } + + public func sizeToFit(constrainedSize: CGSize) { + size = sizeThatFits(constrainedSize) + } } From bd54d5b464bb0bfc56a8a9607e904c9b6f67c39e Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Thu, 5 Mar 2015 15:39:37 -0800 Subject: [PATCH 03/18] Add center and size properties to controllers --- ManualLayout.xcodeproj/project.pbxproj | 8 +-- .../UIViewController+LayoutGuides.swift | 28 --------- .../UIViewController+ManualLayout.swift | 58 +++++++++++++++++++ 3 files changed, 62 insertions(+), 32 deletions(-) delete mode 100644 ManualLayout/UIViewController+LayoutGuides.swift create mode 100644 ManualLayout/UIViewController+ManualLayout.swift diff --git a/ManualLayout.xcodeproj/project.pbxproj b/ManualLayout.xcodeproj/project.pbxproj index d7d5439..032c2ce 100644 --- a/ManualLayout.xcodeproj/project.pbxproj +++ b/ManualLayout.xcodeproj/project.pbxproj @@ -8,7 +8,7 @@ /* Begin PBXBuildFile section */ 5F67BC0A1A9D43FE00347483 /* ManualLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC091A9D43FE00347483 /* ManualLayoutTests.swift */; }; - 5F67BC3F1A9E970300347483 /* UIViewController+LayoutGuides.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC3E1A9E970300347483 /* UIViewController+LayoutGuides.swift */; }; + 5F67BC3F1A9E970300347483 /* UIViewController+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC3E1A9E970300347483 /* UIViewController+ManualLayout.swift */; }; 5F67BC4C1A9FAB4B00347483 /* SmartAssign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */; }; 5F67BC4E1A9FB1A600347483 /* SmartAssignTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4D1A9FB1A600347483 /* SmartAssignTests.swift */; }; 5F67BC501A9FDDD900347483 /* HelperFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4F1A9FDDD900347483 /* HelperFunctions.swift */; }; @@ -32,7 +32,7 @@ /* Begin PBXFileReference section */ 5F67BC091A9D43FE00347483 /* ManualLayoutTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManualLayoutTests.swift; sourceTree = ""; }; - 5F67BC3E1A9E970300347483 /* UIViewController+LayoutGuides.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+LayoutGuides.swift"; sourceTree = ""; }; + 5F67BC3E1A9E970300347483 /* UIViewController+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+ManualLayout.swift"; sourceTree = ""; }; 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartAssign.swift; sourceTree = ""; }; 5F67BC4D1A9FB1A600347483 /* SmartAssignTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartAssignTests.swift; sourceTree = ""; }; 5F67BC4F1A9FDDD900347483 /* HelperFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HelperFunctions.swift; sourceTree = ""; }; @@ -93,7 +93,7 @@ 5F67BC4F1A9FDDD900347483 /* HelperFunctions.swift */, 5F875C681A9BE99F003CACDD /* CALayer+ManualLayout.swift */, 5F875C6C1A9BFC7E003CACDD /* UIView+ManualLayout.swift */, - 5F67BC3E1A9E970300347483 /* UIViewController+LayoutGuides.swift */, + 5F67BC3E1A9E970300347483 /* UIViewController+ManualLayout.swift */, 5FB4CBEC1A9BBE7500C2FB4F /* Supporting Files */, ); path = ManualLayout; @@ -234,7 +234,7 @@ buildActionMask = 2147483647; files = ( 5F875C691A9BE99F003CACDD /* CALayer+ManualLayout.swift in Sources */, - 5F67BC3F1A9E970300347483 /* UIViewController+LayoutGuides.swift in Sources */, + 5F67BC3F1A9E970300347483 /* UIViewController+ManualLayout.swift in Sources */, 5F67BC501A9FDDD900347483 /* HelperFunctions.swift in Sources */, 5F875C6D1A9BFC7E003CACDD /* UIView+ManualLayout.swift in Sources */, 5F67BC4C1A9FAB4B00347483 /* SmartAssign.swift in Sources */, diff --git a/ManualLayout/UIViewController+LayoutGuides.swift b/ManualLayout/UIViewController+LayoutGuides.swift deleted file mode 100644 index 128e4f9..0000000 --- a/ManualLayout/UIViewController+LayoutGuides.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// UIViewController+LayoutGuides.swift -// ManualLayout -// -// Created by Baris Sencan on 25/02/15. -// Copyright (c) 2015 Baris Sencan. All rights reserved. -// - -import UIKit - -public extension UIViewController { - - public var top: CGFloat { - return topLayoutGuide.length - } - - public var right: CGFloat { // For convenience. - return view.width - } - - public var bottom: CGFloat { - return view.height - bottomLayoutGuide.length - } - - public var left: CGFloat { // For convenience. - return 0 - } -} diff --git a/ManualLayout/UIViewController+ManualLayout.swift b/ManualLayout/UIViewController+ManualLayout.swift new file mode 100644 index 0000000..1c7e652 --- /dev/null +++ b/ManualLayout/UIViewController+ManualLayout.swift @@ -0,0 +1,58 @@ +// +// UIViewController+ManualLayout.swift +// ManualLayout +// +// Created by Baris Sencan on 25/02/15. +// Copyright (c) 2015 Baris Sencan. All rights reserved. +// + +import UIKit + +public extension UIViewController { + + // MARK: - Center + + public var center: CGPoint { + return view.center + } + + public var centerX: CGFloat { + return view.centerX + } + + public var centerY: CGFloat { + return view.centerY + } + + // MARK: - Size + + public var size: CGSize { + return view.size + } + + public var width: CGFloat { + return view.width + } + + public var height: CGFloat { + return view.height + } + + // MARK: - Edges + + public var top: CGFloat { + return topLayoutGuide.length + } + + public var right: CGFloat { + return view.width + } + + public var bottom: CGFloat { + return view.height - bottomLayoutGuide.length + } + + public var left: CGFloat { + return 0 + } +} From f4c5d345e9988b490a142f10b9b8ae0ccbd743f2 Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Thu, 5 Mar 2015 15:40:31 -0800 Subject: [PATCH 04/18] Minor naming related changes --- ManualLayout.xcodeproj/project.pbxproj | 8 ++++---- ManualLayout/CALayer+ManualLayout.swift | 2 +- ManualLayout/HelperFunctions.swift | 2 +- ManualLayout/UIView+ManualLayout.swift | 2 +- ...ualLayoutTests.swift => UIViewManualLayoutTests.swift} | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) rename ManualLayoutTests/{ManualLayoutTests.swift => UIViewManualLayoutTests.swift} (98%) diff --git a/ManualLayout.xcodeproj/project.pbxproj b/ManualLayout.xcodeproj/project.pbxproj index 032c2ce..dedac2c 100644 --- a/ManualLayout.xcodeproj/project.pbxproj +++ b/ManualLayout.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 5F67BC0A1A9D43FE00347483 /* ManualLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC091A9D43FE00347483 /* ManualLayoutTests.swift */; }; + 5F67BC0A1A9D43FE00347483 /* UIViewManualLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC091A9D43FE00347483 /* UIViewManualLayoutTests.swift */; }; 5F67BC3F1A9E970300347483 /* UIViewController+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC3E1A9E970300347483 /* UIViewController+ManualLayout.swift */; }; 5F67BC4C1A9FAB4B00347483 /* SmartAssign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */; }; 5F67BC4E1A9FB1A600347483 /* SmartAssignTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4D1A9FB1A600347483 /* SmartAssignTests.swift */; }; @@ -31,7 +31,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 5F67BC091A9D43FE00347483 /* ManualLayoutTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManualLayoutTests.swift; sourceTree = ""; }; + 5F67BC091A9D43FE00347483 /* UIViewManualLayoutTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewManualLayoutTests.swift; sourceTree = ""; }; 5F67BC3E1A9E970300347483 /* UIViewController+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+ManualLayout.swift"; sourceTree = ""; }; 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartAssign.swift; sourceTree = ""; }; 5F67BC4D1A9FB1A600347483 /* SmartAssignTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartAssignTests.swift; sourceTree = ""; }; @@ -112,7 +112,7 @@ children = ( 5F67BC4D1A9FB1A600347483 /* SmartAssignTests.swift */, 5F67BC511A9FE35C00347483 /* HelperFunctionTests.swift */, - 5F67BC091A9D43FE00347483 /* ManualLayoutTests.swift */, + 5F67BC091A9D43FE00347483 /* UIViewManualLayoutTests.swift */, 5FB4CBF91A9BBE7500C2FB4F /* Supporting Files */, ); path = ManualLayoutTests; @@ -248,7 +248,7 @@ files = ( 5F67BC521A9FE35C00347483 /* HelperFunctionTests.swift in Sources */, 5F67BC4E1A9FB1A600347483 /* SmartAssignTests.swift in Sources */, - 5F67BC0A1A9D43FE00347483 /* ManualLayoutTests.swift in Sources */, + 5F67BC0A1A9D43FE00347483 /* UIViewManualLayoutTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ManualLayout/CALayer+ManualLayout.swift b/ManualLayout/CALayer+ManualLayout.swift index 4a58da6..be94772 100644 --- a/ManualLayout/CALayer+ManualLayout.swift +++ b/ManualLayout/CALayer+ManualLayout.swift @@ -1,5 +1,5 @@ // -// CALayer+FastAccesors.swift +// CALayer+ManualLayout.swift // ManualLayout // // Created by Baris Sencan on 23/02/15. diff --git a/ManualLayout/HelperFunctions.swift b/ManualLayout/HelperFunctions.swift index 0a92e89..e8cac0a 100644 --- a/ManualLayout/HelperFunctions.swift +++ b/ManualLayout/HelperFunctions.swift @@ -1,5 +1,5 @@ // -// Functions.swift +// HelperFunctions.swift // ManualLayout // // Created by Baris Sencan on 26/02/15. diff --git a/ManualLayout/UIView+ManualLayout.swift b/ManualLayout/UIView+ManualLayout.swift index a6ec38c..ef68759 100644 --- a/ManualLayout/UIView+ManualLayout.swift +++ b/ManualLayout/UIView+ManualLayout.swift @@ -1,5 +1,5 @@ // -// UIView+FastAccess.swift +// UIView+ManualLayout.swift // ManualLayout // // Created by Baris Sencan on 23/02/15. diff --git a/ManualLayoutTests/ManualLayoutTests.swift b/ManualLayoutTests/UIViewManualLayoutTests.swift similarity index 98% rename from ManualLayoutTests/ManualLayoutTests.swift rename to ManualLayoutTests/UIViewManualLayoutTests.swift index 9c9c509..c1af0cc 100644 --- a/ManualLayoutTests/ManualLayoutTests.swift +++ b/ManualLayoutTests/UIViewManualLayoutTests.swift @@ -1,5 +1,5 @@ // -// ManualLayoutTests.swift +// UIViewManualLayoutTests.swift // ManualLayout // // Created by Baris Sencan on 24/02/15. @@ -10,7 +10,7 @@ import UIKit import XCTest import ManualLayout -class ManualLayoutTests: XCTestCase { +class UIViewManualLayoutTests: XCTestCase { let view = UIView(frame: CGRectZero) let defaultFrame = CGRect(x: 1, y: 3, width: 6, height: 8) From f113e9e045ea988406d6d73b3da2ba902ef299be Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Thu, 5 Mar 2015 15:48:53 -0800 Subject: [PATCH 05/18] Support insetting sizes --- ManualLayout/HelperFunctions.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ManualLayout/HelperFunctions.swift b/ManualLayout/HelperFunctions.swift index e8cac0a..fa698ad 100644 --- a/ManualLayout/HelperFunctions.swift +++ b/ManualLayout/HelperFunctions.swift @@ -50,6 +50,20 @@ public func inset(rect: CGRect, top: CGFloat, left: CGFloat, bottom: CGFloat, ri height: rect.size.height - top - bottom) } +public func inset(size: CGSize, amount: CGFloat) -> CGSize { + return inset(size, amount, amount) +} + +public func inset(size: CGSize, dx: CGFloat, dy: CGFloat) -> CGSize { + return inset(size, dy, dx, dy, dx) +} + +public func inset(size: CGSize, top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> CGSize { + return CGSize( + width: size.width - left - right, + height: size.height - top - bottom) +} + // MARK: - Offsetting public func offset(view: UIView, amount: CGFloat) -> CGRect { From 505da77381332f2235c392a9e28428c4daf39d2e Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Thu, 5 Mar 2015 15:52:01 -0800 Subject: [PATCH 06/18] Remove enums They are no longer used. --- ManualLayout.xcodeproj/project.pbxproj | 4 ---- ManualLayout/Enums.swift | 15 --------------- 2 files changed, 19 deletions(-) delete mode 100644 ManualLayout/Enums.swift diff --git a/ManualLayout.xcodeproj/project.pbxproj b/ManualLayout.xcodeproj/project.pbxproj index dedac2c..ef20921 100644 --- a/ManualLayout.xcodeproj/project.pbxproj +++ b/ManualLayout.xcodeproj/project.pbxproj @@ -13,7 +13,6 @@ 5F67BC4E1A9FB1A600347483 /* SmartAssignTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4D1A9FB1A600347483 /* SmartAssignTests.swift */; }; 5F67BC501A9FDDD900347483 /* HelperFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4F1A9FDDD900347483 /* HelperFunctions.swift */; }; 5F67BC521A9FE35C00347483 /* HelperFunctionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC511A9FE35C00347483 /* HelperFunctionTests.swift */; }; - 5F875C581A9BC8BF003CACDD /* Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C571A9BC8BF003CACDD /* Enums.swift */; }; 5F875C691A9BE99F003CACDD /* CALayer+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C681A9BE99F003CACDD /* CALayer+ManualLayout.swift */; }; 5F875C6D1A9BFC7E003CACDD /* UIView+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F875C6C1A9BFC7E003CACDD /* UIView+ManualLayout.swift */; }; 5FB4CBEF1A9BBE7500C2FB4F /* ManualLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FB4CBEE1A9BBE7500C2FB4F /* ManualLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -37,7 +36,6 @@ 5F67BC4D1A9FB1A600347483 /* SmartAssignTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartAssignTests.swift; sourceTree = ""; }; 5F67BC4F1A9FDDD900347483 /* HelperFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HelperFunctions.swift; sourceTree = ""; }; 5F67BC511A9FE35C00347483 /* HelperFunctionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HelperFunctionTests.swift; sourceTree = ""; }; - 5F875C571A9BC8BF003CACDD /* Enums.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Enums.swift; sourceTree = ""; }; 5F875C681A9BE99F003CACDD /* CALayer+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CALayer+ManualLayout.swift"; sourceTree = ""; }; 5F875C6C1A9BFC7E003CACDD /* UIView+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+ManualLayout.swift"; sourceTree = ""; }; 5FB4CBE91A9BBE7500C2FB4F /* ManualLayout.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ManualLayout.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -88,7 +86,6 @@ isa = PBXGroup; children = ( 5FB4CBEE1A9BBE7500C2FB4F /* ManualLayout.h */, - 5F875C571A9BC8BF003CACDD /* Enums.swift */, 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */, 5F67BC4F1A9FDDD900347483 /* HelperFunctions.swift */, 5F875C681A9BE99F003CACDD /* CALayer+ManualLayout.swift */, @@ -238,7 +235,6 @@ 5F67BC501A9FDDD900347483 /* HelperFunctions.swift in Sources */, 5F875C6D1A9BFC7E003CACDD /* UIView+ManualLayout.swift in Sources */, 5F67BC4C1A9FAB4B00347483 /* SmartAssign.swift in Sources */, - 5F875C581A9BC8BF003CACDD /* Enums.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ManualLayout/Enums.swift b/ManualLayout/Enums.swift deleted file mode 100644 index ed5e686..0000000 --- a/ManualLayout/Enums.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// Enums.swift -// ManualLayout -// -// Created by Baris Sencan on 23/02/15. -// Copyright (c) 2015 Baris Sencan. All rights reserved. -// - -public enum ManualLayoutDimension { - case X, Y -} - -public enum ManualLayoutEdge { - case Top, Right, Bottom, Left -} From 754932c70df7a3e5949a658342908c733e2216c0 Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Thu, 5 Mar 2015 15:55:11 -0800 Subject: [PATCH 07/18] Move snapToPixel function It is more appropriate to place it in HelperFunctions.swift --- ManualLayout/CALayer+ManualLayout.swift | 5 ----- ManualLayout/HelperFunctions.swift | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ManualLayout/CALayer+ManualLayout.swift b/ManualLayout/CALayer+ManualLayout.swift index be94772..47fe2a0 100644 --- a/ManualLayout/CALayer+ManualLayout.swift +++ b/ManualLayout/CALayer+ManualLayout.swift @@ -8,11 +8,6 @@ import UIKit -internal func snapToPixel(pointCoordinate coordinate: CGFloat) -> CGFloat { - let screenScale = UIScreen.mainScreen().scale - return round(coordinate * screenScale) / screenScale -} - public extension CALayer { // MARK: - Position diff --git a/ManualLayout/HelperFunctions.swift b/ManualLayout/HelperFunctions.swift index fa698ad..244e492 100644 --- a/ManualLayout/HelperFunctions.swift +++ b/ManualLayout/HelperFunctions.swift @@ -8,6 +8,11 @@ import UIKit +internal func snapToPixel(pointCoordinate coordinate: CGFloat) -> CGFloat { + let screenScale = UIScreen.mainScreen().scale + return round(coordinate * screenScale) / screenScale +} + //MARK: - Insetting public func inset(view: UIView, amount: CGFloat) -> CGRect { From 4aabcef7393bd0dca1dd884533c94b4efdff8584 Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Fri, 6 Mar 2015 11:49:06 -0800 Subject: [PATCH 08/18] Support offsetting points --- ManualLayout/HelperFunctions.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ManualLayout/HelperFunctions.swift b/ManualLayout/HelperFunctions.swift index 244e492..cde223b 100644 --- a/ManualLayout/HelperFunctions.swift +++ b/ManualLayout/HelperFunctions.swift @@ -94,3 +94,11 @@ public func offset(layer: CALayer, dx: CGFloat, dy: CGFloat) -> CGRect { public func offset(rect: CGRect, dx: CGFloat, dy: CGFloat) -> CGRect { return CGRectOffset(rect, dx, dy) } + +public func offset(point: CGPoint, amount: CGFloat) -> CGPoint { + return offset(point, amount, amount) +} + +public func offset(point: CGPoint, dx: CGFloat, dy: CGFloat) -> CGPoint { + return CGPoint(x: point.x + dx, y: point.y + dy) +} From 06fda1dfc352900a961daee2efb598cea88d0e77 Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Fri, 6 Mar 2015 11:49:33 -0800 Subject: [PATCH 09/18] Use available functions in rectangle insetting --- ManualLayout/HelperFunctions.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ManualLayout/HelperFunctions.swift b/ManualLayout/HelperFunctions.swift index cde223b..ac6bb94 100644 --- a/ManualLayout/HelperFunctions.swift +++ b/ManualLayout/HelperFunctions.swift @@ -49,10 +49,8 @@ public func inset(layer: CALayer, top: CGFloat, left: CGFloat, bottom: CGFloat, public func inset(rect: CGRect, top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> CGRect { return CGRect( - x: rect.origin.x + left, - y: rect.origin.y + top, - width: rect.size.width - left - right, - height: rect.size.height - top - bottom) + origin: offset(rect.origin, left, top), + size: inset(rect.size, top, left, bottom, right)) } public func inset(size: CGSize, amount: CGFloat) -> CGSize { From 2a50fb5f88bfd37fc329a513c82183979d3f25be Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Fri, 6 Mar 2015 12:27:33 -0800 Subject: [PATCH 10/18] Add UIScrollView extension Hold properties for easy access to content and viewport rectangles. --- ManualLayout.xcodeproj/project.pbxproj | 4 + ManualLayout/UIScrollView+ManualLayout.swift | 98 ++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 ManualLayout/UIScrollView+ManualLayout.swift diff --git a/ManualLayout.xcodeproj/project.pbxproj b/ManualLayout.xcodeproj/project.pbxproj index ef20921..a81a3ea 100644 --- a/ManualLayout.xcodeproj/project.pbxproj +++ b/ManualLayout.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 5F3026921AAA3C6B00F65A20 /* UIScrollView+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F3026911AAA3C6B00F65A20 /* UIScrollView+ManualLayout.swift */; }; 5F67BC0A1A9D43FE00347483 /* UIViewManualLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC091A9D43FE00347483 /* UIViewManualLayoutTests.swift */; }; 5F67BC3F1A9E970300347483 /* UIViewController+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC3E1A9E970300347483 /* UIViewController+ManualLayout.swift */; }; 5F67BC4C1A9FAB4B00347483 /* SmartAssign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */; }; @@ -30,6 +31,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 5F3026911AAA3C6B00F65A20 /* UIScrollView+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIScrollView+ManualLayout.swift"; sourceTree = ""; }; 5F67BC091A9D43FE00347483 /* UIViewManualLayoutTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewManualLayoutTests.swift; sourceTree = ""; }; 5F67BC3E1A9E970300347483 /* UIViewController+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+ManualLayout.swift"; sourceTree = ""; }; 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartAssign.swift; sourceTree = ""; }; @@ -90,6 +92,7 @@ 5F67BC4F1A9FDDD900347483 /* HelperFunctions.swift */, 5F875C681A9BE99F003CACDD /* CALayer+ManualLayout.swift */, 5F875C6C1A9BFC7E003CACDD /* UIView+ManualLayout.swift */, + 5F3026911AAA3C6B00F65A20 /* UIScrollView+ManualLayout.swift */, 5F67BC3E1A9E970300347483 /* UIViewController+ManualLayout.swift */, 5FB4CBEC1A9BBE7500C2FB4F /* Supporting Files */, ); @@ -235,6 +238,7 @@ 5F67BC501A9FDDD900347483 /* HelperFunctions.swift in Sources */, 5F875C6D1A9BFC7E003CACDD /* UIView+ManualLayout.swift in Sources */, 5F67BC4C1A9FAB4B00347483 /* SmartAssign.swift in Sources */, + 5F3026921AAA3C6B00F65A20 /* UIScrollView+ManualLayout.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ManualLayout/UIScrollView+ManualLayout.swift b/ManualLayout/UIScrollView+ManualLayout.swift new file mode 100644 index 0000000..776875a --- /dev/null +++ b/ManualLayout/UIScrollView+ManualLayout.swift @@ -0,0 +1,98 @@ +// +// UIScrollView+ManualLayout.swift +// ManualLayout +// +// Created by Baris Sencan on 06/03/15. +// Copyright (c) 2015 Baris Sencan. All rights reserved. +// + +import UIKit + +public extension UIScrollView { + + // MARK: - Content Size + + public var contentWidth: CGFloat { + get { + return contentSize.width + } + set { + contentSize.width = snapToPixel(pointCoordinate: newValue) + } + } + + public var contentHeight: CGFloat { + get { + return contentSize.height + } + set { + contentSize.height = snapToPixel(pointCoordinate: newValue) + } + } + + // MARK: - Content Edges (For Convenience) + + public var contentTop: CGFloat { + return 0 + } + + public var contentLeft: CGFloat { + return 0 + } + + public var contentBottom: CGFloat { + get { + return contentHeight + } + set { + contentHeight = newValue + } + } + + public var contentRight: CGFloat { + get { + return contentWidth + } + set { + contentWidth = newValue + } + } + + // MARK: - Viewport Edges + + public var viewportTop: CGFloat { + get { + return contentOffset.y + } + set { + contentOffset.y = snapToPixel(pointCoordinate: newValue) + } + } + + public var viewportLeft: CGFloat { + get { + return contentOffset.x + } + set { + contentOffset.x = snapToPixel(pointCoordinate: newValue) + } + } + + public var viewportBottom: CGFloat { + get { + return contentOffset.y + height + } + set { + contentOffset.y = snapToPixel(pointCoordinate: newValue - height) + } + } + + public var viewportRight: CGFloat { + get { + return contentOffset.x + width + } + set { + contentOffset.x = snapToPixel(pointCoordinate: newValue - width) + } + } +} From 4b9089c30a20d65a0e05e519810455792f9798d3 Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Fri, 6 Mar 2015 12:30:41 -0800 Subject: [PATCH 11/18] Clean framework header --- ManualLayout/ManualLayout.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ManualLayout/ManualLayout.h b/ManualLayout/ManualLayout.h index d85dc51..4331644 100644 --- a/ManualLayout/ManualLayout.h +++ b/ManualLayout/ManualLayout.h @@ -13,7 +13,3 @@ FOUNDATION_EXPORT double ManualLayoutVersionNumber; //! Project version string for ManualLayout. FOUNDATION_EXPORT const unsigned char ManualLayoutVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - From 01d943ea94ef9bdc29ee5d6a8998053118ab9cf6 Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Fri, 6 Mar 2015 13:30:12 -0800 Subject: [PATCH 12/18] Test UIScrollView+ManualLayout --- ManualLayout.xcodeproj/project.pbxproj | 4 + .../UIScrollViewManualLayoutTests.swift | 131 ++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 ManualLayoutTests/UIScrollViewManualLayoutTests.swift diff --git a/ManualLayout.xcodeproj/project.pbxproj b/ManualLayout.xcodeproj/project.pbxproj index a81a3ea..c4de9bc 100644 --- a/ManualLayout.xcodeproj/project.pbxproj +++ b/ManualLayout.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 5F3026921AAA3C6B00F65A20 /* UIScrollView+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F3026911AAA3C6B00F65A20 /* UIScrollView+ManualLayout.swift */; }; + 5F3026941AAA460E00F65A20 /* UIScrollViewManualLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F3026931AAA460E00F65A20 /* UIScrollViewManualLayoutTests.swift */; }; 5F67BC0A1A9D43FE00347483 /* UIViewManualLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC091A9D43FE00347483 /* UIViewManualLayoutTests.swift */; }; 5F67BC3F1A9E970300347483 /* UIViewController+ManualLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC3E1A9E970300347483 /* UIViewController+ManualLayout.swift */; }; 5F67BC4C1A9FAB4B00347483 /* SmartAssign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */; }; @@ -32,6 +33,7 @@ /* Begin PBXFileReference section */ 5F3026911AAA3C6B00F65A20 /* UIScrollView+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIScrollView+ManualLayout.swift"; sourceTree = ""; }; + 5F3026931AAA460E00F65A20 /* UIScrollViewManualLayoutTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIScrollViewManualLayoutTests.swift; sourceTree = ""; }; 5F67BC091A9D43FE00347483 /* UIViewManualLayoutTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewManualLayoutTests.swift; sourceTree = ""; }; 5F67BC3E1A9E970300347483 /* UIViewController+ManualLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+ManualLayout.swift"; sourceTree = ""; }; 5F67BC4B1A9FAB4B00347483 /* SmartAssign.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartAssign.swift; sourceTree = ""; }; @@ -113,6 +115,7 @@ 5F67BC4D1A9FB1A600347483 /* SmartAssignTests.swift */, 5F67BC511A9FE35C00347483 /* HelperFunctionTests.swift */, 5F67BC091A9D43FE00347483 /* UIViewManualLayoutTests.swift */, + 5F3026931AAA460E00F65A20 /* UIScrollViewManualLayoutTests.swift */, 5FB4CBF91A9BBE7500C2FB4F /* Supporting Files */, ); path = ManualLayoutTests; @@ -247,6 +250,7 @@ buildActionMask = 2147483647; files = ( 5F67BC521A9FE35C00347483 /* HelperFunctionTests.swift in Sources */, + 5F3026941AAA460E00F65A20 /* UIScrollViewManualLayoutTests.swift in Sources */, 5F67BC4E1A9FB1A600347483 /* SmartAssignTests.swift in Sources */, 5F67BC0A1A9D43FE00347483 /* UIViewManualLayoutTests.swift in Sources */, ); diff --git a/ManualLayoutTests/UIScrollViewManualLayoutTests.swift b/ManualLayoutTests/UIScrollViewManualLayoutTests.swift new file mode 100644 index 0000000..ba89968 --- /dev/null +++ b/ManualLayoutTests/UIScrollViewManualLayoutTests.swift @@ -0,0 +1,131 @@ +// +// UIScrollViewManualLayoutTests.swift +// ManualLayout +// +// Created by Baris Sencan on 06/03/15. +// Copyright (c) 2015 Baris Sencan. All rights reserved. +// + +import UIKit +import XCTest +import ManualLayout + +internal final class UIScrollViewManualLayoutTests: XCTestCase { + let defaultContentSize = CGSize(width: 20, height: 20) + let defaultContentOffset = CGPoint(x: 10, y: 10) + let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: 10, height: 10)) + + override func setUp() { + scrollView.contentSize = defaultContentSize + scrollView.contentOffset = defaultContentOffset + } + + func testContentWidth() { + XCTAssertEqual( + scrollView.contentWidth, + scrollView.contentSize.width, + "contentWidth should be equal to contentSize.width") + scrollView.contentWidth = 30 + XCTAssertEqual( + scrollView.contentSize, + CGSize(width: 30, height: defaultContentSize.height), + "Setting contentWidth should modify contentSize correctly") + } + + func testContentHeight() { + XCTAssertEqual( + scrollView.contentHeight, + scrollView.contentSize.height, + "contentHeight should be equal to contentSize.height") + scrollView.contentHeight = 30 + XCTAssertEqual( + scrollView.contentSize, + CGSize(width: defaultContentSize.width, height: 30), + "Setting contentHeight should modify contentSize correctly") + } + + func testContentTop() { + XCTAssert( + scrollView.contentTop == 0, + "contentTop should be equal to 0") + } + + func testContentLeft() { + XCTAssert( + scrollView.contentLeft == 0, + "contentLeft should be equal to 0") + } + + func testContentBottom() { + XCTAssertEqual( + scrollView.contentBottom, + scrollView.contentSize.height, + "contentBottom should be equal to contentSize.height") + scrollView.contentBottom = 30 + XCTAssertEqual( + scrollView.contentSize, + CGSize(width: defaultContentSize.width, height: 30), + "Setting contentBottom should modify contentSize correctly") + } + + func testContentRight() { + XCTAssertEqual( + scrollView.contentRight, + scrollView.contentSize.width, + "contentRight should be equal to contentSize.width") + scrollView.contentRight = 30 + XCTAssertEqual( + scrollView.contentSize, + CGSize(width: 30, height: defaultContentSize.height), + "Setting contentRight should modify contentSize correctly") + } + + func testViewportTop() { + XCTAssertEqual( + scrollView.viewportTop, + scrollView.contentOffset.y, + "viewportTop should be equal to contentOffset.y") + scrollView.viewportTop = 0 + XCTAssertEqual( + scrollView.contentOffset, + CGPoint(x: defaultContentOffset.x, y: 0), + "Setting viewportTop should modify contentOffset correctly") + } + + func testViewportLeft() { + XCTAssertEqual( + scrollView.viewportLeft, + scrollView.contentOffset.x, + "viewportLeft should be equal to contentOffset.x") + scrollView.viewportLeft = 0 + XCTAssertEqual( + scrollView.contentOffset, + CGPoint(x: 0, y: defaultContentOffset.y), + "Setting viewportLeft should modify contentOffset correctly") + } + + func testViewportBottom() { + XCTAssertEqual( + scrollView.viewportBottom, + scrollView.contentOffset.y + scrollView.frame.size.height, + "viewportBottom should be equal to contentOffset.y + height") + scrollView.viewportBottom = 10 + XCTAssertEqual( + scrollView.contentOffset, + CGPoint(x: defaultContentOffset.x, y: 0), + "Setting viewportBottom should modify contentOffset correctly") + } + + func testViewportRight() { + XCTAssertEqual( + scrollView.viewportRight, + scrollView.contentOffset.x + scrollView.frame.size.width, + "viewportRight should be equal to contentOffset.x + width") + scrollView.viewportRight = 10 + XCTAssertEqual( + scrollView.contentOffset, + CGPoint(x: 0, y: defaultContentOffset.y), + "Setting viewportRight should modify contentOffset correctly") + } +} + From f0cc57391309742bb3064810da8007496522c8fb Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Fri, 6 Mar 2015 13:56:36 -0800 Subject: [PATCH 13/18] Test new helper functions --- ManualLayoutTests/HelperFunctionTests.swift | 48 +++++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/ManualLayoutTests/HelperFunctionTests.swift b/ManualLayoutTests/HelperFunctionTests.swift index 64b0330..dd174ec 100644 --- a/ManualLayoutTests/HelperFunctionTests.swift +++ b/ManualLayoutTests/HelperFunctionTests.swift @@ -18,7 +18,7 @@ class HelperFunctionTests: XCTestCase { view.frame = defaultFrame } - func testInsetSingleArg() { + func testInsetRectSingleArg() { view.frame = inset(view, 1) XCTAssertEqual( view.frame, @@ -26,7 +26,7 @@ class HelperFunctionTests: XCTestCase { "insetting with amount should inset correctly") } - func testInsetTwoArg() { + func testInsetRectTwoArg() { view.frame = inset(view, 1, 2) XCTAssertEqual( view.frame, @@ -34,7 +34,7 @@ class HelperFunctionTests: XCTestCase { "insetting with dx and dy should inset correctly") } - func testInsetFourArg() { + func testInsetRectFourArg() { view.frame = inset(view, 1, 2, 3, 4) XCTAssertEqual( view.frame, @@ -42,6 +42,30 @@ class HelperFunctionTests: XCTestCase { "insetting with four arguments should inset correctly") } + func testInsetSizeSingleArg() { + let size = inset(view.frame.size, 1) + XCTAssertEqual( + size, + CGSize(width: 4, height: 6), + "insetting size with amount should inset correctly") + } + + func testInsetSizeTwoArg() { + let size = inset(view.frame.size, 1, 2) + XCTAssertEqual( + size, + CGSize(width: 4, height: 4), + "insetting size with two arguments should inset correctly") + } + + func testInsetSizeFourArg() { + let size = inset(view.frame.size, 1, 2, 3, 4) + XCTAssertEqual( + size, + CGSize(width: 0, height: 4), + "insetting size with four arguments should inset correctly") + } + func testOffsetSingleArg() { view.frame = offset(view, 1) XCTAssertEqual( @@ -57,4 +81,20 @@ class HelperFunctionTests: XCTestCase { CGRect(x: 2, y: 5, width: 6, height: 8), "offsetting with dx and dy should offset correctly") } -} \ No newline at end of file + + func testOffsetPointSingleArg() { + let origin = offset(view.frame.origin, 1) + XCTAssertEqual( + origin, + CGPoint(x: 2, y: 4), + "offsetting origin with amount should offset correctly") + } + + func testOffsetPointTwoArg() { + let origin = offset(view.frame.origin, 1, 2) + XCTAssertEqual( + origin, + CGPoint(x: 2, y: 5), + "offsetting origin with dx and dy should offset correctly") + } +} From d1932b684a8b7cb7bfe498962581e47349d726eb Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Fri, 6 Mar 2015 14:05:32 -0800 Subject: [PATCH 14/18] Remove new lines at the end of files --- ManualLayout/HelperFunctions.swift | 2 +- ManualLayout/ManualLayout.h | 2 +- ManualLayout/SmartAssign.swift | 2 +- ManualLayout/UIScrollView+ManualLayout.swift | 2 +- ManualLayout/UIView+ManualLayout.swift | 2 +- ManualLayout/UIViewController+ManualLayout.swift | 2 +- ManualLayoutTests/HelperFunctionTests.swift | 2 +- ManualLayoutTests/UIScrollViewManualLayoutTests.swift | 3 +-- 8 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ManualLayout/HelperFunctions.swift b/ManualLayout/HelperFunctions.swift index ac6bb94..a71c1ab 100644 --- a/ManualLayout/HelperFunctions.swift +++ b/ManualLayout/HelperFunctions.swift @@ -99,4 +99,4 @@ public func offset(point: CGPoint, amount: CGFloat) -> CGPoint { public func offset(point: CGPoint, dx: CGFloat, dy: CGFloat) -> CGPoint { return CGPoint(x: point.x + dx, y: point.y + dy) -} +} \ No newline at end of file diff --git a/ManualLayout/ManualLayout.h b/ManualLayout/ManualLayout.h index 4331644..f66f67b 100644 --- a/ManualLayout/ManualLayout.h +++ b/ManualLayout/ManualLayout.h @@ -12,4 +12,4 @@ FOUNDATION_EXPORT double ManualLayoutVersionNumber; //! Project version string for ManualLayout. -FOUNDATION_EXPORT const unsigned char ManualLayoutVersionString[]; +FOUNDATION_EXPORT const unsigned char ManualLayoutVersionString[]; \ No newline at end of file diff --git a/ManualLayout/SmartAssign.swift b/ManualLayout/SmartAssign.swift index fb2ec5b..a573f86 100644 --- a/ManualLayout/SmartAssign.swift +++ b/ManualLayout/SmartAssign.swift @@ -23,4 +23,4 @@ public func =~ (inout size: CGSize, sizeTuple: (CGFloat, CGFloat)) -> CGSize { public func =~ (inout rect: CGRect, rectTuple: (CGFloat, CGFloat, CGFloat, CGFloat)) -> CGRect { rect = CGRect(x: rectTuple.0, y: rectTuple.1, width: rectTuple.2, height: rectTuple.3) return rect -} +} \ No newline at end of file diff --git a/ManualLayout/UIScrollView+ManualLayout.swift b/ManualLayout/UIScrollView+ManualLayout.swift index 776875a..9457c58 100644 --- a/ManualLayout/UIScrollView+ManualLayout.swift +++ b/ManualLayout/UIScrollView+ManualLayout.swift @@ -95,4 +95,4 @@ public extension UIScrollView { contentOffset.x = snapToPixel(pointCoordinate: newValue - width) } } -} +} \ No newline at end of file diff --git a/ManualLayout/UIView+ManualLayout.swift b/ManualLayout/UIView+ManualLayout.swift index ef68759..ad4e00f 100644 --- a/ManualLayout/UIView+ManualLayout.swift +++ b/ManualLayout/UIView+ManualLayout.swift @@ -110,4 +110,4 @@ public extension UIView { public func sizeToFit(constrainedSize: CGSize) { size = sizeThatFits(constrainedSize) } -} +} \ No newline at end of file diff --git a/ManualLayout/UIViewController+ManualLayout.swift b/ManualLayout/UIViewController+ManualLayout.swift index 1c7e652..d0e234b 100644 --- a/ManualLayout/UIViewController+ManualLayout.swift +++ b/ManualLayout/UIViewController+ManualLayout.swift @@ -55,4 +55,4 @@ public extension UIViewController { public var left: CGFloat { return 0 } -} +} \ No newline at end of file diff --git a/ManualLayoutTests/HelperFunctionTests.swift b/ManualLayoutTests/HelperFunctionTests.swift index dd174ec..5607a07 100644 --- a/ManualLayoutTests/HelperFunctionTests.swift +++ b/ManualLayoutTests/HelperFunctionTests.swift @@ -97,4 +97,4 @@ class HelperFunctionTests: XCTestCase { CGPoint(x: 2, y: 5), "offsetting origin with dx and dy should offset correctly") } -} +} \ No newline at end of file diff --git a/ManualLayoutTests/UIScrollViewManualLayoutTests.swift b/ManualLayoutTests/UIScrollViewManualLayoutTests.swift index ba89968..fd8771c 100644 --- a/ManualLayoutTests/UIScrollViewManualLayoutTests.swift +++ b/ManualLayoutTests/UIScrollViewManualLayoutTests.swift @@ -127,5 +127,4 @@ internal final class UIScrollViewManualLayoutTests: XCTestCase { CGPoint(x: 0, y: defaultContentOffset.y), "Setting viewportRight should modify contentOffset correctly") } -} - +} \ No newline at end of file From 19cd7337736f35a0ab6c3c52c552858d3b90c1c0 Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Fri, 6 Mar 2015 15:08:14 -0800 Subject: [PATCH 15/18] Test UIView.sizeToFit(constrainedSize) Also changed how it works, and the arguments it can take. All for the better. --- ManualLayout/UIView+ManualLayout.swift | 16 +++++++++------- .../UIViewManualLayoutTests.swift | 19 ++++++++++++++++++- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/ManualLayout/UIView+ManualLayout.swift b/ManualLayout/UIView+ManualLayout.swift index ad4e00f..a4ace42 100644 --- a/ManualLayout/UIView+ManualLayout.swift +++ b/ManualLayout/UIView+ManualLayout.swift @@ -101,13 +101,15 @@ public extension UIView { // MARK: - Automatic Sizing - public func sizeToFit(constrainedSizeTuple: (CGFloat, CGFloat)) { - sizeToFit(CGSize( - width: constrainedSizeTuple.0, - height: constrainedSizeTuple.1)) + public func sizeToFit(width: CGFloat, _ height: CGFloat) -> CGSize { + return sizeToFit(CGSize(width: width, height: height)) } - public func sizeToFit(constrainedSize: CGSize) { - size = sizeThatFits(constrainedSize) + public func sizeToFit(constrainedSize: CGSize) -> CGSize { + var newSize = sizeThatFits(constrainedSize) + newSize.width = min(newSize.width, constrainedSize.width) + newSize.height = min(newSize.height, constrainedSize.height) + size = newSize + return newSize } -} \ No newline at end of file +} diff --git a/ManualLayoutTests/UIViewManualLayoutTests.swift b/ManualLayoutTests/UIViewManualLayoutTests.swift index c1af0cc..d87c780 100644 --- a/ManualLayoutTests/UIViewManualLayoutTests.swift +++ b/ManualLayoutTests/UIViewManualLayoutTests.swift @@ -226,4 +226,21 @@ class UIViewManualLayoutTests: XCTestCase { "left2 changes without a swap should modify frame size") // TODO: Test swap behavior. } -} \ No newline at end of file + + func testSizeToFit() { + let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 200)) + let label = UILabel(frame: CGRectZero) + label.text = "lorem ipsum dolor sit amet" + label.numberOfLines = 5 + containerView.addSubview(label) + label.sizeToFit(containerView.frame.size) + XCTAssert( + label.frame.size.height > 20 && label.frame.size.width <= 20, + "sizeToFit should size the view to fit given constrained size") + label.numberOfLines = 1 + label.sizeToFit(containerView.frame.size) + XCTAssert( + label.frame.size.height > 20 && label.frame.size.width <= 20, + "sizeToFit should size the view to fit given constrained size") + } +} From 85ff4c100f61a1647aa1abc96b1d398d31185840 Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Fri, 6 Mar 2015 15:18:29 -0800 Subject: [PATCH 16/18] Document UIView methods Also removed old API methods. --- README.md | 58 +++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 645cdab..8d1c40a 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,16 @@ Just `import ManualLayout` in your code and use the methods and properties provi #API Cheat Sheet +###Smart Assign Operator + +The smart assign operator `=~` has only one job; to make your life easier. + +```swift +someView.origin =~ (0, 20) +anotherView.size =~ (100, 100) +yetAnotherView.frame =~ (0, 120, view.width, 100) +``` + ###CALayer/UIView Properties ```swift @@ -72,6 +82,24 @@ The difference between alternate edges and normal edges require a bit of explain So basically, *setting a normal edge's position drags the whole view along with that edge but setting an alternative edge's position drags just that edge*. And don't worry if you, for example, try to drag a left edge past its view's right edge. Edge swapping is done automatically so you don't have to worry about. +###UIView Methods + +Just one method with two variants for now, and those are used for easy size calculations. + +```swift +func sizeToFit(width: CGFloat, height: CGFloat) -> CGSize +func sizeToFit(constrainedSize: CGSize) -> CGSize +``` + +So let's say that you have a label inside a view and you want to lay it out with an inset of 4 points on all sides, you could easily do the following: + +```swift +myLabel.sizeToFit(inset(myView, 4)) +myLabel.origin =~ (4, 4) +``` + +Done! + ###UIViewController Properties ```swift @@ -108,33 +136,3 @@ func offset(rect: CGRect, dx: CGFloat, dy: CGFloat) -> CGRect ``` These functions never modify the view/layer/rectangle they are passed. - -###Smart Assign Operator - -The smart assign operator `=~` has only one job; to make your life easier. - -```swift -someView.origin =~ (0, 20) -anotherView.size =~ (100, 100) -yetAnotherView.frame =~ (0, 120, view.width, 100) -``` - -###CALayer/UIView Methods - -Replace the word "layer" with "view" for the UIView methods. - -```swift -func centerInSuperlayer() -func centerDimensionInSuperlayer(dimension: ManualLayoutDimension) // .X or .Y -``` - -More coming soon. - -###ManualLayout Methods - -```swift -static func getOriginForCenteringRect(rect: CGRect, inRect container: CGRect) -> CGPoint -static func getPositionForCenteringRect(rect: CGRect, dimension: ManualLayoutDimension, inRect container: CGRect) -> CGFloat -``` - -More coming soon. From d200ddd735767d9672851c0d7dc7de7e394c35b5 Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Fri, 6 Mar 2015 15:36:42 -0800 Subject: [PATCH 17/18] Document the rest --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8d1c40a..29a76f0 100644 --- a/README.md +++ b/README.md @@ -100,17 +100,46 @@ myLabel.origin =~ (4, 4) Done! +###UIScrollView Properties + +```swift +var contentWidth: CGFloat +var contentHeight: CGFloat + +var contentTop: CGFloat // Always equal to 0. Read-only. +var contentLeft: CGFloat // Always equal to 0. Read-only. +var contentBottom: CGFloat // contentHeight alias. +var contentRight: CGFloat // contentWidth alias. + +var viewportTop: CGFloat // contentOffset.y alias. +var viewportLeft: CGFloat // contentOffset.x alias. +var viewportBottom: CGFloat // conentOffset.y + view height +var viewportRight: CGFloat // contentOffset.x + view width +``` + ###UIViewController Properties +All UIViewController properties are read only. They offer easy read access to a controller's view's properties. + ```swift -var top: CGFloat // Top layout guide y coordinate. Read-only. -var right: CGFloat // Equal to the width of the controller's view. Read-only. For convenience. -var bottom: CGFloat // Bottom layout guide y coordinate. Read-only. -var left: CGFloat // Always equal to 0. Read-only. For convenience. +var center: CGPoint +var centerX: CGFloat +var centerY: CGFloat + +var size: CGSize +var width: CGFloat +var height: CGFloat + +var top: CGFloat // Top layout guide y coordinate. +var right: CGFloat // Equal to the width of the controller's view. +var bottom: CGFloat // Bottom layout guide y coordinate. +var left: CGFloat // Always equal to 0. ``` ###Helper Methods +These functions never modify the view/layer/rectangle/etc they are passed. + ```swift func inset(view: UIView, amount: CGFloat) -> CGRect func inset(layer: CALayer, amount: CGFloat) -> CGRect @@ -123,6 +152,10 @@ func inset(rect: CGRect, dx: CGFloat, dy: CGFloat) -> CGRect func inset(view: UIView, top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> CGRect func inset(layer: CALayer, top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> CGRect func inset(rect: CGRect, top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> CGRect + +func inset(size: CGSize, amount: CGFloat) -> CGSize +func inset(size: CGSize, dx: CGFloat, dy: CGFloat) -> CGSize +func inset(size: CGSize, top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> CGSize ``` ```swift @@ -133,6 +166,7 @@ func offset(rect: CGRect, amount: CGFloat) -> CGRect func offset(view: UIView, dx: CGFloat, dy: CGFloat) -> CGRect func offset(layer: CALayer, dx: CGFloat, dy: CGFloat) -> CGRect func offset(rect: CGRect, dx: CGFloat, dy: CGFloat) -> CGRect -``` -These functions never modify the view/layer/rectangle they are passed. +func offset(point: CGPoint, amount: CGFloat) -> CGPoint +func offset(point: CGPoint, dx: CGFloat, dy: CGFloat) -> CGPoint +``` From b5f4fc852ac2e89c93b7e0002fdaa2304ee8999c Mon Sep 17 00:00:00 2001 From: Baris Sencan Date: Fri, 6 Mar 2015 15:39:51 -0800 Subject: [PATCH 18/18] Increment version number --- ManualLayout.podspec | 2 +- ManualLayout/Info.plist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ManualLayout.podspec b/ManualLayout.podspec index 3157af9..b622472 100644 --- a/ManualLayout.podspec +++ b/ManualLayout.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'ManualLayout' - s.version = '0.3.1' + s.version = '0.4.0' s.license = { :type => 'MIT', :file => 'LICENSE' } s.summary = 'Easy to use and flexible AutoLayout alternative for iOS 8+. Supports AsyncDisplayKit.' diff --git a/ManualLayout/Info.plist b/ManualLayout/Info.plist index 824cbdf..fb77999 100644 --- a/ManualLayout/Info.plist +++ b/ManualLayout/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.3.1 + 0.4.0 CFBundleSignature ???? CFBundleVersion