Skip to content

Commit 8d520e7

Browse files
author
Anton Doudarev
committed
Added Actual Code to the Framework
1 parent 8f7d478 commit 8d520e7

File tree

4 files changed

+192
-4
lines changed

4 files changed

+192
-4
lines changed
File renamed without changes.

SwiftLayout/SwiftLayout-Demo/SwiftLayout-Demo.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
131720571CF6D74B0032B64D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131720561CF6D74B0032B64D /* ViewController.swift */; };
1212
1317205C1CF6D74B0032B64D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1317205B1CF6D74B0032B64D /* Assets.xcassets */; };
1313
1317205F1CF6D74B0032B64D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1317205D1CF6D74B0032B64D /* LaunchScreen.storyboard */; };
14-
131720691CF6D9420032B64D /* SwiftLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131720681CF6D9420032B64D /* SwiftLayout.swift */; };
14+
131720691CF6D9420032B64D /* UIView+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131720681CF6D9420032B64D /* UIView+Layout.swift */; };
1515
/* End PBXBuildFile section */
1616

1717
/* Begin PBXFileReference section */
@@ -21,7 +21,7 @@
2121
1317205B1CF6D74B0032B64D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
2222
1317205E1CF6D74B0032B64D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
2323
131720601CF6D74B0032B64D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
24-
131720681CF6D9420032B64D /* SwiftLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SwiftLayout.swift; path = ../../../Source/SwiftLayout.swift; sourceTree = "<group>"; };
24+
131720681CF6D9420032B64D /* UIView+Layout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+Layout.swift"; path = "../../../Source/UIView+Layout.swift"; sourceTree = "<group>"; };
2525
/* End PBXFileReference section */
2626

2727
/* Begin PBXFrameworksBuildPhase section */
@@ -83,7 +83,7 @@
8383
1317206A1CF6D9490032B64D /* SwiftLayout */ = {
8484
isa = PBXGroup;
8585
children = (
86-
131720681CF6D9420032B64D /* SwiftLayout.swift */,
86+
131720681CF6D9420032B64D /* UIView+Layout.swift */,
8787
);
8888
name = SwiftLayout;
8989
sourceTree = "<group>";
@@ -159,7 +159,7 @@
159159
buildActionMask = 2147483647;
160160
files = (
161161
131720571CF6D74B0032B64D /* ViewController.swift in Sources */,
162-
131720691CF6D9420032B64D /* SwiftLayout.swift in Sources */,
162+
131720691CF6D9420032B64D /* UIView+Layout.swift in Sources */,
163163
131720551CF6D74B0032B64D /* AppDelegate.swift in Sources */,
164164
);
165165
runOnlyForDeploymentPostprocessing = 0;

SwiftLayout/SwiftLayout.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
136B00AC1D59380100065EC9 /* UIView+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136B00AB1D59380100065EC9 /* UIView+Layout.swift */; };
11+
136B00AD1D59380100065EC9 /* UIView+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136B00AB1D59380100065EC9 /* UIView+Layout.swift */; };
1012
1374273F1CF6070D000FCEA7 /* SwiftLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 1374273E1CF6070D000FCEA7 /* SwiftLayout.h */; settings = {ATTRIBUTES = (Public, ); }; };
1113
137427461CF6070D000FCEA7 /* SwiftLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1374273B1CF6070D000FCEA7 /* SwiftLayout.framework */; };
1214
1374274B1CF6070D000FCEA7 /* SwiftLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1374274A1CF6070D000FCEA7 /* SwiftLayoutTests.swift */; };
@@ -23,6 +25,7 @@
2325
/* End PBXContainerItemProxy section */
2426

