Skip to content

Commit fa69c4b

Browse files
author
Luc Dion
authored
Merge pull request #51 from mirego/add_form_sample
Add a form example
2 parents 6a2d4be + b0f5ae2 commit fa69c4b

File tree

20 files changed

+372
-37
lines changed

20 files changed

+372
-37
lines changed

Example/PinLayoutSample.xcodeproj/project.pbxproj

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
249326891EEEEE3D00BCB814 /* Stylesheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 249326881EEEEE3D00BCB814 /* Stylesheet.swift */; };
2020
2493268C1EEEEFF100BCB814 /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2493268B1EEEEFF100BCB814 /* BaseViewController.swift */; };
2121
2493268E1EEEF02700BCB814 /* BaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2493268D1EEEF02700BCB814 /* BaseView.swift */; };
22+
2497CFED1EF40B9100DFD13B /* FormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2497CFEB1EF40B9100DFD13B /* FormView.swift */; };
23+
2497CFEE1EF40B9100DFD13B /* FormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2497CFEC1EF40B9100DFD13B /* FormViewController.swift */; };
2224
249EFE431E64FAFE00165E39 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 249EFE421E64FAFE00165E39 /* AppDelegate.swift */; };
2325
249EFE4A1E64FAFE00165E39 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 249EFE491E64FAFE00165E39 /* Assets.xcassets */; };
2426
249EFE4D1E64FAFE00165E39 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 249EFE4B1E64FAFE00165E39 /* LaunchScreen.storyboard */; };
@@ -28,6 +30,7 @@
2830
24A9C1F91EF0619C00F2CF64 /* MethodGroupHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A9C1F81EF0619C00F2CF64 /* MethodGroupHeader.swift */; };
2931
24A9C2031EF16A3E00F2CF64 /* AutoAdjustingSizeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A9C2011EF16A3E00F2CF64 /* AutoAdjustingSizeView.swift */; };
3032
24A9C2041EF16A3E00F2CF64 /* AutoAdjustingSizeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A9C2021EF16A3E00F2CF64 /* AutoAdjustingSizeViewController.swift */; };
33+
24DA374B1EF7F90600D1AB2F /* BaseFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24DA374A1EF7F90600D1AB2F /* BaseFormView.swift */; };
3134
24E654821E69041B00A72A8B /* Expect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24E654811E69041B00A72A8B /* Expect.swift */; };
3235
24F75B5B1EE5644E008DB567 /* IntroView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F75B591EE5644E008DB567 /* IntroView.swift */; };
3336
24F75B5C1EE5644E008DB567 /* IntroViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F75B5A1EE5644E008DB567 /* IntroViewController.swift */; };
@@ -56,6 +59,13 @@
5659
remoteGlobalIDString = 249EFE791E64FB4C00165E39;
5760
remoteInfo = PinLayout;
5861
};
62+
24DA374E1EF7F90700D1AB2F /* PBXContainerItemProxy */ = {
63+
isa = PBXContainerItemProxy;
64+
containerPortal = 2439CC1E1E665858003326FB /* PinLayout.xcodeproj */;
65+
proxyType = 2;
66+
remoteGlobalIDString = 244DF2F81EF46C500090508B;
67+
remoteInfo = PinLayoutTVOS;
68+
};
5969
/* End PBXContainerItemProxy section */
6070

