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