sugarcube 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sugarcube (1.1.0)
4
+ sugarcube (1.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -171,8 +171,9 @@ A big package chock full of methods to make working in UIKit a joy.
171
171
  A few varieties of methods are in this package:
172
172
 
173
173
  * Conversions: `'string-to'.uiimage`, `image.uiimageview`
174
- * Helpers: shorthands for common operations, like `a_view << a_subview`
174
+ * Helpers: shorthands for common operations, like `a_view << a_subview`, `a_subview.convert_frame_to(a_view)`
175
175
  * Symbols: `:system.uifont(20)`, `:label.uifontsize`
176
+ * Frame accessors: `a_view.x`, `a_view.x = 100`
176
177
 
177
178
  There are too many methods to define here. Instead: a complete list of methods
178
179
  is available in the [documentation][], and the [wiki page][UIKit Wiki] is a
@@ -451,8 +452,22 @@ image.stretchable(insets)
451
452
  # will be made transparent, and black opaque.
452
453
  image.masked(mask_image)
453
454
 
455
+ # Apply a color overlay to an image. This is used used on icons (PNG's), on which
456
+ # you want to change the color.
457
+ image.overlay(UIColor.redColor)
458
+ image.overlay(:red)
459
+
454
460
  # Combine two images
455
461
  image_ab = image_a << image_b
462
+
463
+ # Create an image from scratch!
464
+ UIImage.canvas([100, 100]) do |context| # opaque: false, scale: UIScreen.mainScreen.scale
465
+ # draw here!
466
+ end
467
+ # use an image as a background to draw on
468
+ image.draw do |context|
469
+ # draw here!
470
+ end
456
471
  ```
457
472
 
458
473
  ###### CIFilter additions
@@ -546,6 +561,15 @@ These methods are added onto the UIColor class:
546
561
  :white.uicolor.mix_with(:black.uicolor, 0.75) # => 0xbfbfbf.uicolor
547
562
  :white.uicolor.mix_with(:black.uicolor, 1) # => :black
548
563
 
564
+ # you can get information about a color:
565
+ :cyan.uicolor.red # => 0
566
+ :cyan.uicolor.green # => 1
567
+ :cyan.uicolor.blue # => 1
568
+ :cyan.uicolor.hue # => 0.5
569
+ :cyan.uicolor.saturation # => 1.0
570
+ :cyan.uicolor.brightness # => 1.0
571
+ :cyan.uicolor(0.9).alpha # => 0.9
572
+
549
573
  # convert to CGColor
550
574
  color.cgcolor
551
575
  ```
@@ -796,8 +820,9 @@ view.tumble # great way to dismiss an alert-like-view
796
820
 
797
821
  These helpers all delegate to the `UIView.animate` method, which accepts all the
798
822
  options that `UIView.animateWithDuration(delay:options:animations:completion:)`
799
- accepts, but they are optional, and they will play nicely inside an animation
800
- chain.
823
+ or `UIView.animateWithDuration(delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:)`
824
+ accept. All options are optional, and they will play nicely inside an animation
825
+ chain (see below, and the wiki page).
801
826
 
802
827
  ```ruby
803
828
  UIView.animate do
@@ -805,6 +830,23 @@ UIView.animate do
805
830
  end
806
831
  ```
807
832
 
833
+ The "spring" animations use the method `UIView.animateWithDuration(delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:)`,
834
+ available in iOS 7. In testing, I've found this method to be slightly
835
+ unreliable, so use with caution. To "enable" it, pass in the `:damping` option.
836
+ You can also use `:velocity` to set an initial velocity, if there is an
837
+ animation in progress.
838
+
839
+ ```ruby
840
+ new_frame = [[110, 200], [100, 20]]
841
+
842
+ UIView.animate(damping: 0.1) do # default velocity is 0
843
+ view.frame = new_frame
844
+ end
845
+
846
+ # equivalent:
847
+ view.reframe_to(new_frame, damping: 0.1, velocity: 1)
848
+ ```
849
+
808
850
  The [wiki] page documents all the different animation methods, and documents
809
851
  animation chaining, which looks like this:
810
852
 
@@ -819,6 +861,14 @@ end.and_then do
819
861
  end.start
820
862
  ```
821
863
 
864
+ Core Animation classes get some love, too!
865
+
866
+ ```ruby
867
+ view.layer.basic_animation('opacity', from: 0, to: 1, duration: 0.1)
868
+ ```
869
+
870
+ Lots more information in the Wiki!
871
+
822
872
  [Animations Wiki]: https://github.com/rubymotion/sugarcube/wiki/Animations
823
873
 
824
874
  Modal
@@ -947,6 +997,13 @@ e.g. 1024 bytes in a kilobyte.
947
997
  1.megabyte.in_kilobytes # => 1024
948
998
  ```
949
999
 
1000
+ ### Screen
1001
+
1002
+ ```ruby
1003
+ 1.pixel # => 1 on non-retina, 0.5 on retina.
1004
+ # Useful when drawing if you want to specify the number of pixels
1005
+ ```
1006
+
950
1007
  AttributedString
951
1008
  -----
952
1009
 
@@ -1113,8 +1170,8 @@ NSDate ([wiki][NSDate Wiki])
1113
1170
  > `require 'sugarcube-nsdate'`
1114
1171
 
1115
1172
  This package includes additions to the `NSDate` class, and related additions to
1116
- `Fixnum` and `NSString`. There's a lot here, so check out the [wiki][NSDate Wiki]
1117
- for detailed information.
1173
+ `Numeric` and `NSString`. There's a lot here, so check out the [wiki][NSDate
1174
+ Wiki] for detailed information.
1118
1175
 
