sugarcube 0.11.3 → 0.12
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.
- data/.gitignore +1 -0
- data/.yardopts +1 -0
- data/README.md +104 -113
- data/Rakefile +3 -1
- data/app/app_delegate.rb +4 -0
- data/lib/sugarcube-gestures.rb +23 -0
- data/lib/sugarcube-gestures/gestures.rb +134 -0
- data/lib/sugarcube/adjust.rb +69 -64
- data/lib/sugarcube/calayer.rb +8 -0
- data/lib/sugarcube/core_graphics.rb +107 -459
- data/lib/sugarcube/modal.rb +25 -6
- data/lib/sugarcube/{array.rb → nsarray.rb} +7 -1
- data/lib/sugarcube/nsdata.rb +22 -0
- data/lib/sugarcube/nsdate.rb +23 -0
- data/lib/sugarcube/nserror.rb +16 -0
- data/lib/sugarcube/nsstring.rb +29 -19
- data/lib/sugarcube/nsstring_files.rb +6 -0
- data/lib/sugarcube/nsuserdefaults.rb +34 -1
- data/lib/sugarcube/symbol.rb +125 -17
- data/lib/sugarcube/timer.rb +7 -0
- data/lib/sugarcube/to_s/nslayoutconstraint.rb +97 -0
- data/lib/sugarcube/to_s/uilabel.rb +4 -0
- data/lib/sugarcube/to_s/uitextfield.rb +15 -0
- data/lib/sugarcube/to_s/uiview.rb +11 -1
- data/lib/sugarcube/uiactionsheet.rb +86 -0
- data/lib/sugarcube/uialertview.rb +1 -1
- data/lib/sugarcube/uicolor.rb +18 -9
- data/lib/sugarcube/uiimage.rb +158 -12
- data/lib/sugarcube/uitableview.rb +2 -2
- data/lib/sugarcube/uiview.rb +92 -51
- data/lib/sugarcube/uiviewcontroller.rb +1 -0
- data/lib/sugarcube/version.rb +1 -1
- data/spec/core_graphics_spec.rb +304 -0
- metadata +17 -4
data/.gitignore
CHANGED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown - LICENSE
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
SugarCube
|
2
2
|
=========
|
3
3
|
|
4
4
|
Some sugar for your cocoa, or your [tea][sweettea].
|
@@ -8,14 +8,14 @@ About
|
|
8
8
|
|
9
9
|
CocoaTouch/iOS is a *verbose* framework. These extensions hope to make
|
10
10
|
development in rubymotion more enjoyable by tacking "UI" methods onto the base
|
11
|
-
classes (String, Fixnum, Numeric). With
|
11
|
+
classes (String, Fixnum, Numeric). With SugarCube, you can create a color from an
|
12
12
|
integer or symbol, or create a UIFont or UIImage from a string.
|
13
13
|
|
14
14
|
Some UI classes are opened up as well, like adding the '<<' operator to a UIView
|
15
15
|
instance, instead of view.addSubview(subview), you can use the more idiomatic:
|
16
16
|
view << subview.
|
17
17
|
|
18
|
-
The basic idea of
|
18
|
+
The basic idea of SugarCube is to turn some operations on their head. Insead of
|
19
19
|
|
20
20
|
UIApplication.sharedApplication.openURL(NSURL.URLWithString(url))
|
21
21
|
|
@@ -25,7 +25,7 @@ How about:
|
|
25
25
|
|
26
26
|
**DISCLAIMER**
|
27
27
|
|
28
|
-
It is possible that you *will not like
|
28
|
+
It is possible that you *will not like SugarCube*. That is perfectly fine!
|
29
29
|
Some people take milk in their coffee, some take sugar. Some crazy maniacs
|
30
30
|
don't even *drink* coffee, if you can imagine that... All I'm saying is: to each
|
31
31
|
their own. You should checkout [BubbleWrap][] for another take on
|
@@ -45,11 +45,14 @@ Installation
|
|
45
45
|
|
46
46
|
gem install sugarcube
|
47
47
|
|
48
|
+
# in Rakefile
|
49
|
+
require 'sugarcube'
|
50
|
+
|
48
51
|
# or in Gemfile
|
49
52
|
gem 'sugarcube'
|
50
53
|
|
51
|
-
# in
|
52
|
-
|
54
|
+
# in terminal
|
55
|
+
$ bundle install
|
53
56
|
|
54
57
|
Examples
|
55
58
|
========
|
@@ -114,7 +117,8 @@ Shorthands and hash-like access to the coder/decoder objects.
|
|
114
117
|
coder['key'] = self.value
|
115
118
|
self.value = decoder['key']
|
116
119
|
|
117
|
-
# but if you want to store booleans and such in
|
120
|
+
# but if you want to store booleans and such (in their C form,
|
121
|
+
# which will take up less space I suppose):
|
118
122
|
coder.set('sugarcube_is_neat', toBool:self.is_sugarcube_neat?)
|
119
123
|
self.sugarcube_is_neat = decoder.bool('sugarcube_is_neat')
|
120
124
|
|
@@ -160,6 +164,11 @@ recurring events)
|
|
160
164
|
ignoring the time components. `start_of_day` and `end_of_day` methods help
|
161
165
|
you here. They are akin to `floor` and `ceil`, if you consider the time to
|
162
166
|
be the "floating" component, and the date to be the nearest "integer".
|
167
|
+
4. Formatting is made easier with `NSDate#string_with_style(NSDateStyleConstant or Symbol)`
|
168
|
+
and `NSDate#string_with_format(format_string)`. See
|
169
|
+
<http://www.unicode.org/reports/tr35/tr35-25.html#Date_Format_Patterns> for
|
170
|
+
the formatters, they take getting used to, coming from `strftime`, but they
|
171
|
+
are much more powerful and locale-aware.
|
163
172
|
|
164
173
|
```
|
165
174
|
(main)> now = NSDate.new # Time.new is the same thing
|
@@ -358,6 +367,11 @@ This is the "big daddy". Lots of sugar here...
|
|
358
367
|
:change.uicontrolevent # => UIControlEventValueChanged
|
359
368
|
:all.uicontrolevent # => UIControlEventAllEvents
|
360
369
|
:blue.uicolor # UIColor.blueColor
|
370
|
+
|
371
|
+
# these are really handy for custom buttons - touch_start means the finger is inside the button, touch_stop is outside the button or canceled
|
372
|
+
:touch_start # => UIControlEventTouchDown | UIControlEventTouchDragEnter
|
373
|
+
:touch_stop # => UIControlEventTouchUpInside | UIControlEventTouchCancel | UIControlEventTouchDragExit
|
374
|
+
|
361
375
|
# all CSS colors are supported, and alpha
|
362
376
|
# (no "grey"s, only "gray"s, consistent with UIKit, which only provides "grayColor")
|
363
377
|
:firebrick.uicolor(0.25) # => 0xb22222.uicolor(0.25)
|
@@ -385,16 +399,28 @@ image = "my_image".uiimage
|
|
385
399
|
image.uicolor # => UIColor.colorWithPatternImage(image)
|
386
400
|
```
|
387
401
|
|
388
|
-
###### Image Manipulation
|
402
|
+
###### Image Manipulation - VERY handy!
|
389
403
|
|
390
404
|
```ruby
|
391
405
|
image.scale_to [37, 37]
|
392
406
|
image.rounded # default: 5 pt radius
|
393
407
|
image.rounded(10)
|
394
408
|
|
395
|
-
#
|
409
|
+
image.in_rect([[10, 10], [100, 100]]) # get part of an image
|
410
|
+
|
411
|
+
image.darken # => good for "pressed" buttons
|
412
|
+
image.darken(brightness: -0.5, saturation: -0.2) # these are the defaults
|
413
|
+
|
414
|
+
image.rotate(:left)
|
415
|
+
image.rotate(:right)
|
416
|
+
image.rotate(:flip) # 180° - if you have a better name, let me know!
|
417
|
+
image.rotate(45.degrees)
|
418
|
+
|
419
|
+
# default insets are UIEdgeInsetsZero
|
396
420
|
image.tileable
|
421
|
+
image.tileable(insets)
|
397
422
|
image.stretchable
|
423
|
+
image.stretchable(insets)
|
398
424
|
```
|
399
425
|
|
400
426
|
UIAlertView
|
@@ -530,7 +556,7 @@ UIActivityIndicatorView.gray
|
|
530
556
|
-----------
|
531
557
|
|
532
558
|
Inspired by [BubbleWrap's][BubbleWrap] `when` method, but I prefer jQuery-style
|
533
|
-
verbs and
|
559
|
+
verbs and SugarCube symbols.
|
534
560
|
|
535
561
|
```ruby
|
536
562
|
button = UIButton.alloc.initWithFrame([0, 0, 10, 10])
|
@@ -715,13 +741,13 @@ date2.same_day? date1
|
|
715
741
|
:key.get_default # => NSUserDefaults.standardUserDefaults.objectForKey(:key)
|
716
742
|
```
|
717
743
|
|
718
|
-
This is strange, and backwards, which is just
|
744
|
+
This is strange, and backwards, which is just SugarCube's style. But there is
|
719
745
|
one advantage to doing it this way. Compare these two snippets:
|
720
746
|
|
721
747
|
```ruby
|
722
748
|
# BubbleWrap
|
723
749
|
App::Persistance[:test] = { my: 'test' }
|
724
|
-
#
|
750
|
+
# SugarCube
|
725
751
|
:test.set_default { my: 'test' }
|
726
752
|
# k, BubbleWrap looks better
|
727
753
|
|
@@ -743,19 +769,26 @@ test[:my] = 'new'
|
|
743
769
|
CoreGraphics
|
744
770
|
--------------
|
745
771
|
|
746
|
-
###### Is it `CGMakeRect` or `CGRectMake`?
|
772
|
+
###### Is it `CGMakeRect` or `CGRectMake`? What arguments does `CGRect.new` take?
|
747
773
|
|
748
|
-
Instead, just use `Rect`, `Size` and `Point`. They
|
749
|
-
|
750
|
-
|
774
|
+
Instead, just use the coercion methods `Rect()`, `Size()` and `Point()`. They
|
775
|
+
will happily convert most sensible (and some non-sensible) arguments into a
|
776
|
+
`CGRect/CGSize/CGPoint` struct. For more CoreGraphics additions, you should use
|
777
|
+
[geomotion][] by [Clay Allsopp][]. It adds methods to `CGRect`, `CGPoint`, and
|
778
|
+
`CGSize` to make these structures more rubyesque (these methods used to be part
|
779
|
+
of SugarCube, but were removed in an attempt to decrease the amount of
|
780
|
+
duplicated code).
|
751
781
|
|
752
|
-
|
753
|
-
|
782
|
+
[geomotion]: https://github.com/clayallsopp
|
783
|
+
[Clay Allsopp]: https://github.com/clayallsopp/geomotion
|
784
|
+
|
785
|
+
These are namespaced in the `SugarCube::CoreGraphics` module, but I recommend
|
786
|
+
you `include SugarCube::CoreGraphics` in app_delegate.rb.
|
754
787
|
|
755
788
|
```ruby
|
756
|
-
f = Rect(view.frame) #
|
757
|
-
o = Point(view.frame.origin) #
|
758
|
-
s = Size(view.frame.size) #
|
789
|
+
f = Rect(view.frame) # the identity function - returns a copy of the CGRect
|
790
|
+
o = Point(view.frame.origin) # returns a copy of CGPoint
|
791
|
+
s = Size(view.frame.size) # returns a copy of CGSize
|
759
792
|
|
760
793
|
# lots of other conversions are possible.
|
761
794
|
# a UIView or CALayer => view.frame
|
@@ -763,103 +796,19 @@ f = Rect(view)
|
|
763
796
|
# 4 numbers
|
764
797
|
f = Rect(x, y, w, h)
|
765
798
|
# or two arrays
|
799
|
+
f = Rect([x, y], [w, h])
|
800
|
+
# one array
|
801
|
+
f = Rect([[x, y], [w, h]])
|
802
|
+
f = Rect([x, y, w, h])
|
803
|
+
# a CGPoint and CGSize
|
766
804
|
p = Point(x, y) # or just [x, y] works, too
|
767
805
|
s = Size(w, h) # again, [w, h] is fine
|
768
806
|
f = Rect(p, s)
|
769
|
-
#
|
770
|
-
f = Rect(
|
771
|
-
|
772
|
-
|
773
|
-
###### CG{Rect,Point,Size} is a *real boy*!
|
774
|
-
|
775
|
-
These methods get defined in a module (`SugarCube::CG{Rect,Size,Point}Extensions`),
|
776
|
-
and included in `CGRect` *and* `Rect`. The idea is that you do not have to
|
777
|
-
distinguish between the two objects.
|
778
|
-
|
779
|
-
These methods all use the methods as described in [CGGeometry Reference][], e.g.
|
780
|
-
`CGRectContainsPoint`, `CGRectIntersectsRect`, etc.
|
781
|
-
|
782
|
-
```ruby
|
783
|
-
# intersection / contains
|
784
|
-
Point(0, 0).intersects?(Rect(-1, -1, 2, 2)) # => true
|
785
|
-
# if a Point intersects a Rect, the Rect intersects the Point, right?
|
786
|
-
Rect(-1, -1, 2, 2).intersects? Point(0, 0) # => true
|
787
|
-
|
788
|
-
# CGRect and the gang are real Ruby objects. Let's treat 'em that way!
|
789
|
-
view.frame.contains? Point(10, 10) # in this case, contains? and intersects? are synonyms
|
790
|
-
view.frame.intersects? Rect(0, 0, 10, 10) # <= but this one
|
791
|
-
view.frame.contains? Rect(0, 0, 10, 10) # <= and this one are different.
|
792
|
-
|
793
|
-
# CGRect has factory methods for CGRectEmpty, CGRectNull, and - KINDA - CGRectInfinite
|
794
|
-
# BUT, there is a bug (?) right now where CGRectIsInfinite(CGRectInfinite) returns false.
|
795
|
-
# so instead, I've built my own infinite? method that checks for the special "Infinite" value
|
796
|
-
> CGRect.infinite
|
797
|
-
=> [[0, 0], [Infinity, Infinity]]
|
798
|
-
> CGRect.infinite.infinite?
|
799
|
-
=> true
|
800
|
-
> CGRect.null
|
801
|
-
=> [[Infinity, Infinity], [0.0, 0.0]]
|
802
|
-
> CGRect.null.null?
|
803
|
-
=> true
|
804
|
-
> CGRect.empty
|
805
|
-
=> [[0.0, 0.0], [0.0, 0.0]]
|
806
|
-
> CGRect.empty.empty?
|
807
|
-
=> true
|
808
|
-
```
|
809
|
-
|
810
|
-
A lot of the methods in CGGeometry Reference are available as instance methods
|
811
|
-
|
812
|
-
```ruby
|
813
|
-
view.frame.left # => CGRectGetMinX(view.frame)
|
814
|
-
view.frame.right # => CGRectGetMaxX(view.frame)
|
815
|
-
view.frame.top # => CGRectGetMinY(view.frame)
|
816
|
-
view.frame.bottom # => CGRectGetMaxY(view.frame)
|
817
|
-
view.frame.width # => CGRectGetWidth(view.frame)
|
818
|
-
view.frame.height # => CGRectGetHeight(view.frame)
|
819
|
-
view.frame.center # => Point(CGRectGetMidX(view.frame), CGRectGetMidY(view.frame))
|
820
|
-
|
821
|
-
view.frame.intersection(another_rect) # => CGRectIntersection(view.frame, another_rect)
|
822
|
-
view.frame + another_rect # => CGRectUnion(view.frame, another_rect)
|
823
|
-
view.frame + a_point # => CGRectOffset(view.frame, a_point.x, a_point.y)
|
824
|
-
view.frame + a_offset # => CGRectOffset(view.frame, a_offset.horizontal, a_offset.vertical)
|
825
|
-
view.frame + edgeinsets # => UIEdgeInsetsInsetRect(view.frame, edgeinsets)
|
826
|
-
view.frame + a_size # => CGRectInset(view.frame, -a_size.width, -a_size.height)
|
827
|
-
# Adding a size to a view keeps the view's CENTER in the same place, but
|
828
|
-
# increases its size by `size.width,size.height`. it's the same as using
|
829
|
-
# UIEdgeInsets with top == bottom, and left == right
|
830
|
-
> Rect(0, 0, 10, 10).center
|
831
|
-
=> Point(5.0, 5.0) # note the center
|
832
|
-
> Rect(0, 0, 10, 10) + Size(10, 10)
|
833
|
-
=> Rect([-10.0, -10.0],{30.0 × 30.0}) # origin and size changed, but...
|
834
|
-
> (Rect(0, 0, 10, 10) + Size(10, 10)).center
|
835
|
-
=> Point(5.0, 5.0)
|
836
|
-
# See? It's bigger, but the center hasn't moved.
|
807
|
+
# any combination of the two
|
808
|
+
f = Rect(p, [w, h])
|
809
|
+
f = Rect([x, y], s)
|
837
810
|
```
|
838
811
|
|
839
|
-
`to_hash/from_hash`, and notice here that I used `inspect`, to show that it is a
|
840
|
-
little more readable.
|
841
|
-
|
842
|
-
**NOTE** As of today, Aug. 25, 2012, rubymotion v1.22, the `inspect` method in SugarCube is not
|
843
|
-
being called. I think this is a bug... this worked before!
|
844
|
-
|
845
|
-
```ruby
|
846
|
-
> Rect(0, 0, 10, 10).to_hash
|
847
|
-
=> {"Width"=>10.0, "Height"=>10.0, "Y"=>0.0, "X"=>0.0}
|
848
|
-
> puts CGRect.from_hash(Rect(0, 0, 1, 1).to_hash).inspect
|
849
|
-
CGRect([0.0, 0.0],{1.0 × 1.0})
|
850
|
-
```
|
851
|
-
|
852
|
-
`to_s/from_s`, which rely on `NSStringFromCGRect/CGRectFromString` (et. al.)
|
853
|
-
|
854
|
-
```ruby
|
855
|
-
> Rect(0, 0, 10, 10).to_s
|
856
|
-
=> "{{0, 0}, {10, 10}}"
|
857
|
-
> puts CGRect.from_s Rect(0, 0, 10, 10).to_s
|
858
|
-
{{0, 0}, {10, 10}}
|
859
|
-
```
|
860
|
-
|
861
|
-
[CGGeometry Reference]: https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CGGeometry/Reference/reference.html
|
862
|
-
|
863
812
|
CoreLocation
|
864
813
|
--------------
|
865
814
|
|
@@ -1126,3 +1075,45 @@ true.blank? # => false
|
|
1126
1075
|
['a'].blank? # => false
|
1127
1076
|
{a: 'a'}.blank? # => false
|
1128
1077
|
```
|
1078
|
+
|
1079
|
+
Gestures
|
1080
|
+
--------
|
1081
|
+
|
1082
|
+
Sugarcube's gesture support is very similar to BubbleWrap's, and it's entirely
|
1083
|
+
possible that the two will be merged into one thing. But SugarCube is all about
|
1084
|
+
extending base classes, whereas BubbleWrap tends to add *new* classes to do the
|
1085
|
+
heavy lifting. Plus the options you pass to SugarCube are very different, and
|
1086
|
+
the prefix is "on" instead of "when" (e.g. "on_pan" instead of "when_panned")
|
1087
|
+
|
1088
|
+
Gestures are an "opt-in" extension. In your Rakefile, add
|
1089
|
+
`require 'sugarcube-gestures'`.
|
1090
|
+
|
1091
|
+
```ruby
|
1092
|
+
require 'sugarcube-gestures'
|
1093
|
+
|
1094
|
+
view.on_pan { |gesture|
|
1095
|
+
location = gesture.view.locationInView(view)
|
1096
|
+
}
|
1097
|
+
|
1098
|
+
# other gesture methods, with common options:
|
1099
|
+
view.on_tap # use system defaults
|
1100
|
+
view.on_tap(1) # number of taps
|
1101
|
+
view.on_tap(taps: 1, fingers: 1) # number of taps and number of fingers
|
1102
|
+
|
1103
|
+
view.on_pinch # no options
|
1104
|
+
view.on_rotate # no options
|
1105
|
+
|
1106
|
+
view.on_swipe # use system defaults
|
1107
|
+
view.on_swipe :left
|
1108
|
+
view.on_swipe(direction: :left, fingers: 1)
|
1109
|
+
view.on_swipe(direction: UISwipeGestureRecognizerDirectionLeft, fingers: 1)
|
1110
|
+
|
1111
|
+
view.on_pan # use system defaults
|
1112
|
+
view.on_pan(2) # minimum and maximum fingers required
|
1113
|
+
view.on_pan(fingers: 2)
|
1114
|
+
view.on_pan(min_fingers: 2, max_fingers: 3)
|
1115
|
+
|
1116
|
+
view.on_press # use system defaults
|
1117
|
+
view.on_press(1.5) # duration
|
1118
|
+
view.on_press(duration: 1.5, taps: 1, fingers: 1)
|
1119
|
+
```
|
data/Rakefile
CHANGED
data/app/app_delegate.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
unless defined?(Motion::Project::Config)
|
2
|
+
raise "The sugarcube gem must be required within a RubyMotion project Rakefile."
|
3
|
+
end
|
4
|
+
|
5
|
+
|
6
|
+
Motion::Project::App.setup do |app|
|
7
|
+
# scans app.files until it finds app/ (the default)
|
8
|
+
# if found, it inserts just before those files, otherwise it will insert to
|
9
|
+
# the end of the list
|
10
|
+
insert_point = 0
|
11
|
+
app.files.each_index do |index|
|
12
|
+
file = app.files[index]
|
13
|
+
if file =~ /^(?:\.\/)?app\//
|
14
|
+
# found app/, so stop looking
|
15
|
+
break
|
16
|
+
end
|
17
|
+
insert_point = index + 1
|
18
|
+
end
|
19
|
+
|
20
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'sugarcube-gestures/**/*.rb')).reverse.each do |file|
|
21
|
+
app.files.insert(insert_point, file)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# BubbleWrap has these same methods, but the logic and options are a little
|
2
|
+
# different. In the spirit of open source, I am blatantly copying their code,
|
3
|
+
# changing it to suit my needs, and offering it here
|
4
|
+
class UIView
|
5
|
+
|
6
|
+
# a generic gesture adder, but using sugarcube_add_gesture, which handles the block
|
7
|
+
def on_gesture(klass, options={}, &proc)
|
8
|
+
recognizer = klass.alloc.initWithTarget(self, action:'sugarcube_handle_gesture:')
|
9
|
+
options.each do |method, value|
|
10
|
+
recognizer.send(method, value)
|
11
|
+
end
|
12
|
+
sugarcube_add_gesture(proc, recognizer)
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_tap(taps_or_options=nil, &proc)
|
16
|
+
taps = nil
|
17
|
+
fingers = nil
|
18
|
+
|
19
|
+
if taps_or_options
|
20
|
+
if taps_or_options.is_a? Hash
|
21
|
+
taps = taps_or_options[:taps] || taps
|
22
|
+
fingers = taps_or_options[:fingers] || fingers
|
23
|
+
else
|
24
|
+
taps = taps_or_options
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
recognizer = UITapGestureRecognizer.alloc.initWithTarget(self, action:'sugarcube_handle_gesture:')
|
29
|
+
recognizer.numberOfTapsRequired = taps if taps
|
30
|
+
recognizer.numberOfTouchesRequired = fingers if fingers
|
31
|
+
sugarcube_add_gesture(proc, recognizer)
|
32
|
+
end
|
33
|
+
|
34
|
+
def on_pinch(&proc)
|
35
|
+
recognizer = UIPinchGestureRecognizer.alloc.initWithTarget(self, action:'sugarcube_handle_gesture:')
|
36
|
+
sugarcube_add_gesture(proc, recognizer)
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_rotate(&proc)
|
40
|
+
recognizer = UIRotationGestureRecognizer.alloc.initWithTarget(self, action:'sugarcube_handle_gesture:')
|
41
|
+
sugarcube_add_gesture(proc, recognizer)
|
42
|
+
end
|
43
|
+
|
44
|
+
def on_swipe(direction_or_options=nil, &proc)
|
45
|
+
direction = UISwipeGestureRecognizerDirectionRight
|
46
|
+
fingers = nil
|
47
|
+
|
48
|
+
if direction_or_options
|
49
|
+
if direction_or_options.is_a? Hash
|
50
|
+
direction = direction_or_options[:direction] || direction
|
51
|
+
fingers = direction_or_options[:fingers] || fingers
|
52
|
+
else
|
53
|
+
direction = direction_or_options
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
case direction
|
58
|
+
when :left
|
59
|
+
direction = UISwipeGestureRecognizerDirectionLeft
|
60
|
+
when :right
|
61
|
+
direction = UISwipeGestureRecognizerDirectionRight
|
62
|
+
when :up
|
63
|
+
direction = UISwipeGestureRecognizerDirectionUp
|
64
|
+
when :down
|
65
|
+
direction = UISwipeGestureRecognizerDirectionDown
|
66
|
+
end
|
67
|
+
|
68
|
+
recognizer = UISwipeGestureRecognizer.alloc.initWithTarget(self, action:'sugarcube_handle_gesture:')
|
69
|
+
recognizer.direction = direction if direction
|
70
|
+
recognizer.numberOfTouchesRequired = fingers if fingers
|
71
|
+
sugarcube_add_gesture(proc, recognizer)
|
72
|
+
end
|
73
|
+
|
74
|
+
def on_pan(fingers_or_options=nil, &proc)
|
75
|
+
fingers = nil
|
76
|
+
min_fingers = nil
|
77
|
+
max_fingers = nil
|
78
|
+
|
79
|
+
if fingers_or_options
|
80
|
+
if fingers_or_options.is_a? Hash
|
81
|
+
fingers = fingers_or_options[:fingers] || fingers
|
82
|
+
min_fingers = fingers_or_options[:min_fingers] || min_fingers
|
83
|
+
max_fingers = fingers_or_options[:max_fingers] || max_fingers else
|
84
|
+
fingers = fingers_or_options
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
recognizer = UIPanGestureRecognizer.alloc.initWithTarget(self, action:'sugarcube_handle_gesture:')
|
89
|
+
sugarcube_add_gesture(proc, recognizer)
|
90
|
+
end
|
91
|
+
|
92
|
+
def on_press(duration_or_options=nil, &proc)
|
93
|
+
duration = nil
|
94
|
+
taps = nil
|
95
|
+
fingers = nil
|
96
|
+
|
97
|
+
if duration_or_options
|
98
|
+
if duration_or_options.is_a? Hash
|
99
|
+
duration = duration_or_options[:duration] || duration
|
100
|
+
taps = duration_or_options[:taps] || taps
|
101
|
+
fingers = duration_or_options[:fingers] || fingers
|
102
|
+
else
|
103
|
+
duration = duration_or_options
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
recognizer = UILongPressGestureRecognizer.alloc.initWithTarget(self, action:'sugarcube_handle_gesture:')
|
108
|
+
recognizer.minimumPressDuration = duration if duration
|
109
|
+
recognizer.numberOfTapsRequired = taps if taps
|
110
|
+
recognizer.numberOfTouchesRequired = fingers if fingers
|
111
|
+
sugarcube_add_gesture(proc, recognizer)
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
def sugarcube_handle_gesture(recognizer)
|
116
|
+
handler = @sugarcube_recognizers[recognizer]
|
117
|
+
if handler.arity == 0
|
118
|
+
handler.call
|
119
|
+
else
|
120
|
+
handler.call(recognizer)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Adds the recognizer and keeps a strong reference to the Proc object.
|
125
|
+
def sugarcube_add_gesture(proc, recognizer)
|
126
|
+
self.addGestureRecognizer(recognizer)
|
127
|
+
|
128
|
+
@sugarcube_recognizers = {} unless @sugarcube_recognizers
|
129
|
+
@sugarcube_recognizers[recognizer] = proc
|
130
|
+
|
131
|
+
recognizer
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|