rm-extensions 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -1
- data/README.md +198 -1
- data/Rakefile +15 -0
- data/app/app_delegate.rb +5 -0
- data/lib/rm-extensions/version.rb +1 -1
- data/resources/Default-568h@2x.png +0 -0
- data/spec/main_spec.rb +240 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d64ca280c2914d4e0e8ebda0af7b8900c4a71d0
|
4
|
+
data.tar.gz: 422760a452010841d394d296a59090c5967b43cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 613afb58ed64e974e51cdfc117e8627ecc381084c2d1cf6e571b2d0df6a95ba071fab76efeda59cf9eb0e6a203a3d9cce1908a5e3cdf05be8b9179e8c947c4dd
|
7
|
+
data.tar.gz: 41375da6369ebe8921c5f47d2576ea774cc353b8701774e092ffaf7df6948e6b65b87bf203f10c2a055603e324c93b8ee4689205f76f5597ee267ee38a45f86d
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,204 @@
|
|
1
1
|
RMExtensions
|
2
2
|
-----------------
|
3
3
|
|
4
|
-
#### Extensions and helpers for dealing with various areas of rubymotion.
|
4
|
+
#### Extensions and helpers for dealing with various areas of rubymotion and iOS.
|
5
|
+
|
6
|
+
## Equation-style AutoLayout Constraints
|
7
|
+
|
8
|
+
AutoLayout is a great way to lay out views, but writing constraints manually is
|
9
|
+
confusing and verbose.
|
10
|
+
|
11
|
+
Using Apple's "Visual Format Language" ASCII-inspired
|
12
|
+
strings can improve things, but it has drawbacks: **1)** It returns an array
|
13
|
+
of constraints. This means if you plan on altering one of them later, or removing
|
14
|
+
one in particular, you would have to loop through all of the constraints, testing
|
15
|
+
each one to see if its the one you want. **2)** The `options` argument adds additional
|
16
|
+
constraints. For example, if you specify NSLayoutAttributeCenterY to a horizontal string,
|
17
|
+
an additional constraint will be added for each view to set their centerY's equal to each
|
18
|
+
other. This compounds problem #1. The chances you will get an error that the layout system
|
19
|
+
cannot satisfy your constraints is probably because of these "extra" constraints. **3)**
|
20
|
+
It can't handle complex constraints, so you end up needing to supplement it with
|
21
|
+
verbose low-level constraint creation anyway.
|
22
|
+
|
23
|
+
Apple makes note of how constraints can be thought of like a linear equation:
|
24
|
+
|
25
|
+
http://developer.apple.com/library/ios/documentation/AppKit/Reference/NSLayoutConstraint_Class/NSLayoutConstraint/NSLayoutConstraint.html
|
26
|
+
|
27
|
+
**Remember the formula:**
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
view1.attr1 == view2.attr2 * multiplier + constant @ priority
|
31
|
+
```
|
32
|
+
|
33
|
+
**We can actually use this super-simple formula to write ALL of our constraints, simple OR complex!**
|
34
|
+
|
35
|
+
Once you get the hang of the formula and visualization of how the geometry works, it becomes easy to create complex layouts with little
|
36
|
+
effort. And, in my opinion, its only slightly more verbose than the visual format language, but much clearer, and you only end up
|
37
|
+
with the exact constraints you want.
|
38
|
+
|
39
|
+
Available values for `attr1` and `attr2` are:
|
40
|
+
|
41
|
+
- left
|
42
|
+
- right
|
43
|
+
- top
|
44
|
+
- bottom
|
45
|
+
- leading
|
46
|
+
- trailing
|
47
|
+
- width
|
48
|
+
- height
|
49
|
+
- centerX
|
50
|
+
- centerY
|
51
|
+
- baseline
|
52
|
+
|
53
|
+
Available `relation` values are:
|
54
|
+
|
55
|
+
- ==
|
56
|
+
- <=
|
57
|
+
- >=
|
58
|
+
|
59
|
+
Available `priority` values are:
|
60
|
+
|
61
|
+
- required (1000 is the default)
|
62
|
+
- high (750)
|
63
|
+
- low (250)
|
64
|
+
- fit (50)
|
65
|
+
- or, you can use your own value between 1-1000
|
66
|
+
|
67
|
+
|
68
|
+
### Examples
|
69
|
+
|
70
|
+
Here is a real example. The Layout instance is created just like the motion-layout gem. `layout.view` sets the view
|
71
|
+
that will act as the 'superview' to the views set in `layout.subviews`. Thats where the similarities end with
|
72
|
+
motion-layout. With RMExtensions::Layout, there are two methods: `eq` and `eqs`, short for equation and equations.
|
73
|
+
|
74
|
+
- `layout.eq` takes one string, and returns *one constraint*
|
75
|
+
- `layout.eqs` takes one string, assumes multiple constraints are separated by newlines, and returns an *array of constraints*
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
RMExtensions::Layout.new do |layout|
|
79
|
+
layout.view view
|
80
|
+
layout.subviews({
|
81
|
+
"calendar" => calendarView,
|
82
|
+
"table" => tableView,
|
83
|
+
"shadow" => line
|
84
|
+
})
|
85
|
+
|
86
|
+
layout.eqs %Q{
|
87
|
+
calendar.left == 0
|
88
|
+
calendar.right == 0
|
89
|
+
table.left == 7
|
90
|
+
table.right == -7
|
91
|
+
shadow.left == 0
|
92
|
+
shadow.right == 0
|
93
|
+
|
94
|
+
calendar.top == 0
|
95
|
+
table.top == calendar.bottom
|
96
|
+
table.bottom == 0
|
97
|
+
shadow.top == table.top
|
98
|
+
}
|
99
|
+
|
100
|
+
@calendar_height_constraint = layout.eq "calendar.height == 0"
|
101
|
+
end
|
102
|
+
```
|
103
|
+
|
104
|
+
Above, **calendar.left == 0** is short for **calendar.left == view.left * 1.0 + 0 @ 1000**. If no view2 is given, the superview ('view') is assumed.
|
105
|
+
If no multiplier is given, 1.0 is assumed. If no constant is given, 0 is assumed. If no priority is given, "required" (1000) is assumed.
|
106
|
+
The last constraint is created separately and stored in @calendar_height_constraint, because I want to be able to change the calendar's height
|
107
|
+
any time I want.
|
108
|
+
|
109
|
+
Here is another example:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
RMExtensions::Layout.new do |layout|
|
113
|
+
layout.view self
|
114
|
+
layout.subviews({
|
115
|
+
"timeLabel" => @timeLabel,
|
116
|
+
"titleLabel" => @titleLabel,
|
117
|
+
"trackingImage" => @trackingImage,
|
118
|
+
"inOutStatusInImage" => @inOutStatusInImage,
|
119
|
+
"inOutStatusOutImage" => @inOutStatusOutImage,
|
120
|
+
"plannerImage" => @plannerImage,
|
121
|
+
"shareButton" => @shareButton,
|
122
|
+
"cancelledLabel" => @cancelledLabel,
|
123
|
+
"unreadImage" => @unreadImage
|
124
|
+
})
|
125
|
+
|
126
|
+
layout.eqs %Q{
|
127
|
+
unreadImage.left == 6
|
128
|
+
unreadImage.top == 6
|
129
|
+
plannerImage.left == 14
|
130
|
+
plannerImage.centerY == 0
|
131
|
+
plannerImage.width == 30
|
132
|
+
plannerImage.height == 30
|
133
|
+
trackingImage.left == timeLabel.right + 5
|
134
|
+
inOutStatusOutImage.left == trackingImage.right + 5
|
135
|
+
inOutStatusInImage.left == inOutStatusOutImage.right + 5
|
136
|
+
timeLabel.left == plannerImage.right + 5
|
137
|
+
timeLabel.baseline == plannerImage.bottom + 1
|
138
|
+
trackingImage.centerY == timeLabel.centerY
|
139
|
+
inOutStatusOutImage.centerY == timeLabel.centerY
|
140
|
+
inOutStatusInImage.centerY == timeLabel.centerY
|
141
|
+
titleLabel.left == cancelledLabel.right
|
142
|
+
cancelledLabel.left == plannerImage.right + 5
|
143
|
+
titleLabel.top == plannerImage.top - 4
|
144
|
+
cancelledLabel.centerY == titleLabel.centerY
|
145
|
+
shareButton.right == -10
|
146
|
+
shareButton.centerY == 0
|
147
|
+
titleLabel.resistH == low
|
148
|
+
shareButton.left >= titleLabel.right + 5
|
149
|
+
timeLabel.resistH == low
|
150
|
+
shareButton.left >= inOutStatusInImage.right + 5
|
151
|
+
}
|
152
|
+
|
153
|
+
end
|
154
|
+
```
|
155
|
+
|
156
|
+
Keep in mind none of these lines are using the multiplier, and thats OK. I've only needed it on one constraint in my entire app so far,
|
157
|
+
so don't think its odd if you can't find a use for it.
|
158
|
+
|
159
|
+
There are two special cases at the moment. **titleLabel.resistH == low** is not a "real" constraint. Its a shortcut to
|
160
|
+
`setContentCompressionResistancePriority`, and since its common when dealing with autolayout, its nice to include it
|
161
|
+
in our layout code. The same is done for `setContentHuggingPriority`. The full list of "special cases" at the moment:
|
162
|
+
|
163
|
+
- view1.resistH == priority
|
164
|
+
- view1.resistV == priority
|
165
|
+
- view1.hugH == priority
|
166
|
+
- view1.hugV == priority
|
167
|
+
|
168
|
+
"priority" can be one of the values listed earlier, or your own number between 1-1000.
|
169
|
+
|
170
|
+
### Debugging constraints
|
171
|
+
|
172
|
+
- You can include a **?** on any line, and debug output will be printed when that constraint is built:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
layout.eqs %Q{
|
176
|
+
label.left == photo.right + 5 ?
|
177
|
+
}
|
178
|
+
```
|
179
|
+
|
180
|
+
- Since layout.eqs allows you to write many constraints in one string, and sometimes its nice to
|
181
|
+
keep comments next to constraints, **comments are allowed**:
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
layout.eqs %Q{
|
185
|
+
commentsCount.width == likesCount.width @ low # the widths of the labels prefer to be the same
|
186
|
+
}
|
187
|
+
```
|
188
|
+
|
189
|
+
### Things to remember
|
190
|
+
|
191
|
+
- Remember you usually want negative constants for right and bottom. For example: label.right == -10 means "label's right should be 10 away from the right side of the superview". But if you accidentally said label.right == 10, you would have created "label's right should be 10 PAST the right side of the superview". It may require you to adjust your thinking.
|
192
|
+
|
193
|
+
- The formula is just shorthand for `constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:`. You should **really** read up on constraints and
|
194
|
+
understand this method, to fully understand the power and simplicity the shorthand formula gives you.
|
195
|
+
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
|
5
202
|
|
6
203
|
## Observation/KVO, Events
|
7
204
|
|
data/Rakefile
CHANGED
@@ -1 +1,16 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
$:.unshift('/Library/RubyMotion/lib')
|
3
|
+
if ENV.fetch('platform', 'ios') == 'ios'
|
4
|
+
require 'motion/project/template/ios'
|
5
|
+
elsif ENV['platform'] == 'osx'
|
6
|
+
require 'motion/project/template/osx'
|
7
|
+
else
|
8
|
+
raise "Unsupported platform #{ENV['platform']}"
|
9
|
+
end
|
10
|
+
require 'bundler'
|
11
|
+
Bundler.require
|
12
|
+
|
13
|
+
Motion::Project::App.setup do |app|
|
14
|
+
# Use `rake config' to see complete project settings.
|
15
|
+
app.name = 'rm-extensions'
|
16
|
+
end
|
data/app/app_delegate.rb
ADDED
Binary file
|
data/spec/main_spec.rb
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
describe "Equation-style AutoLayout Constraints" do
|
2
|
+
|
3
|
+
def self.test_constraint_equation(c1_str, optional_desc=nil, &block)
|
4
|
+
it "#{optional_desc || c1_str}" do
|
5
|
+
c1 = @layout.eq c1_str
|
6
|
+
c2 = block.call
|
7
|
+
c1.priority.should == c2.priority
|
8
|
+
c1.firstItem.should == c2.firstItem
|
9
|
+
c1.firstAttribute.should == c2.firstAttribute
|
10
|
+
c1.relation.should == c2.relation
|
11
|
+
c1.secondItem.should == c2.secondItem
|
12
|
+
c1.secondAttribute.should == c2.secondAttribute
|
13
|
+
c1.multiplier.should == c2.multiplier
|
14
|
+
c1.constant.should == c2.constant
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
before do
|
19
|
+
@view = UIView.new
|
20
|
+
@label1 = UILabel.new
|
21
|
+
@label2 = UILabel.new
|
22
|
+
@layout = RMExtensions::Layout.new
|
23
|
+
@layout.view @view
|
24
|
+
@layout.subviews({
|
25
|
+
"label1" => @label1,
|
26
|
+
"label2" => @label2
|
27
|
+
})
|
28
|
+
end
|
29
|
+
|
30
|
+
test_constraint_equation("label1.left == 0") do
|
31
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
32
|
+
attribute:NSLayoutAttributeLeft,
|
33
|
+
relatedBy:NSLayoutRelationEqual,
|
34
|
+
toItem:@view,
|
35
|
+
attribute:NSLayoutAttributeLeft,
|
36
|
+
multiplier:1.0,
|
37
|
+
constant:0)
|
38
|
+
end
|
39
|
+
|
40
|
+
test_constraint_equation("label1.left == 8") do
|
41
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
42
|
+
attribute:NSLayoutAttributeLeft,
|
43
|
+
relatedBy:NSLayoutRelationEqual,
|
44
|
+
toItem:@view,
|
45
|
+
attribute:NSLayoutAttributeLeft,
|
46
|
+
multiplier:1.0,
|
47
|
+
constant:8)
|
48
|
+
end
|
49
|
+
|
50
|
+
test_constraint_equation("label1.right == -20") do
|
51
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
52
|
+
attribute:NSLayoutAttributeRight,
|
53
|
+
relatedBy:NSLayoutRelationEqual,
|
54
|
+
toItem:@view,
|
55
|
+
attribute:NSLayoutAttributeRight,
|
56
|
+
multiplier:1.0,
|
57
|
+
constant:-20)
|
58
|
+
end
|
59
|
+
|
60
|
+
test_constraint_equation("label1.top == 0") do
|
61
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
62
|
+
attribute:NSLayoutAttributeTop,
|
63
|
+
relatedBy:NSLayoutRelationEqual,
|
64
|
+
toItem:@view,
|
65
|
+
attribute:NSLayoutAttributeTop,
|
66
|
+
multiplier:1.0,
|
67
|
+
constant:0)
|
68
|
+
end
|
69
|
+
|
70
|
+
test_constraint_equation("label1.bottom == -36") do
|
71
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
72
|
+
attribute:NSLayoutAttributeBottom,
|
73
|
+
relatedBy:NSLayoutRelationEqual,
|
74
|
+
toItem:@view,
|
75
|
+
attribute:NSLayoutAttributeBottom,
|
76
|
+
multiplier:1.0,
|
77
|
+
constant:-36)
|
78
|
+
end
|
79
|
+
|
80
|
+
test_constraint_equation("label1.height == 1") do
|
81
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
82
|
+
attribute:NSLayoutAttributeHeight,
|
83
|
+
relatedBy:NSLayoutRelationEqual,
|
84
|
+
toItem:nil,
|
85
|
+
attribute:NSLayoutAttributeNotAnAttribute,
|
86
|
+
multiplier:1.0,
|
87
|
+
constant:1)
|
88
|
+
end
|
89
|
+
|
90
|
+
test_constraint_equation("label1.centerX == 0") do
|
91
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
92
|
+
attribute:NSLayoutAttributeCenterX,
|
93
|
+
relatedBy:NSLayoutRelationEqual,
|
94
|
+
toItem:@view,
|
95
|
+
attribute:NSLayoutAttributeCenterX,
|
96
|
+
multiplier:1.0,
|
97
|
+
constant:0)
|
98
|
+
end
|
99
|
+
|
100
|
+
test_constraint_equation("label1.width == 1.5") do
|
101
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
102
|
+
attribute:NSLayoutAttributeWidth,
|
103
|
+
relatedBy:NSLayoutRelationEqual,
|
104
|
+
toItem:nil,
|
105
|
+
attribute:NSLayoutAttributeNotAnAttribute,
|
106
|
+
multiplier:1.0,
|
107
|
+
constant:1.5)
|
108
|
+
end
|
109
|
+
|
110
|
+
test_constraint_equation("label1.left >= 6") do
|
111
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
112
|
+
attribute:NSLayoutAttributeLeft,
|
113
|
+
relatedBy:NSLayoutRelationGreaterThanOrEqual,
|
114
|
+
toItem:@view,
|
115
|
+
attribute:NSLayoutAttributeLeft,
|
116
|
+
multiplier:1.0,
|
117
|
+
constant:6)
|
118
|
+
end
|
119
|
+
|
120
|
+
test_constraint_equation("label1.width == 0 @ low # prefer box hugs content") do
|
121
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
122
|
+
attribute:NSLayoutAttributeWidth,
|
123
|
+
relatedBy:NSLayoutRelationEqual,
|
124
|
+
toItem:nil,
|
125
|
+
attribute:NSLayoutAttributeNotAnAttribute,
|
126
|
+
multiplier:1.0,
|
127
|
+
constant:0).tap { |x| x.priority = UILayoutPriorityDefaultLow }
|
128
|
+
end
|
129
|
+
|
130
|
+
test_constraint_equation("label1.left == 24 @ low # this button prefers to hug the left") do
|
131
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
132
|
+
attribute:NSLayoutAttributeLeft,
|
133
|
+
relatedBy:NSLayoutRelationEqual,
|
134
|
+
toItem:@view,
|
135
|
+
attribute:NSLayoutAttributeLeft,
|
136
|
+
multiplier:1.0,
|
137
|
+
constant:24).tap { |x| x.priority = UILayoutPriorityDefaultLow }
|
138
|
+
end
|
139
|
+
|
140
|
+
test_constraint_equation("label1.top == view.top + 8") do
|
141
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
142
|
+
attribute:NSLayoutAttributeTop,
|
143
|
+
relatedBy:NSLayoutRelationEqual,
|
144
|
+
toItem:@view,
|
145
|
+
attribute:NSLayoutAttributeTop,
|
146
|
+
multiplier:1.0,
|
147
|
+
constant:8)
|
148
|
+
end
|
149
|
+
|
150
|
+
test_constraint_equation("label1.left == label2.left * 0.5 - 5") do
|
151
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
152
|
+
attribute:NSLayoutAttributeLeft,
|
153
|
+
relatedBy:NSLayoutRelationEqual,
|
154
|
+
toItem:@label2,
|
155
|
+
attribute:NSLayoutAttributeLeft,
|
156
|
+
multiplier:0.5,
|
157
|
+
constant:-5)
|
158
|
+
end
|
159
|
+
|
160
|
+
test_constraint_equation("label1.top == label2.top + 5") do
|
161
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
162
|
+
attribute:NSLayoutAttributeTop,
|
163
|
+
relatedBy:NSLayoutRelationEqual,
|
164
|
+
toItem:@label2,
|
165
|
+
attribute:NSLayoutAttributeTop,
|
166
|
+
multiplier:1.0,
|
167
|
+
constant:5)
|
168
|
+
end
|
169
|
+
|
170
|
+
test_constraint_equation("label1.top == label2.bottom") do
|
171
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
172
|
+
attribute:NSLayoutAttributeTop,
|
173
|
+
relatedBy:NSLayoutRelationEqual,
|
174
|
+
toItem:@label2,
|
175
|
+
attribute:NSLayoutAttributeBottom,
|
176
|
+
multiplier:1.0,
|
177
|
+
constant:0)
|
178
|
+
end
|
179
|
+
|
180
|
+
test_constraint_equation("label1.width == label2.width @ low # the widths of the labels prefer to be the same") do
|
181
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
182
|
+
attribute:NSLayoutAttributeWidth,
|
183
|
+
relatedBy:NSLayoutRelationEqual,
|
184
|
+
toItem:@label2,
|
185
|
+
attribute:NSLayoutAttributeWidth,
|
186
|
+
multiplier:1.0,
|
187
|
+
constant:0).tap { |x| x.priority = UILayoutPriorityDefaultLow }
|
188
|
+
end
|
189
|
+
|
190
|
+
test_constraint_equation("label1.left == label2.right + 20") do
|
191
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
192
|
+
attribute:NSLayoutAttributeLeft,
|
193
|
+
relatedBy:NSLayoutRelationEqual,
|
194
|
+
toItem:@label2,
|
195
|
+
attribute:NSLayoutAttributeRight,
|
196
|
+
multiplier:1.0,
|
197
|
+
constant:20)
|
198
|
+
end
|
199
|
+
|
200
|
+
test_constraint_equation("label1.centerY == label2.centerY") do
|
201
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
202
|
+
attribute:NSLayoutAttributeCenterY,
|
203
|
+
relatedBy:NSLayoutRelationEqual,
|
204
|
+
toItem:@label2,
|
205
|
+
attribute:NSLayoutAttributeCenterY,
|
206
|
+
multiplier:1.0,
|
207
|
+
constant:0)
|
208
|
+
end
|
209
|
+
|
210
|
+
test_constraint_equation("label1.left >= label2.right + 6") do
|
211
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
212
|
+
attribute:NSLayoutAttributeLeft,
|
213
|
+
relatedBy:NSLayoutRelationGreaterThanOrEqual,
|
214
|
+
toItem:@label2,
|
215
|
+
attribute:NSLayoutAttributeRight,
|
216
|
+
multiplier:1.0,
|
217
|
+
constant:6)
|
218
|
+
end
|
219
|
+
|
220
|
+
test_constraint_equation("label1.right <= view.right - 8") do
|
221
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
222
|
+
attribute:NSLayoutAttributeRight,
|
223
|
+
relatedBy:NSLayoutRelationLessThanOrEqual,
|
224
|
+
toItem:@view,
|
225
|
+
attribute:NSLayoutAttributeRight,
|
226
|
+
multiplier:1.0,
|
227
|
+
constant:-8)
|
228
|
+
end
|
229
|
+
|
230
|
+
test_constraint_equation("label1.right <= label2.left - 10") do
|
231
|
+
NSLayoutConstraint.constraintWithItem(@label1,
|
232
|
+
attribute:NSLayoutAttributeRight,
|
233
|
+
relatedBy:NSLayoutRelationLessThanOrEqual,
|
234
|
+
toItem:@label2,
|
235
|
+
attribute:NSLayoutAttributeLeft,
|
236
|
+
multiplier:1.0,
|
237
|
+
constant:-10)
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rm-extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Noon
|
@@ -22,6 +22,7 @@ files:
|
|
22
22
|
- LICENSE.txt
|
23
23
|
- README.md
|
24
24
|
- Rakefile
|
25
|
+
- app/app_delegate.rb
|
25
26
|
- lib/motion/accessors.rb
|
26
27
|
- lib/motion/layout.rb
|
27
28
|
- lib/motion/observation.rb
|
@@ -29,7 +30,9 @@ files:
|
|
29
30
|
- lib/motion/util.rb
|
30
31
|
- lib/rm-extensions.rb
|
31
32
|
- lib/rm-extensions/version.rb
|
33
|
+
- resources/Default-568h@2x.png
|
32
34
|
- rm-extensions.gemspec
|
35
|
+
- spec/main_spec.rb
|
33
36
|
homepage: https://github.com/joenoon/rm-extensions
|
34
37
|
licenses: []
|
35
38
|
metadata: {}
|
@@ -53,4 +56,5 @@ rubygems_version: 2.0.3
|
|
53
56
|
signing_key:
|
54
57
|
specification_version: 4
|
55
58
|
summary: Extensions and helpers for dealing with various areas of rubymotion
|
56
|
-
test_files:
|
59
|
+
test_files:
|
60
|
+
- spec/main_spec.rb
|