1119
1176
  [NSDate Wiki]: https://github.com/rubymotion/sugarcube/wiki/NSDate
1120
1177
 
@@ -1314,20 +1371,26 @@ CoreLocation
1314
1371
  Open up `CLLocationCoordinate2D` to provide handy-dandies
1315
1372
 
1316
1373
  ```ruby
1374
+ # distances
1375
+
1317
1376
  > denver_co = CLLocationCoordinate2D.new(39.739188,-104.985223)
1318
1377
  => #<CLLocationCoordinate2D latitude=39.7391815185547 longitude=-104.985198974609>
1319
1378
  > loveland_oh = CLLocationCoordinate2D.new(39.268128,-84.257648)
1320
1379
  => #<CLLocationCoordinate2D latitude=39.2681274414062 longitude=-84.2576293945312>
1321
1380
  > denver_co.distance_to(loveland_oh)
1322
- => 1773425.5 # in meters
1381
+ => 1773425.54893302 # in meters
1323
1382
  > denver_co.distance_to(loveland_oh).in_miles
1324
- => 1101.955078125
1383
+ => 1101.95556640625
1384
+
1385
+ # move around the globe using x/y distances in miles or kilometers
1325
1386
  > denver_co.delta_miles(1101.6, -32.556)
1326
1387
  => #<CLLocationCoordinate2D latitude=39.2681427001953 longitude=-84.2577209472656>
1327
- > denver_co.delta_miles(1101.6, -32.556).distance_to(loveland_oh)
1328
- => 8.0804328918457 # this is in meters
1388
+ # our location is pretty close!
1329
1389
  > denver_co.delta_miles(1101.6, -32.556).distance_to(loveland_oh).miles
1330
- => 0.00502094626426697
1390
+ => 0.90043306350708
1391
+
1392
+ > denver_co.delta_kilometers(10, 10) # 10 kilometers east, 10 kilometers north
1393
+ => #<CLLocationCoordinate2D latitude=39.8290100097656 longitude=-104.868377685547>
1331
1394
  ```
1332
1395
 
1333
1396
  Pipes