6171
/* Begin PBXCopyFilesBuildPhase section */
@@ -84,6 +94,8 @@
8494
249326881EEEEE3D00BCB814 /* Stylesheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Stylesheet.swift; sourceTree = "<group>"; };
8595
2493268B1EEEEFF100BCB814 /* BaseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = "<group>"; };
8696
2493268D1EEEF02700BCB814 /* BaseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseView.swift; sourceTree = "<group>"; };
97+
2497CFEB1EF40B9100DFD13B /* FormView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FormView.swift; path = Form/FormView.swift; sourceTree = "<group>"; };
98+
2497CFEC1EF40B9100DFD13B /* FormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FormViewController.swift; path = Form/FormViewController.swift; sourceTree = "<group>"; };
8799
249EFE3F1E64FAFE00165E39 /* PinLayoutSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PinLayoutSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
88100
249EFE421E64FAFE00165E39 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
89101
249EFE491E64FAFE00165E39 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@@ -95,6 +107,7 @@
95107
24A9C1F81EF0619C00F2CF64 /* MethodGroupHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MethodGroupHeader.swift; sourceTree = "<group>"; };
96108
24A9C2011EF16A3E00F2CF64 /* AutoAdjustingSizeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AutoAdjustingSizeView.swift; path = AutoAdjustingSize/AutoAdjustingSizeView.swift; sourceTree = "<group>"; };
97109
24A9C2021EF16A3E00F2CF64 /* AutoAdjustingSizeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AutoAdjustingSizeViewController.swift; path = AutoAdjustingSize/AutoAdjustingSizeViewController.swift; sourceTree = "<group>"; };
110+
24DA374A1EF7F90600D1AB2F /* BaseFormView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFormView.swift; sourceTree = "<group>"; };
98111
24E654811E69041B00A72A8B /* Expect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Expect.swift; sourceTree = "<group>"; };
99112
24F75B591EE5644E008DB567 /* IntroView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IntroView.swift; path = Intro/IntroView.swift; sourceTree = "<group>"; };
100113
24F75B5A1EE5644E008DB567 /* IntroViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IntroViewController.swift; path = Intro/IntroViewController.swift; sourceTree = "<group>"; };
@@ -129,6 +142,7 @@
129142
children = (
130143
2439CC241E665858003326FB /* PinLayout.framework */,
131144
2439CC261E665858003326FB /* PinLayoutTests.xctest */,
145+
24DA374F1EF7F90700D1AB2F /* PinLayoutTVOS.framework */,
132146
);
133147
name = Products;
134148
sourceTree = "<group>";
@@ -147,6 +161,7 @@
147161
isa = PBXGroup;
148162
children = (
149163
DF66F9D61E8493D400ADB8D5 /* AutoAdjustingSizeView */,
164+
2497CFEA1EF40B8100DFD13B /* Form */,
150165
24F75B581EE5642C008DB567 /* Intro */,
151166
2439CC5F1E665F66003326FB /* MultiRelativeView */,
152167
2439CC631E66606D003326FB /* RelativeView */,
@@ -159,6 +174,7 @@
159174
isa = PBXGroup;
160175
children = (
161176
2493268B1EEEEFF100BCB814 /* BaseViewController.swift */,
177+
24DA374A1EF7F90600D1AB2F /* BaseFormView.swift */,
162178
2493268D1EEEF02700BCB814 /* BaseView.swift */,
163179
2439CC381E665C6B003326FB /* BasicView.swift */,
164180
249326881EEEEE3D00BCB814 /* Stylesheet.swift */,
@@ -203,6 +219,15 @@
203219
path = "Supporting Files";
204220
sourceTree = "<group>";
205221
};
222+
2497CFEA1EF40B8100DFD13B /* Form */ = {
223+
isa = PBXGroup;
224+
children = (
225+
2497CFEB1EF40B9100DFD13B /* FormView.swift */,
226+
2497CFEC1EF40B9100DFD13B /* FormViewController.swift */,
227+
);
228+
name = Form;
229+
sourceTree = "<group>";
230+
};
206231
249EFE361E64FAFE00165E39 = {
207232
isa = PBXGroup;
208233
children = (
@@ -369,6 +394,13 @@
369394
remoteRef = 2439CC251E665858003326FB /* PBXContainerItemProxy */;
370395
sourceTree = BUILT_PRODUCTS_DIR;
371396
};
397+
24DA374F1EF7F90700D1AB2F /* PinLayoutTVOS.framework */ = {
398+
isa = PBXReferenceProxy;
399+
fileType = wrapper.framework;
400+
path = PinLayoutTVOS.framework;
401+
remoteRef = 24DA374E1EF7F90700D1AB2F /* PBXContainerItemProxy */;
402+
sourceTree = BUILT_PRODUCTS_DIR;
403+
};
372404
/* End PBXReferenceProxy section */
373405

374406
/* Begin PBXResourcesBuildPhase section */
@@ -450,6 +482,7 @@
450482
isa = PBXSourcesBuildPhase;
451483
buildActionMask = 2147483647;
452484
files = (
485+
24DA374B1EF7F90600D1AB2F /* BaseFormView.swift in Sources */,
453486
24F75B5C1EE5644E008DB567 /* IntroViewController.swift in Sources */,
454487
2439CC541E665C6B003326FB /* RelativeView.swift in Sources */,
455488
2439CC551E665C6B003326FB /* RelativeViewController.swift in Sources */,
@@ -459,8 +492,10 @@
459492
2439CC4B1E665C6B003326FB /* BasicView.swift in Sources */,
460493
24A9C1F61EF054BF00F2CF64 /* MethodCell.swift in Sources */,
461494
24A9C2041EF16A3E00F2CF64 /* AutoAdjustingSizeViewController.swift in Sources */,
495+
2497CFED1EF40B9100DFD13B /* FormView.swift in Sources */,
462496
24F75B5B1EE5644E008DB567 /* IntroView.swift in Sources */,
463497
249EFE431E64FAFE00165E39 /* AppDelegate.swift in Sources */,
498+
2497CFEE1EF40B9100DFD13B /* FormViewController.swift in Sources */,
464499
24A9C1F31EF0542F00F2CF64 /* TableViewExampleViewController.swift in Sources */,
465500
2439CC361E665BF6003326FB /* MenuViewController.swift in Sources */,
466501
2439CC531E665C6B003326FB /* MultiRelativeViewController.swift in Sources */,
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright (c) 2017, Mirego
2+
// All rights reserved.
3+
//
4+
// Redistribution and use in source and binary forms, with or without
5+
// modification, are permitted provided that the following conditions are met:
6+
//
7+
// - Redistributions of source code must retain the above copyright notice,
8+
// this list of conditions and the following disclaimer.
9+
// - Redistributions in binary form must reproduce the above copyright notice,
10+
// this list of conditions and the following disclaimer in the documentation
11+
// and/or other materials provided with the distribution.
12+
// - Neither the name of the Mirego nor the names of its contributors may
13+
// be used to endorse or promote products derived from this software without
14+
// specific prior written permission.
15+
//
16+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
// POSSIBILITY OF SUCH DAMAGE.
27+
import UIKit
28+
29+
class BaseFormView: BaseView {
30+
let formScrollView = UIScrollView()
31+
32+
override init() {
33+
super.init()
34+
35+
formScrollView.showsVerticalScrollIndicator = false
36+
formScrollView.keyboardDismissMode = .onDrag
37+
formScrollView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapScrollView)))
38+
addSubview(formScrollView)
39+
40+
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
41+
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: .UIKeyboardWillHide, object: nil)
42+
}
43+
44+
required init(coder aDecoder: NSCoder) {
45+
fatalError("init(coder:) has not been implemented")
46+
}
47+
48+
deinit {
49+
NotificationCenter.default.removeObserver(self)
50+
}
51+
52+
override func layoutSubviews() {
53+
super.layoutSubviews()
54+
55+
formScrollView.pin.topLeft().bottomRight()
56+
}
57+
58+
override func didChangeLayoutGuides() {
59+
super.didChangeLayoutGuides()
60+
formScrollView.contentOffset = CGPoint(x: 0, y: topLayoutGuide)
61+
}
62+
63+
internal func keyboardWillShow(notification: Notification) {
64+
guard let sizeValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
65+
setFormScrollView(bottomInset: sizeValue.cgRectValue.height)
66+
}
67+
68+
internal func keyboardWillHide(notification: Notification) {
69+
resetScrollOffset()
70+
}
71+
72+
internal func didTapScrollView() {
73+
endEditing(true)
74+
resetScrollOffset()
75+
}
76+
77+
fileprivate func resetScrollOffset() {
78+
guard formScrollView.contentInset != .zero else { return }
79+
setFormScrollView(bottomInset: 0)
80+
}
81+
82+
fileprivate func setFormScrollView(bottomInset: CGFloat) {
83+
formScrollView.contentInset = UIEdgeInsets(top: formScrollView.contentInset.top, left: 0,
84+
bottom: bottomInset, right: 0)
85+
}
86+
}