2527
/* Begin PBXFileReference section */
28+
136B00AB1D59380100065EC9 /* UIView+Layout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Layout.swift"; sourceTree = "<group>"; };
2629
1374273B1CF6070D000FCEA7 /* SwiftLayout.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftLayout.framework; sourceTree = BUILT_PRODUCTS_DIR; };
2730
1374273E1CF6070D000FCEA7 /* SwiftLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftLayout.h; sourceTree = "<group>"; };
2831
137427401CF6070D000FCEA7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -71,6 +74,7 @@
7174
1374273D1CF6070D000FCEA7 /* SwiftLayout */ = {
7275
isa = PBXGroup;
7376
children = (
77+
136B00AB1D59380100065EC9 /* UIView+Layout.swift */,
7478
1374273E1CF6070D000FCEA7 /* SwiftLayout.h */,
7579
137427401CF6070D000FCEA7 /* Info.plist */,
7680
);
@@ -194,13 +198,15 @@
194198
isa = PBXSourcesBuildPhase;
195199
buildActionMask = 2147483647;
196200
files = (
201+
136B00AC1D59380100065EC9 /* UIView+Layout.swift in Sources */,
197202
);
198203
runOnlyForDeploymentPostprocessing = 0;
199204
};
200205
137427411CF6070D000FCEA7 /* Sources */ = {
201206
isa = PBXSourcesBuildPhase;
202207
buildActionMask = 2147483647;
203208
files = (
209+
136B00AD1D59380100065EC9 /* UIView+Layout.swift in Sources */,
204210
1374274B1CF6070D000FCEA7 /* SwiftLayoutTests.swift in Sources */,
205211
);
206212
runOnlyForDeploymentPostprocessing = 0;
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
//
2+
// SwiftLayout.swift
3+
// SwiftLayout
4+
//
5+
// Created by Anton Doudarev on 5/25/16.
6+
// Copyright © 2016 Anton Doudarev. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import UIKit
11+
12+
public enum VerticalAlign {
13+
case Above // Align vertically Above
14+
case Below // Align vertically Below
15+
case Center // Align center.y vertically
16+
case Top // Align vertically to the top
17+
case Base // Align vertically to the base
18+
}
19+
20+
public enum HorizontalAlign {
21+
case Left // Align horizontally to the Left
22+
case Right // Align horizontally to the Right
23+
case Center // Align center.y horizontally
24+
case RightEdge // Align horizontally to the Right Edge
25+
case LeftEdge // Align horizontally to the Left Edge
26+
}
27+
28+
29+
// MARK: - UIView Alignment Extension
30+
31+
public extension UIView {
32+
33+
/**
34+
Align self relative to another frame.
35+
36+
This method calculate a new frame based on the alignment
37+
parameters, and sets that frame on self
38+
39+
- parameter toFrame: relative frame to align against. If not assigned, will attempt to use the superview, else defaults to CGRectZero
40+
- parameter withSize: size to set on the calculated frame, defaults to self.bounds.size
41+
- parameter horizontal: horizontal alignment relative to the toView
42+
- parameter vertical: vertical alignment relative to the toView
43+
- parameter horizontalOffset: horizontal offset to apply to the calculated relative frame, defautls to 0
44+
- parameter verticalOffset: vertical offset to apply to the calculated relative frame, defautls to 0
45+
*/
46+
func align(toFrame frame : CGRect? = nil,
47+
withSize size : CGSize? = nil,
48+
horizontal : HorizontalAlign = .Center,
49+
vertical : VerticalAlign = .Center,
50+
horizontalOffset : CGFloat = 0.0,
51+
verticalOffset : CGFloat = 0.0) {
52+
53+
let newRect = rectAligned(toFrame : frame,
54+
withSize : size,
55+
horizontal : horizontal,
56+
vertical : vertical,
57+
horizontalOffset : horizontalOffset,
58+
verticalOffset : verticalOffset)
59+
60+
if CGRectEqualToRect(self.frame, newRect) == false {
61+
self.frame = newRect
62+
}
63+
}
64+
65+
/**
66+
Calculates,vand returns a frame based on the alignment parameters.
67+
68+
This is a handy method to use when performing animations, you can ask the view to return
69+
the frame it would align to without aligning it self to the returned value.
70+
71+
See the CGRect Extension provided with this framework, you can query a CGRect
72+
for it's bounds and center. Since the frame property is not animatable, you
73+
may cancreate an animation group with two separate animations, one for position,
74+
and one for hte bounds
75+
76+
- parameter toFrame: relative frame to align against. If not assigned, will attempt to use the superview, else defaults to CGRectZero
77+
- parameter withSize: size to set on the calculated frame, defaults to self.bounds.size
78+
- parameter horizontal: horizontal alignment relative to the toView
79+
- parameter vertical: vertical alignment relative to the toView
80+
- parameter horizontalOffset: horizontal offset to apply to the calculated relative frame, defautls to 0
81+
- parameter verticalOffset: vertical offset to apply to the calculated relative frame, defautls to 0
82+
83+
- returns: returns the final aligned frame
84+
*/
85+
func rectAligned(toFrame frame : CGRect? = nil,
86+
withSize size : CGSize? = nil,
87+
horizontal : HorizontalAlign = .Center,
88+
vertical : VerticalAlign = .Center,
89+
horizontalOffset : CGFloat = 0.0,
90+
verticalOffset : CGFloat = 0.0) -> CGRect {
91+
92+
var referenceFrame = frame
93+
94+
if let relativeFrame = frame {
95+
if CGRectEqualToRect(CGRectZero, relativeFrame) {
96+
if let superviewFrame = superview?.bounds {
97+
referenceFrame = superviewFrame
98+
}
99+
}
100+
} else {
101+
if let superviewFrame = superview?.bounds {
102+
referenceFrame = superviewFrame
103+
}
104+
}
105+
106+
var calculatedFrame = self.bounds
107+
108+
if let newSize = size {
109+
calculatedFrame.size = newSize
110+
}
111+
112+
calculatedFrame.origin.x = alignedHorizontalOrigin(forRect : calculatedFrame,
113+
relativeToRect : referenceFrame!,
114+
withAlignment : horizontal)
115+
116+
calculatedFrame.origin.y = alignedVerticalOrigin(forRect : calculatedFrame,
117+
relativeToRect : referenceFrame!,
118+
withAlignment : vertical)
119+
120+
calculatedFrame.origin.x += horizontalOffset
121+
calculatedFrame.origin.y += verticalOffset
122+
123+
return calculatedFrame
124+
}
125+
}
126+
127+
128+
// MARK: - Private Alignment Calculations Extension
129+
130+
extension UIView {
131+
132+
/**
133+
Private Method. Calculates a horizontally aligned frame for the source frame relative to
134+
the destination frame
135+
*/
136+
final private func alignedHorizontalOrigin(forRect sourceRect : CGRect,
137+
relativeToRect toRect : CGRect,
138+
withAlignment alignment : HorizontalAlign) -> CGFloat {
139+
140+
var origin = sourceRect.origin.x
141+
142+
switch (alignment) {
143+
case .Left:
144+
origin = toRect.origin.x - sourceRect.size.width;
145+
case .Right:
146+
origin = CGRectGetMaxX(toRect);
147+
case .Center:
148+
origin = toRect.origin.x + ((toRect.size.width - sourceRect.size.width) / 2.0);
149+
case .LeftEdge:
150+
origin = toRect.origin.x;
151+
case .RightEdge:
152+
origin = CGRectGetMaxX(toRect) - sourceRect.size.width;
153+
}
154+
155+
return round(origin)
156+
}
157+
158+
/**
159+
Private Method. Calculates a vertically aligned frame for the source frame relative to
160+
the destination frame
161+
*/
162+
final private func alignedVerticalOrigin(forRect sourceRect : CGRect,
163+
relativeToRect toRect : CGRect,
164+
withAlignment alignment : VerticalAlign) -> CGFloat {
165+
var origin = sourceRect.origin.x
166+
167+
switch (alignment) {
168+
case .Top:
169+
origin = toRect.origin.y
170+
case .Base:
171+
origin = CGRectGetMaxY(toRect) - sourceRect.size.height
172+
case .Center:
173+
origin = toRect.origin.y + ((toRect.size.height - sourceRect.size.height) / 2.0)
174+
case .Above:
175+
origin = toRect.origin.y - sourceRect.size.height
176+
case .Below:
177+
origin = CGRectGetMaxY(toRect)
178+
}
179+
180+
return round(origin)
181+
}
182+
}

0 commit comments

Comments
 (0)