@@ -0,0 +1,31 @@
1
+ class CAAnimation
2
+
3
+ class << self
4
+
5
+ def basic(target, key_path, options={}, &block)
6
+ corner_animation = CABasicAnimation.animationWithKeyPath(key_path)
7
+ corner_animation.duration = options[:duration] if options[:duration]
8
+ corner_animation.delegate = options[:delegate] if options[:delegate]
9
+
10
+ if options.key?(:from) || options.key?(:to) || options.key?(:by)
11
+ add_animation = options.fetch(:add, true)
12
+
13
+ corner_animation.fromValue = options[:from] if options[:from]
14
+ corner_animation.toValue = options[:to] if options[:to]
15
+ corner_animation.byValue = options[:by] if options[:by]
16
+ else
17
+ add_animation = options.fetch(:add, false)
18
+ end
19
+
20
+ if add_animation
21
+ target.addAnimation(corner_animation, forKey:key_path)
22
+ target.send("#{key_path}=", options[:to])
23
+ end
24
+
25
+ block.call(corner_animation) if block
26
+ return corner_animation
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,7 @@
1
+ class CALayer
2
+
3
+ def basic_animation(key_path, options={})
4
+ CAAnimation.basic(self, key_path, options)
5
+ end
6
+
7
+ end
@@ -5,18 +5,30 @@ class UIView
5
5
  # If options is a Numeric, it is used as the duration. Otherwise, duration
6
6
  # is an option, and defaults to 0.3. All the transition methods work this
7
7
  # way.
8
- def animate(options={}, &animations)
8
+ # @option options [Float] :duration Animation duration. default: 0.3
9
+ # @option options [Float] :delay Delay before animations begin. default: 0
10
+ # @option options [Float] :damping Enables the "spring" animation. Value of 1.0 is a stiff spring.
11
+ # @option options [Float] :velocity Used in a spring animation to set the initial velocity
12
+ # @option options [Proc] :after A block that is executed when the animation is complete, useful for chaining (though the `animation_chain` method is better!)
13
+ # @option options [Fixnum] :options The options parameter that is passed to the UIView.animateWithDuration(...) method. You can also use the more verbose options `:curve`, `:from_current`, and `:allow_interaction`
14
+ # @option options [Fixnum] :curve The animation curve option. default: UIViewAnimationOptionCurveEaseIn
15
+ # @option options [Boolean] :from_current Whether or not to have animations start from their current position (aka UIViewAnimationOptionBeginFromCurrentState)
16
+ # @option options [Boolean] :allow_interaction aka UIViewAnimationOptionAllowUserInteraction
17
+ def animate(options={}, more_options={}, &animations)
9
18
  raise "animation block is required" unless animations
10
19
 
11
20
  if options.is_a? Numeric
12
21
  duration = options
13
- options = {}
22
+ options = more_options
14
23
  else
15
24
  duration = options[:duration] || 0.3
16
25
  end
17
26
 
18
27
  delay = options[:delay] || 0
19
28
 
29
+ damping_ratio = options[:damping] || nil
30
+ spring_velocity = options[:velocity] || 0.0
31
+
20
32
  # chain: true is used inside animation_chain blocks to prevent some weird
21
33
  # animation errors (nested animations do not delay/queue as you'd expect)
22
34
  if options[:chain] || Thread.current[:sugarcube_chaining]
@@ -47,18 +59,34 @@ class UIView
47
59
  animation_options = curve | from_current
48
60
  end
49
61
 
62
+
63
+
64
+
65
+
50
66
  if duration == 0 && delay == 0
51
67
  animations.call
52
68
  after_adjusted.call(true) if after_adjusted
53
69
  else
54
70
  prev_value = Thread.current[:sugarcube_chaining]
55
71
  Thread.current[:sugarcube_chaining] = true
