Skip to content

Commit 22cb4d8

Browse files
author
Luc Dion
authored
Merge pull request #67 from mirego/add_rtl_support
Add left to right (LTR) and right to left (RTL) language support + renamed 2 anchors's name
2 parents 2223674 + 75aa3af commit 22cb4d8

20 files changed

+1605
-336
lines changed

.codeclimate.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ ratings:
77
- "**.swift"
88

99
exclude_paths:
10-
- PinLayoutTests
10+
- Tests
1111
- Example
1212
- Pods
1313
- data

Example/PinLayoutSample.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
24CB999C1F29059B004EA7FB /* AdjustToContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24CB999A1F29059B004EA7FB /* AdjustToContainerView.swift */; };
3434
24CB999D1F29059B004EA7FB /* AdjustToContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24CB999B1F29059B004EA7FB /* AdjustToContainerViewController.swift */; };
3535
24CB99A01F290664004EA7FB /* ChoiceSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24CB999F1F290664004EA7FB /* ChoiceSelectorView.swift */; };
36+
24D18D1D1F3DED0D008129EF /* IntroRTLView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D1B1F3DED0D008129EF /* IntroRTLView.swift */; };
37+
24D18D1E1F3DED0D008129EF /* IntroRTLViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D1C1F3DED0D008129EF /* IntroRTLViewController.swift */; };
3638
24DA374B1EF7F90600D1AB2F /* BaseFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24DA374A1EF7F90600D1AB2F /* BaseFormView.swift */; };
3739
24E654821E69041B00A72A8B /* Expect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24E654811E69041B00A72A8B /* Expect.swift */; };
3840
24F75B5B1EE5644E008DB567 /* IntroView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F75B591EE5644E008DB567 /* IntroView.swift */; };
@@ -113,6 +115,8 @@
113115
24CB999A1F29059B004EA7FB /* AdjustToContainerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AdjustToContainerView.swift; path = AdjustToContainer/AdjustToContainerView.swift; sourceTree = "<group>"; };
114116
24CB999B1F29059B004EA7FB /* AdjustToContainerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AdjustToContainerViewController.swift; path = AdjustToContainer/AdjustToContainerViewController.swift; sourceTree = "<group>"; };
115117
24CB999F1F290664004EA7FB /* ChoiceSelectorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ChoiceSelectorView.swift; path = AdjustToContainer/Subviews/ChoiceSelectorView.swift; sourceTree = "<group>"; };
118+
24D18D1B1F3DED0D008129EF /* IntroRTLView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IntroRTLView.swift; path = IntroRTL/IntroRTLView.swift; sourceTree = "<group>"; };
119+
24D18D1C1F3DED0D008129EF /* IntroRTLViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IntroRTLViewController.swift; path = IntroRTL/IntroRTLViewController.swift; sourceTree = "<group>"; };
116120
24DA374A1EF7F90600D1AB2F /* BaseFormView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFormView.swift; sourceTree = "<group>"; };
117121
24E654811E69041B00A72A8B /* Expect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Expect.swift; sourceTree = "<group>"; };
118122
24F75B591EE5644E008DB567 /* IntroView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IntroView.swift; path = Intro/IntroView.swift; sourceTree = "<group>"; };
@@ -170,6 +174,7 @@
170174
DF66F9D61E8493D400ADB8D5 /* AutoAdjustingSizeView */,
171175
2497CFEA1EF40B8100DFD13B /* Form */,
172176
24F75B581EE5642C008DB567 /* Intro */,
177+
24D18D181F3DECD6008129EF /* IntroRTL */,
173178
2439CC5F1E665F66003326FB /* MultiRelativeView */,
174179
2439CC631E66606D003326FB /* RelativeView */,
175180
24A9C1EF1EF0542500F2CF64 /* TableViewExample */,
@@ -302,6 +307,15 @@
302307
name = Subviews;
303308
sourceTree = "<group>";
304309
};
310+
24D18D181F3DECD6008129EF /* IntroRTL */ = {
311+
isa = PBXGroup;
312+
children = (
313+
24D18D1B1F3DED0D008129EF /* IntroRTLView.swift */,
314+
24D18D1C1F3DED0D008129EF /* IntroRTLViewController.swift */,
315+
);
316+
name = IntroRTL;
317+
sourceTree = "<group>";
318+
};
305319
24E654801E69040000A72A8B /* Domain */ = {
306320
isa = PBXGroup;
307321
children = (
@@ -511,7 +525,9 @@
511525
24F75B5C1EE5644E008DB567 /* IntroViewController.swift in Sources */,
512526
2439CC541E665C6B003326FB /* RelativeView.swift in Sources */,
513527
2439CC551E665C6B003326FB /* RelativeViewController.swift in Sources */,
528+
24D18D1E1F3DED0D008129EF /* IntroRTLViewController.swift in Sources */,
514529
24A9C2031EF16A3E00F2CF64 /* AutoAdjustingSizeView.swift in Sources */,
530+
24D18D1D1F3DED0D008129EF /* IntroRTLView.swift in Sources */,
515531
2439CC351E665BF6003326FB /* MenuView.swift in Sources */,
516532
2493268C1EEEEFF100BCB814 /* BaseViewController.swift in Sources */,
517533
2439CC4B1E665C6B003326FB /* BasicView.swift in Sources */,

Example/PinLayoutSample/UI/Main/MenuViewController.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ enum PageType: Int {
3535
case relativePositions
3636
case multiRelativePositions
3737
case autoAdjustingSize
38+
case introRTL
3839

3940
case count
4041

@@ -47,6 +48,7 @@ enum PageType: Int {
4748
case .relativePositions: return "Relative Positionning"
4849
case .multiRelativePositions: return "Multiple Relatives Positionning"
4950
case .autoAdjustingSize: return "Auto adjusting size"
51+
case .introRTL: return "PinLayout's right-to-left language support"
5052
case .count: return ""
5153
}
5254
}
@@ -60,6 +62,7 @@ enum PageType: Int {
6062
case .relativePositions: return RelativeViewController(pageType: self)
6163
case .multiRelativePositions: return MultiRelativeViewController(pageType: self)
6264
case .autoAdjustingSize: return AutoAdjustingSizeViewController(pageType: self)
65+
case .introRTL: return IntroRTLViewController(pageType: self)
6366
case .count: return UIViewController()
6467
}
6568
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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+
28+
import UIKit
29+
import PinLayout
30+
31+
class IntroRTLView: BaseView {
32+
33+
fileprivate let container = UIView()
34+
fileprivate let logo = UIImageView(image: UIImage(named: "PinLayout-logo"))
35+
fileprivate let segmented = UISegmentedControl(items: ["Intro", "1", "2"])
36+
fileprivate let textLabel = UILabel()
37+
fileprivate let separatorView = UIView()
38+
39+
override init() {
40+
super.init()
41+
42+
// PinLayout will detect automatically the layout direction based on
43+
// `UIView.userInterfaceLayoutDirection(for: semanticContentAttribute)` (>= iOS 9) or
44+
// `UIApplication.shared.userInterfaceLayoutDirection` (< iOS 9)
45+
Pin.layoutDirection(.auto)
46+
47+
logo.contentMode = .scaleAspectFit
48+
addSubview(logo)
49+
50+
segmented.selectedSegmentIndex = 0
51+
segmented.tintColor = .pinLayoutColor
52+
addSubview(segmented)
53+
54+
textLabel.text = "Swift manual views layouting without auto layout, no magic, pure code, full control. Concise syntax, readable & chainable.\n\nSwift manual views layouting without auto layout, no magic, pure code, full control. Concise syntax, readable & chainable."
55+
textLabel.font = .systemFont(ofSize: 14)
56+
textLabel.numberOfLines = 0
57+
textLabel.lineBreakMode = .byWordWrapping
58+
addSubview(textLabel)
59+
60+
separatorView.pin.height(1)
61+
separatorView.backgroundColor = .pinLayoutColor
62+
addSubview(separatorView)
63+
}
64+
65+
required init?(coder aDecoder: NSCoder) {
66+
super.init(coder: aDecoder)
67+
}
68+
69+
override func layoutSubviews() {
70+
super.layoutSubviews()
71+
72+
logo.pin.topStart().size(100).margin(topLayoutGuide + 10, 10, 10, 10)
73+
segmented.pin.after(of: logo, aligned: .top).end().marginHorizontal(10)
74+
textLabel.pin.below(of: segmented, aligned: .start).width(of: segmented).pinEdges().marginTop(10).sizeToFit()
75+
separatorView.pin.below(of: [logo, textLabel], aligned: .start).end(to: segmented.edge.end).marginTop(10)
76+
}
77+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
28+
import UIKit
29+
30+
class IntroRTLViewController: BaseViewController {
31+
fileprivate var mainView: IntroRTLView {
32+
return self.view as! IntroRTLView
33+
}
34+
35+
init(pageType: PageType) {
36+
super.init(nibName: nil, bundle: nil)
37+
38+
title = pageType.text
39+
}
40+
41+
required init?(coder aDecoder: NSCoder) {
42+
super.init(coder: aDecoder)
43+
}
44+
45+
override func loadView() {
46+
view = IntroRTLView()
47+
}
48+
}

PinLayout.podspec

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
1616
#
1717

1818
s.name = "PinLayout"
19-
s.version = "1.1.6"
19+
s.version = "1.2.0"
2020
s.summary = "Fast Swift UIViews layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainable."
2121

2222
# This description is used to generate tags and improve search results.
@@ -25,46 +25,11 @@ Pod::Spec.new do |s|
2525
# * Write the description between the DESC delimiters below.
2626
# * Finally, don't worry about the indent, CocoaPods strips it!
2727
s.description = <<-DESC
28-
29-
* Layout one view at a time.
30-
* Layout most views using a single line
31-
* Stateless
32-
* The layout system doesn’t add any stored properties to UIViews. It simply compute the UIView.frame property, one view at a time.
33-
* Since it is stateless, it can be used with any other layout framework without conflicts.
34-
Each view can use the layout system that better suit it (PinLayout, constraint, flexbox, grids, …)
35-
A view can be layouted using PinLayout and later with another method.
36-
* REWORK THAT!!! Stateless also means that if a view reference other views, the view should be re-layouted in layoutSubViews() layouted with PinLayout use other views as referenced view change (size/position)
37-
38-
* No constraints
39-
* Constraints are very verbose and hard for a human brains to understand. Too much information.
40-
* PinLayout positions views as a designer would explain it (eg: “The TextField is below the Label, aligned left, and is its width match the other view’s width“).
41-
* No priorities, simply layout views in the order that make sense. No priority required.
42-
43-
* Before applying the new sets of attributes, PinLayout always start with the view’s current frame. So it’s possible to set the view’s size during the initialization (ex: view.pin.width(100).height(200)), and later only position the view (ex: view.pin.top(10).left(20))
44-
45-
* Minimize as much as possible calculations and constants when layouting views.
46-
47-
* Methods matches as much as possible other layouting system, including CSS, flexbox, reactive Flexbox, …
48-
* margin, marginHorizontal, marginVertical, marginTop, marginLeft, marginBottom, marginRight
49-
* top, left, bottom, right, width, height
50-
* As in CSS and flexbox, right and bottom coordinates are offset from container’s view right and bottom edges.
51-
52-
* Shorter possible commands to layout views, but keeping english phrasing almost valid.
28+
* Support left to right (LTR) and right to left (RTL) languages.
5329
DESC
5430

5531
s.homepage = "https://mirego.github.io/PinLayout/"
56-
# s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
57-
58-
59-
# ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
60-
#
61-
# Licensing your code is important. See http://choosealicense.com for more info.
62-
# CocoaPods will detect a license file if there is a named LICENSE*
63-
# Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
64-
#
65-
6632
s.license = "BSD 3-clause"
67-
# s.license = { :type => "MIT", :file => "FILE_LICENSE" }
6833

6934

7035
# ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
@@ -78,8 +43,8 @@ A view can be layouted using PinLayout and later with another method.
7843
#
7944

8045
s.author = {
81-
"Luc Dion" => "[email protected]"
82-
# TODO Add more
46+
"Luc Dion" => "[email protected]",
47+
"Luc Dion" => "[email protected]`
8348
}
8449
8550
# ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #

0 commit comments

Comments
 (0)