sugarcube 1.1.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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