56
- UIView.animateWithDuration( duration,
57
- delay: delay,
58
- options: animation_options,
59
- animations: animations,
60
- completion: after_adjusted
61
- )
72
+
73
+ if damping_ratio
74
+ UIView.animateWithDuration( duration,
75
+ delay: delay,
76
+ usingSpringWithDamping: damping_ratio,
77
+ initialSpringVelocity: spring_velocity,
78
+ options: animation_options,
79
+ animations: animations,
80
+ completion: after_adjusted
81
+ )
82
+ else
83
+ UIView.animateWithDuration( duration,
84
+ delay: delay,
85
+ options: animation_options,
86
+ animations: animations,
87
+ completion: after_adjusted
88
+ )
89
+ end
62
90
  Thread.current[:sugarcube_chaining] = prev_value
63
91
  end
64
92
  nil
@@ -87,12 +115,9 @@ class UIView
87
115
  end
88
116
 
89
117
  # Same as UIView##animate, but acts on self
90
- def animate(options={}, &animations)
118
+ def animate(options={}, more_options={}, &animations)
91
119
  if options.is_a? Numeric
92
- duration = options
93
- options = {}
94
- else
95
- duration = options[:duration] || 0.3
120
+ options = more_options.merge(duration: options)
96
121
  end
97
122
 
98
123
  assign = options[:assign] || {}
@@ -108,7 +133,7 @@ class UIView
108
133
  end
109
134
 
110
135
  # Changes the layer opacity.
111
- def fade(options={}, &after)
136
+ def fade(options={}, more_options={}, &after)
112
137
  if options.is_a? Numeric
113
138
  options = { opacity: options }
114
139
  end
@@ -122,9 +147,9 @@ class UIView
122
147
 
123
148
  # Changes the layer opacity to 0.
124
149
  # @see #fade
125
- def fade_out(options={}, &after)
150
+ def fade_out(options={}, more_options={}, &after)
126
151
  if options.is_a? Numeric
127
- options = { duration: options }
152
+ options = more_options.merge(duration: options)
128
153
  end
129
154
 
130
155
  options[:opacity] ||= 0.0
@@ -134,9 +159,9 @@ class UIView
134
159
 
135
160
  # Changes the layer opacity to 1.
136
161
  # @see #fade
137
- def fade_in(options={}, &after)
162
+ def fade_in(options={}, more_options={}, &after)
138
163
  if options.is_a? Numeric
139
- options = { duration: options }
164
+ options = more_options.merge(duration: options)
140
165
  end
141
166
 
142
167
  options[:opacity] ||= 1.0
@@ -146,9 +171,9 @@ class UIView
146
171
 
147
172
  # Changes the layer opacity to 0 and then removes the view from its superview
148
173
  # @see #fade_out
149
- def fade_out_and_remove(options={}, &after)
174
+ def fade_out_and_remove(options={}, more_options={}, &after)
150
175
  if options.is_a? Numeric
151
- options = { duration: options }
176
+ options = more_options.merge(duration: options)
152
177
  end
153
178
 
154
179
  original_opacity = self.alpha
@@ -162,9 +187,9 @@ class UIView
162
187
  fade_out(options, &after_remove)
163
188
  end
164
189
 
165
- def move_to(position, options={}, &after)
190
+ def move_to(position, options={}, more_options={}, &after)
166
191
  if options.is_a? Numeric
167
- options = { duration: options }
192
+ options = more_options.merge(duration: options)
168
193
  end
169
194
 
170
195
  options[:after] = after
@@ -176,18 +201,18 @@ class UIView
176
201
  end
177
202
  end
178
203
 
179
- def delta_to(delta, options={}, &after)
204
+ def delta_to(delta, options={}, more_options={}, &after)
180
205
  f = self.frame
181
206
  delta = SugarCube::CoreGraphics::Point(delta)
182
207
  position = SugarCube::CoreGraphics::Point(f.origin)
183
208
  to_position = CGPoint.new(position.x + delta.x, position.y + delta.y)
184
- move_to(to_position, options, &after)
209
+ move_to(to_position, options, more_options, &after)
185
210
  self
186
211
  end
187
212
 