Example/PinLayoutSample/UI/Common/BaseView.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ class BaseView: UIView {
3131
fileprivate (set) var topLayoutGuide: CGFloat = 0
3232
fileprivate (set) var bottomLayoutGuide: CGFloat = 0
3333

34+
init() {
35+
super.init(frame: .zero)
36+
backgroundColor = .white
37+
}
38+
39+
required init?(coder aDecoder: NSCoder) {
40+
fatalError("init(coder:) has not been implemented")
41+
}
42+
3443
func setLayoutGuides(top: CGFloat, bottom: CGFloat) {
3544
var didChange = false
3645

Example/PinLayoutSample/UI/Main/MenuView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ class MenuView: BaseView {
3737
fileprivate let tableView = UITableView()
3838
fileprivate let cellIdentifier = "MenuViewCell"
3939

40-
init() {
41-
super.init(frame: .zero)
40+
override init() {
41+
super.init()
4242

4343
backgroundColor = .red
4444

Example/PinLayoutSample/UI/Main/MenuViewController.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import UIKit
3030
enum PageType: Int {
3131
case intro
3232
case tableView
33+
case form
3334
case relativePositions
3435
case multiRelativePositions
3536
case autoAdjustingSize
@@ -40,6 +41,7 @@ enum PageType: Int {
4041
switch self {
4142
case .intro: return "PinLayout's Intro"
4243
case .tableView: return "TableView with variable cell's height"
44+
case .form: return "Form Example"
4345
case .relativePositions: return "Relative Positionning"
4446
case .multiRelativePositions: return "Multiple Relatives Positionning"
4547
case .autoAdjustingSize: return "Auto adjusting size"
@@ -51,6 +53,7 @@ enum PageType: Int {
5153
switch self {
5254
case .intro: return IntroViewController(pageType: self)
5355
case .tableView: return TableViewExampleViewController(pageType: self)
56+
case .form: return FormViewController(pageType: self)
5457
case .relativePositions: return RelativeViewController(pageType: self)
5558
case .multiRelativePositions: return MultiRelativeViewController(pageType: self)
5659
case .autoAdjustingSize: return AutoAdjustingSizeViewController(pageType: self)
@@ -80,7 +83,7 @@ class MenuViewController: BaseViewController {
8083

8184
// override func viewDidAppear(_ animated: Bool) {
8285
// super.viewDidAppear(true)
83-
// didSelect(pageType: .tableView)
86+
// didSelect(pageType: .form)
8487
// }
8588
}
8689

Example/PinLayoutSample/UI/Tests/AutoAdjustingSize/AutoAdjustingSizeView.swift

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,8 @@ class AutoAdjustingSizeView: BaseView {
5050
var row4Item2 = BasicView(text: "50%", color: .gray)
5151
var row4Item3 = BasicView(text: "25%", color: .pinLayoutColor)
5252

53-
init() {
54-
super.init(frame: .zero)
55-
56-
backgroundColor = .white
53+
override init() {
54+
super.init()
5755

5856
contentScrollView.backgroundColor = .white
5957
addSubview(contentScrollView)
@@ -84,11 +82,9 @@ class AutoAdjustingSizeView: BaseView {
8482
override func layoutSubviews() {
8583
super.layoutSubviews()
8684

87-
contentScrollView.pin.topLeft().bottomRight().marginTop(topLayoutGuide)
88-
contentScrollView.contentSize = CGSize(width: frame.width, height: frame.height * 2)
89-
contentScrollView.contentInset = .zero
85+
contentScrollView.pin.topLeft().bottomRight()
9086

91-
row1.pin.topLeft().right().height(40).marginTop(10)
87+
row1.pin.topLeft().right().height(40)
9288
row1Item1.pin.topLeft().bottom().width(50).margin(2)
9389
row1Item2.pin.right(of: row1Item1, aligned: .top).bottomRight().margin(0, 2, 2, 2)
9490

@@ -105,5 +101,7 @@ class AutoAdjustingSizeView: BaseView {
105101
row4Item1.pin.topLeft().width(25%).bottom().margin(2)
106102
row4Item2.pin.right(of: row4Item1, aligned: .top).width(50%).bottom().margin(0, 2, 2, 2)
107103
row4Item3.pin.right(of: row4Item2, aligned: .top).bottomRight().margin(0, 2, 2, 2)
104+
105+
contentScrollView.contentSize = CGSize(width: frame.width, height: row4.frame.maxY)
108106
}
109107
}

0 commit comments

Comments
 (0)