Skip to content

Commit e0b3ca3

Browse files
author
Luc Dion
committed
Initial commit for pin.readableMargins
1 parent bd9c81a commit e0b3ca3

File tree

7 files changed

+312
-4
lines changed

7 files changed

+312
-4
lines changed

Example/PinLayoutSample.xcodeproj/project.pbxproj

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,12 @@
5151
DF4C1AAA205AF10900DED50B /* RoundedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF4C1AA7205AF10900DED50B /* RoundedButton.swift */; };
5252
DF4C1AAE205AF78A00DED50B /* SafeAreaCornersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF4C1AAC205AF78A00DED50B /* SafeAreaCornersViewController.swift */; };
5353
DF4C1AAF205AF78A00DED50B /* SafeAreaCornersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF4C1AAD205AF78A00DED50B /* SafeAreaCornersView.swift */; };
54+
DFBCAEFB213012930025F7BF /* MethodReadableInsetsGroupHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFBCAEF9213012930025F7BF /* MethodReadableInsetsGroupHeader.swift */; };
55+
DFBCAEFC213012930025F7BF /* MethodReadableInsetsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFBCAEFA213012930025F7BF /* MethodReadableInsetsCell.swift */; };
5456
DFD27841211B1A710056BD93 /* UINavigationController+Orientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFD27840211B1A700056BD93 /* UINavigationController+Orientation.swift */; };
5557
DFD27848211B1D090056BD93 /* UITabBarController+Orientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFD27847211B1D090056BD93 /* UITabBarController+Orientation.swift */; };
58+
DFD31BA0212EE4F200566CA4 /* TableViewReadableContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFD31B9E212EE4F100566CA4 /* TableViewReadableContentView.swift */; };
59+
DFD31BA1212EE4F200566CA4 /* TableViewReadableContentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFD31B9F212EE4F200566CA4 /* TableViewReadableContentViewController.swift */; };
5660
DFEAF74A20C9648A00E33147 /* WrapContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFEAF74920C9648A00E33147 /* WrapContentView.swift */; };
5761
DFEAF74C20C9649F00E33147 /* WrapContentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFEAF74B20C9649F00E33147 /* WrapContentViewController.swift */; };
5862
/* End PBXBuildFile section */
@@ -185,8 +189,12 @@
185189
DF4C1AA7205AF10900DED50B /* RoundedButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoundedButton.swift; sourceTree = "<group>"; };
186190
DF4C1AAC205AF78A00DED50B /* SafeAreaCornersViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SafeAreaCornersViewController.swift; sourceTree = "<group>"; };
187191
DF4C1AAD205AF78A00DED50B /* SafeAreaCornersView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SafeAreaCornersView.swift; sourceTree = "<group>"; };
192+
DFBCAEF9213012930025F7BF /* MethodReadableInsetsGroupHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MethodReadableInsetsGroupHeader.swift; sourceTree = "<group>"; };
193+
DFBCAEFA213012930025F7BF /* MethodReadableInsetsCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MethodReadableInsetsCell.swift; sourceTree = "<group>"; };
188194
DFD27840211B1A700056BD93 /* UINavigationController+Orientation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Orientation.swift"; sourceTree = "<group>"; };
189195
DFD27847211B1D090056BD93 /* UITabBarController+Orientation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITabBarController+Orientation.swift"; sourceTree = "<group>"; };
196+
DFD31B9E212EE4F100566CA4 /* TableViewReadableContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewReadableContentView.swift; sourceTree = "<group>"; };
197+
DFD31B9F212EE4F200566CA4 /* TableViewReadableContentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewReadableContentViewController.swift; sourceTree = "<group>"; };
190198
DFEAF74920C9648A00E33147 /* WrapContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WrapContentView.swift; sourceTree = "<group>"; };
191199
DFEAF74B20C9649F00E33147 /* WrapContentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WrapContentViewController.swift; sourceTree = "<group>"; };
192200
/* End PBXFileReference section */
@@ -258,11 +266,12 @@
258266
DF4C1A9F205AEDFC00DED50B /* SafeArea */,
259267
DFEAF71520C840F300E33147 /* WrapContent */,
260268
DF3908912118FFF20049FD56 /* Animations */,
269+
2439CC631E66606D003326FB /* RelativeView */,
270+
2439CC5F1E665F66003326FB /* MultiRelativeView */,
261271
2497CFEA1EF40B8100DFD13B /* Form */,
272+
DFD31B9D212EE4D600566CA4 /* ReadableMargins */,
262273
24D18D181F3DECD6008129EF /* IntroRTL */,
263274
2416376F1F8E4BC200EE703A /* IntroObjectiveC */,
264-
2439CC5F1E665F66003326FB /* MultiRelativeView */,
265-
2439CC631E66606D003326FB /* RelativeView */,
266275
24CD1E8D1F8E4B0A00C3A54D /* PinLayoutSample-Bridging-Header.h */,
267276
);
268277
path = Examples;
@@ -460,6 +469,25 @@
460469
path = AutoAdjustingSize;
461470
sourceTree = "<group>";
462471
};
472+
DFBCAEF82130127F0025F7BF /* Cells */ = {
473+
isa = PBXGroup;
474+
children = (
475+
DFBCAEF9213012930025F7BF /* MethodReadableInsetsGroupHeader.swift */,
476+
DFBCAEFA213012930025F7BF /* MethodReadableInsetsCell.swift */,
477+
);
478+
path = Cells;
479+
sourceTree = "<group>";
480+
};
481+
DFD31B9D212EE4D600566CA4 /* ReadableMargins */ = {
482+
isa = PBXGroup;
483+
children = (
484+
DFBCAEF82130127F0025F7BF /* Cells */,
485+
DFD31B9E212EE4F100566CA4 /* TableViewReadableContentView.swift */,
486+
DFD31B9F212EE4F200566CA4 /* TableViewReadableContentViewController.swift */,
487+
);
488+
path = ReadableMargins;
489+
sourceTree = "<group>";
490+
};
463491
DFEAF71520C840F300E33147 /* WrapContent */ = {
464492
isa = PBXGroup;
465493
children = (
@@ -663,6 +691,7 @@
663691
files = (
664692
DF4C1AAF205AF78A00DED50B /* SafeAreaCornersView.swift in Sources */,
665693
24F246141FA8D57100B6332E /* UIImageView+Download.swift in Sources */,
694+
DFBCAEFC213012930025F7BF /* MethodReadableInsetsCell.swift in Sources */,
666695
24DA374B1EF7F90600D1AB2F /* BaseFormView.swift in Sources */,
667696
24F75B5C1EE5644E008DB567 /* IntroViewController.swift in Sources */,
668697
241637741F8E4BC200EE703A /* IntroObjectiveCViewController.m in Sources */,
@@ -689,6 +718,8 @@
689718
DF4C1AA5205AEDFC00DED50B /* SafeAreaViewController.swift in Sources */,
690719
DFEAF74A20C9648A00E33147 /* WrapContentView.swift in Sources */,
691720
249EFE431E64FAFE00165E39 /* AppDelegate.swift in Sources */,
721+
DFD31BA1212EE4F200566CA4 /* TableViewReadableContentViewController.swift in Sources */,
722+
DFBCAEFB213012930025F7BF /* MethodReadableInsetsGroupHeader.swift in Sources */,
692723
2497CFEE1EF40B9100DFD13B /* FormViewController.swift in Sources */,
693724
24A9C1F31EF0542F00F2CF64 /* TableViewExampleViewController.swift in Sources */,
694725
24CB99981F290540004EA7FB /* MethodGroupHeader.swift in Sources */,
@@ -699,6 +730,7 @@
699730
241637771F8E4F9100EE703A /* IntroObjectiveCView.m in Sources */,
700731
24CB99A01F290664004EA7FB /* ChoiceSelectorView.swift in Sources */,
701732
249326891EEEEE3D00BCB814 /* Stylesheet.swift in Sources */,
733+
DFD31BA0212EE4F200566CA4 /* TableViewReadableContentView.swift in Sources */,
702734
DF39089A211900480049FD56 /* AnimationsViewController.swift in Sources */,
703735
2439CC521E665C6B003326FB /* MultiRelativeView.swift in Sources */,
704736
24F246101FA8D4D100B6332E /* CollectionViewExampleView.swift in Sources */,
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import Foundation
2+
3+
class MethodReadableInsetsCell: UITableViewCell {
4+
static let reuseIdentifier = "MethodReadableInsetsCell"
5+
6+
private let iconImageView = UIImageView(image: UIImage(named: "method"))
7+
private let nameLabel = UILabel()
8+
private let descriptionLabel = UILabel()
9+
private let margin: CGFloat = 10
10+
11+
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
12+
super.init(style: style, reuseIdentifier: reuseIdentifier)
13+
14+
selectionStyle = .none
15+
separatorInset = .zero
16+
preservesSuperviewLayoutMargins = false
17+
18+
contentView.addSubview(iconImageView)
19+
20+
nameLabel.font = UIFont.boldSystemFont(ofSize: 14)
21+
nameLabel.lineBreakMode = .byTruncatingTail
22+
contentView.addSubview(nameLabel)
23+
24+
descriptionLabel.font = UIFont.systemFont(ofSize: 12)
25+
descriptionLabel.numberOfLines = 0
26+
contentView.addSubview(descriptionLabel)
27+
}
28+
29+
required init?(coder aDecoder: NSCoder) {
30+
super.init(coder: aDecoder)
31+
}
32+
33+
func configure(method: Method) {
34+
nameLabel.text = method.name
35+
descriptionLabel.text = method.description
36+
}
37+
38+
override func layoutSubviews() {
39+
super.layoutSubviews()
40+
layout()
41+
}
42+
43+
private func layout() {
44+
// 1) Layout the contentView
45+
contentView.pin.top(layoutMargins).horizontally(pin.readableMargins)
46+
47+
// 2) Layout contentView's childs
48+
iconImageView.pin.top().left().size(30)
49+
nameLabel.pin.after(of: iconImageView, aligned: .center).right().marginHorizontal(margin).sizeToFit(.width)
50+
descriptionLabel.pin.below(of: [iconImageView, nameLabel]).horizontally().marginTop(margin).sizeToFit(.width)
51+
52+
// 3) Adjust the contentView size to wrap its childs
53+
contentView.pin.wrapContent(.vertically)
54+
}
55+
56+
override func sizeThatFits(_ size: CGSize) -> CGSize {
57+
// 1) Set the width to the specified size parameter
58+
pin.width(size.width)
59+
60+
// 2) Layout the contentView's controls
61+
layout()
62+
63+
// 3) Returns a size that contains all views
64+
return CGSize(width: size.width, height: contentView.frame.maxY + margin + layoutMargins.bottom)
65+
}
66+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (c) 2017 Luc Dion
2+
// Permission is hereby granted, free of charge, to any person obtaining a copy
3+
// of this software and associated documentation files (the "Software"), to deal
4+
// in the Software without restriction, including without limitation the rights
5+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6+
// copies of the Software, and to permit persons to whom the Software is
7+
// furnished to do so, subject to the following conditions:
8+
//
9+
// The above copyright notice and this permission notice shall be included in
10+
// all copies or substantial portions of the Software.
11+
//
12+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18+
// THE SOFTWARE.
19+
20+
import UIKit
21+
22+
class MethodReadableInsetsGroupHeader: UITableViewHeaderFooterView {
23+
static let reuseIdentifier = "MethodReadableInsetsGroupHeader"
24+
static let height: CGFloat = 50
25+
26+
fileprivate let titleLabel = UILabel()
27+
28+
override init(reuseIdentifier: String?) {
29+
super.init(reuseIdentifier: reuseIdentifier)
30+
31+
preservesSuperviewLayoutMargins = false
32+
33+
titleLabel.font = .systemFont(ofSize: 20)
34+
contentView.addSubview(titleLabel)
35+
}
36+
37+
required init?(coder aDecoder: NSCoder) {
38+
fatalError("init(coder:) has not been implemented")
39+
}
40+
41+
func configure(title: String) {
42+
titleLabel.text = title
43+
}
44+
45+
override func layoutSubviews() {
46+
super.layoutSubviews()
47+
48+
contentView.pin.horizontally(pin.readableMargins)
49+
titleLabel.pin.horizontally().vCenter().sizeToFit(.width)
50+
}
51+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright (c) 2017 Luc Dion
2+
// Permission is hereby granted, free of charge, to any person obtaining a copy
3+
// of this software and associated documentation files (the "Software"), to deal
4+
// in the Software without restriction, including without limitation the rights
5+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6+
// copies of the Software, and to permit persons to whom the Software is
7+
// furnished to do so, subject to the following conditions:
8+
//
9+
// The above copyright notice and this permission notice shall be included in
10+
// all copies or substantial portions of the Software.
11+
//
12+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18+
// THE SOFTWARE.
19+
20+
import UIKit
21+
22+
class TableViewReadableContentView: UIView {
23+
24+
fileprivate let tableView = UITableView()
25+
fileprivate let methodCellTemplate = MethodReadableInsetsCell()
26+
fileprivate var methods: [Method] = []
27+
28+
init() {
29+
super.init(frame: .zero)
30+
backgroundColor = .white
31+
32+
tableView.dataSource = self
33+
tableView.delegate = self
34+
tableView.tableFooterView = UIView()
35+
tableView.register(MethodReadableInsetsCell.self, forCellReuseIdentifier: MethodReadableInsetsCell.reuseIdentifier)
36+
tableView.register(MethodReadableInsetsGroupHeader.self, forHeaderFooterViewReuseIdentifier: MethodReadableInsetsGroupHeader.reuseIdentifier)
37+
addSubview(tableView)
38+
}
39+
40+
required init?(coder aDecoder: NSCoder) {
41+
super.init(coder: aDecoder)
42+
}
43+
44+
func configure(methods: [Method]) {
45+
self.methods = methods
46+
tableView.reloadData()
47+
}
48+
49+
override func layoutSubviews() {
50+
super.layoutSubviews()
51+
52+
tableView.pin.all()
53+
}
54+
}
55+
56+
// MARK: UITableViewDataSource, UITableViewDelegate
57+
extension TableViewReadableContentView: UITableViewDataSource, UITableViewDelegate {
58+
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
59+
return MethodReadableInsetsGroupHeader.height
60+
}
61+
62+
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
63+
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: MethodReadableInsetsGroupHeader.reuseIdentifier) as! MethodReadableInsetsGroupHeader
64+
header.configure(title: "PinLayout few methods")
65+
return header
66+
}
67+
68+
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
69+
return methods.count
70+
}
71+
72+
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
73+
let cell = tableView.dequeueReusableCell(withIdentifier: MethodReadableInsetsCell.reuseIdentifier, for: indexPath) as! MethodReadableInsetsCell
74+
cell.configure(method: methods[indexPath.row])
75+
76+
return cell
77+
}
78+
79+
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
80+
// WARNING:
81+
// Configure a MethodReadableInsetsCell and ask its size.
82+
methodCellTemplate.configure(method: methods[indexPath.row])
83+
return methodCellTemplate.sizeThatFits(CGSize(width: tableView.bounds.width, height: .greatestFiniteMagnitude)).height
84+
}
85+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) 2017 Luc Dion
2+
// Permission is hereby granted, free of charge, to any person obtaining a copy
3+
// of this software and associated documentation files (the "Software"), to deal
4+
// in the Software without restriction, including without limitation the rights
5+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6+
// copies of the Software, and to permit persons to whom the Software is
7+
// furnished to do so, subject to the following conditions:
8+
//
9+
// The above copyright notice and this permission notice shall be included in
10+
// all copies or substantial portions of the Software.
11+
//
12+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18+
// THE SOFTWARE.
19+
20+
import UIKit
21+
22+
class TableViewReadableContentViewController: UIViewController {
23+
fileprivate var mainView: TableViewReadableContentView {
24+
return self.view as! TableViewReadableContentView
25+
}
26+
27+
init(pageType: PageType) {
28+
super.init(nibName: nil, bundle: nil)
29+
30+
title = pageType.text
31+
}
32+
33+
required init?(coder aDecoder: NSCoder) {
34+
super.init(coder: aDecoder)
35+
}
36+
37+
override func loadView() {
38+
view = TableViewReadableContentView()
39+
mainView.configure(methods: [
40+
Method(name: "top(_ value: CGFloat)", description: "The value specifies the top edge distance from the superview's top edge in pixels."),
41+
Method(name: "top(_ percent: Percent)", description: "The value specifies the top edge distance from the superview's top edge in percentage of its superview's height."),
42+
Method(name: "vCenter(_ value: CGFloat)", description: "The value specifies the distance vertically of the view's center related to the superview's center in pixels."),
43+
Method(name: "vCenter(_ percent: Percent)", description: "The value specifies the distance vertically of the view's center related to the superview's center in percentage of its superview's height."),
44+
Method(name: "bottom(_ value: CGFloat)", description: "The value specifies the bottom edge distance from the superview's bottom edge in pixels."),
45+
Method(name: "bottom(_ percent: Percent)", description: "The value specifies the bottom edge distance from the superview's bottom edge in percentage of its superview's height."),
46+
47+
Method(name: "left(_ value: CGFloat)", description: "The value specifies the left edge distance from the superview's left edge in pixels. The value specifies the left edge distance from the superview's left edge in pixels."),
48+
Method(name: "left(_ percent: Percent)", description: "The value specifies the left edge distance from the superview's left edge in percentage of its superview's width."),
49+
Method(name: "hCenter(_ value: CGFloat)", description: "The value specifies the distance horizontally of the view's center related to the superview's center in pixels."),
50+
Method(name: "hCenter(_ percent: Percent)", description: "The value specifies the distance horizontally of the view's center related to the superview's center in percentage of its superview's height."),
51+
Method(name: "right(_ value: CGFloat)", description: "The value specifies the right edge distance from the superview's right edge in pixels."),
52+
Method(name: "right(_ percent: Percent)", description: "The value specifies the right edge distance from the superview's right edge in percentage of its superview's width.")
53+
])
54+
}
55+
}

0 commit comments

Comments
 (0)