188
- def resize_to(size, options={}, &after)
213
+ def resize_to(size, options={}, more_options={}, &after)
189
214
  if options.is_a? Numeric
190
- options = { duration: options }
215
+ options = more_options.merge(duration: options)
191
216
  end
192
217
 
193
218
  options[:after] = after
@@ -199,9 +224,9 @@ class UIView
199
224
  end
200
225
  end
201
226
 
202
- def reframe_to(frame, options={}, &after)
227
+ def reframe_to(frame, options={}, more_options={}, &after)
203
228
  if options.is_a? Numeric
204
- options = { duration: options }
229
+ options = more_options.merge(duration: options)
205
230
  end
206
231
 
207
232
  options[:after] = after
@@ -276,10 +301,10 @@ class UIView
276
301
  # view.shake(offset: 0.1, repeat: 2, duration: 0.5, keypath: 'transform.rotation')
277
302
  # # slow nodding
278
303
  # view.shake(offset: 20, repeat: 10, duration: 5, keypath: 'transform.translation.y')
279
- def shake(options={})
304
+ def shake(options={}, more_options={})
280
305
  if options.is_a? Numeric
281
306
  duration = options
282
- options = {}
307
+ options = more_options
283
308
  else
284
309
  duration = options[:duration] || 0.3
285
310
  end
@@ -324,10 +349,10 @@ class UIView
324
349
  # Moves the view off screen while slowly rotating it.
325
350
  #
326
351
  # Based on https://github.com/warrenm/AHAlertView/blob/master/AHAlertView/AHAlertView.m
327
- def tumble(options={}, &after)
352
+ def tumble(options={}, more_options={}, &after)
328
353
  if options.is_a? Numeric
329
354
  default_duration = options
330
- options = {}
355
+ options = more_options
331
356
  else
332
357
  default_duration = 0.3
333
358
  end
@@ -366,7 +391,7 @@ class UIView
366
391
 
367
392
  # Moves the view backwards, similar to what Google has been doing a lot
368
393
  # recently
369
- def back_fiend!(options={})
394
+ def back_fiend!(options={}, more_options={})
370
395
  scale = options[:scale] || 0.5
371
396
  perspective = options[:perspective] || -0.0005
372
397
  size = options[:size] || -140
@@ -379,7 +404,7 @@ class UIView
379
404
  end
380
405
 
381
406
  # restores the layer after a call to 'back_fiend!'
382
- def forward_fiend!(options={})
407
+ def forward_fiend!(options={}, more_options={})
383
408
  UIView.animate(options) do
384
409
  self.layer.transform = CATransform3DIdentity
385
410
  end
@@ -53,6 +53,9 @@ class NSAttributedString
53
53
  foo = NSStrokeWidthAttributeName
54
54
  foo = NSShadowAttributeName
55
55
  foo = NSVerticalGlyphFormAttributeName
56
+ # new iOS 7 text effects
57
+ foo = NSTextEffectsAttributeName
58
+ foo = NSTextEffectsLetterPressStyle
56
59
  # make sure alignments get compiled
57
60
  foo = NSLeftTextAlignment
58
61
  foo = NSRightTextAlignment
@@ -130,6 +133,10 @@ class NSAttributedString
130
133
  with_attributes({NSVerticalGlyphFormAttributeName => value})
131
134
  end
132
135
 
136
+ def letterpress
137
+ with_attributes({NSTextEffectsAttributeName => NSTextEffectsLetterPressStyle})
138
+ end
139
+
133
140
  def with_attributes(attributes)
134
141
  retval = NSMutableAttributedString.alloc.initWithAttributedString(self)
135
142
  retval.addAttributes(attributes, range:[0, self.length])
@@ -9,7 +9,7 @@ class NSString
9
9
  return self[1..-1].to_i(16).uicolor(alpha)
10
10
  end
11
11
 
12
- img = self.uiimage
12
+ img = UIImage.imageNamed(self)
13
13
  img && img.uicolor(alpha)
14
14
  end
15
15