mirror of
https://github.com/zhigang1992/RubyMotion.git
synced 2026-04-13 09:40:32 +08:00
add gesture table sample
This commit is contained in:
8
sample/gesture_table/Rakefile
Normal file
8
sample/gesture_table/Rakefile
Normal file
@@ -0,0 +1,8 @@
|
||||
$:.unshift('../../lib')
|
||||
require 'motion/project'
|
||||
|
||||
Motion::Project::App.setup do |app|
|
||||
# Use `rake config' to see complete project settings.
|
||||
app.name = 'Gesture Table'
|
||||
app.frameworks += ['QuartzCore']
|
||||
end
|
||||
32
sample/gesture_table/app/UIColor_extensions.rb
Normal file
32
sample/gesture_table/app/UIColor_extensions.rb
Normal file
@@ -0,0 +1,32 @@
|
||||
class UIColor
|
||||
def colorWithBrightness(brightnessComponent)
|
||||
hue = Pointer.new(:float)
|
||||
saturation = Pointer.new(:float)
|
||||
brightness = Pointer.new(:float)
|
||||
red = Pointer.new(:float)
|
||||
green = Pointer.new(:float)
|
||||
blue = Pointer.new(:float)
|
||||
white = Pointer.new(:float)
|
||||
alpha = Pointer.new(:float)
|
||||
|
||||
if getHue(hue, saturation: saturation, brightness: brightness, alpha: alpha)
|
||||
UIColor.colorWithHue(hue[0], saturation: saturation[0], brightness: brightness[0] * brightnessComponent, alpha: alpha[0])
|
||||
elsif getRed(red, green: green, blue: blue, alpha: alpha)
|
||||
UIColor.colorWithRed(red[0] * brightnessComponent, green: green[0] * brightnessComponent, blue: blue[0] * brightnessComponent, alpha: alpha[0])
|
||||
elsif getWhite(white, alpha: alpha)
|
||||
UIColor.colorWithWhite(white[0] * brightnessComponent, alpha: alpha[0])
|
||||
end
|
||||
end
|
||||
|
||||
def colorWithHueOffset(hueOffset)
|
||||
hue = Pointer.new(:float)
|
||||
saturation = Pointer.new(:float)
|
||||
brightness = Pointer.new(:float)
|
||||
alpha = Pointer.new(:float)
|
||||
|
||||
if getHue(hue, saturation: saturation, brightness: brightness, alpha: alpha)
|
||||
newHue = (hue[0] + hueOffset) % 1
|
||||
UIColor.colorWithHue(newHue, saturation: saturation[0], brightness: brightness[0], alpha: alpha[0])
|
||||
end
|
||||
end
|
||||
end
|
||||
7
sample/gesture_table/app/UITableView_extensions.rb
Normal file
7
sample/gesture_table/app/UITableView_extensions.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
class UITableView
|
||||
def reloadVisibleRowsExceptIndexPath(indexPath)
|
||||
visibleRows = indexPathsForVisibleRows.mutableCopy
|
||||
visibleRows.removeObject(indexPath)
|
||||
reloadRowsAtIndexPaths(visibleRows, withRowAnimation: UITableViewRowAnimationNone)
|
||||
end
|
||||
end
|
||||
9
sample/gesture_table/app/app_delegate.rb
Normal file
9
sample/gesture_table/app/app_delegate.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class AppDelegate
|
||||
def application(application, didFinishLaunchingWithOptions:launchOptions)
|
||||
application.setStatusBarStyle(UIStatusBarStyleBlackOpaque)
|
||||
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
|
||||
@window.rootViewController = UINavigationController.alloc.initWithRootViewController(ViewController.new)
|
||||
@window.makeKeyAndVisible
|
||||
true
|
||||
end
|
||||
end
|
||||
376
sample/gesture_table/app/gesture_recognizer.rb
Normal file
376
sample/gesture_table/app/gesture_recognizer.rb
Normal file
@@ -0,0 +1,376 @@
|
||||
class GestureRecognizer
|
||||
CommitEditingRowDefaultRowHeight = 80
|
||||
RowAnimationDuration = 0.25
|
||||
CellSnapshotTag = 100000
|
||||
|
||||
# attr_accessor :delegate, :tableViewDelegate, :tableView, :addingRowHeight, :addingIndexPath,
|
||||
# :addingCellState, :startPinchingUpperPoint, :panRecognizer,
|
||||
# :longPressRecognizer, :state, :cellSnapshot, :scrollingRate, :movingTimer
|
||||
|
||||
def initWithTableView(tableView, delegate:delegate)
|
||||
if init
|
||||
@tableView = tableView
|
||||
@delegate= delegate
|
||||
@state = :none
|
||||
@tableViewDelegate = tableView.delegate
|
||||
tableView.delegate = self
|
||||
|
||||
@pinchRecognizer = UIPinchGestureRecognizer.alloc.initWithTarget(self, action: :"pinchGestureRecognizer:")
|
||||
@panRecognizer = UIPanGestureRecognizer.alloc.initWithTarget(self, action: :"panGestureRecognizer:")
|
||||
@longPressRecognizer = UILongPressGestureRecognizer.alloc.initWithTarget(self, action: :"longPressGestureRecognizer:")
|
||||
tableView.gestureRecognizers += [@pinchRecognizer, @panRecognizer, @longPressRecognizer]
|
||||
@pinchRecognizer.delegate = @panRecognizer.delegate = @longPressRecognizer.delegate = self
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def scrollTable
|
||||
location = @longPressRecognizer.locationInView(@tableView)
|
||||
|
||||
currentOffset = @tableView.contentOffset
|
||||
@scrollingRate ||= 0
|
||||
newOffset = CGPointMake(currentOffset.x, currentOffset.y + @scrollingRate)
|
||||
if newOffset.y < 0
|
||||
newOffset.y = 0
|
||||
elsif @tableView.contentSize.height < @tableView.frame.size.height
|
||||
newOffset = currentOffset
|
||||
elsif newOffset.y > @tableView.contentSize.height - @tableView.frame.size.height
|
||||
newOffset.y = @tableView.contentSize.height - @tableView.frame.size.height
|
||||
end
|
||||
@tableView.setContentOffset(newOffset)
|
||||
|
||||
if location.y >= 0
|
||||
cellSnapshotView = @tableView.viewWithTag(CellSnapshotTag)
|
||||
cellSnapshotView.center = CGPointMake(@tableView.center.x, location.y)
|
||||
end
|
||||
|
||||
updateAddingIndexPathForCurrentLocation
|
||||
end
|
||||
|
||||
def updateAddingIndexPathForCurrentLocation
|
||||
indexPath = indexPathFromRecognizer(@longPressRecognizer)
|
||||
if indexPath != @addingIndexPath
|
||||
@tableView.beginUpdates
|
||||
@tableView.deleteRowsAtIndexPaths([@addingIndexPath], withRowAnimation: UITableViewRowAnimationNone)
|
||||
@tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationNone)
|
||||
@delegate.gestureRecognizer(self, needsMoveRowAtIndexPath: @addingIndexPath, toIndexPath: indexPath)
|
||||
@tableView.endUpdates
|
||||
@addingIndexPath = indexPath
|
||||
end
|
||||
end
|
||||
|
||||
def commitOrDiscardCell
|
||||
cell = @tableView.cellForRowAtIndexPath(@addingIndexPath)
|
||||
|
||||
@tableView.beginUpdates
|
||||
|
||||
commitingCellHeight = @tableView.rowHeight
|
||||
if @delegate.respond_to? :"gestureRecognizer:heightForCommittingRowAtIndexPath:"
|
||||
commitingCellHeight = @delegate.gestureRecognizer(self, heightForCommittingRowAtIndexPath: @addingIndexPath)
|
||||
end
|
||||
|
||||
if cell.frame.size.height >= commitingCellHeight
|
||||
@delegate.gestureRecognizer(self, needsCommitRowAtIndexPath: @addingIndexPath)
|
||||
else
|
||||
@delegate.gestureRecognizer(self, needsDiscardRowAtIndexPath: @addingIndexPath)
|
||||
@tableView.deleteRowsAtIndexPaths([@addingIndexPath], withRowAnimation: UITableViewRowAnimationMiddle)
|
||||
end
|
||||
|
||||
@tableView.performSelector(:"reloadVisibleRowsExceptIndexPath:", withObject: @addingIndexPath, afterDelay: RowAnimationDuration)
|
||||
@addingIndexPath = nil
|
||||
|
||||
@tableView.endUpdates
|
||||
|
||||
UIView.beginAnimations('', context: nil)
|
||||
UIView.setAnimationBeginsFromCurrentState(true)
|
||||
UIView.setAnimationDuration(0.5)
|
||||
@tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
|
||||
UIView.commitAnimations
|
||||
|
||||
@state = :none
|
||||
end
|
||||
|
||||
def pinchGestureRecognizer(recognizer)
|
||||
if recognizer.state == UIGestureRecognizerStateEnded || recognizer.numberOfTouches < 2
|
||||
self.commitOrDiscardCell if @addingIndexPath
|
||||
return
|
||||
end
|
||||
|
||||
location1 = recognizer.locationOfTouch(0, inView: @tableView)
|
||||
location2 = recognizer.locationOfTouch(1, inView: @tableView)
|
||||
upperPoint = location1.y < location2.y ? location1 : location2
|
||||
|
||||
rect = CGRectMake(*location1, location2.x - location1.x, location2.y - location1.y)
|
||||
|
||||
if recognizer.state == UIGestureRecognizerStateBegan
|
||||
@state = :pinching
|
||||
indexPaths = @tableView.indexPathsForRowsInRect(rect)
|
||||
unless indexPaths.empty?
|
||||
midIndex = ((indexPaths.first.row + indexPaths.last.row) / 2.0) + 0.5
|
||||
midIndexPath = NSIndexPath.indexPathForRow(midIndex, inSection: indexPaths.first.section)
|
||||
|
||||
@startPinchingUpperPoint = upperPoint
|
||||
|
||||
if @delegate.respond_to? :"gestureRecognizer:willCreateCellAtIndexPath:"
|
||||
@addingIndexPath = @delegate.gestureRecognizer(self, willCreateCellAtIndexPath: midIndexPath)
|
||||
else
|
||||
@addingIndexPath = midIndexPath
|
||||
end
|
||||
|
||||
@tableView.contentInset = UIEdgeInsetsMake(@tableView.frame.size.height, 0, @tableView.frame.size.height, 0)
|
||||
|
||||
if @addingIndexPath
|
||||
@tableView.beginUpdates
|
||||
@delegate.gestureRecognizer(self, needsAddRowAtIndexPath: @addingIndexPath)
|
||||
@tableView.insertRowsAtIndexPaths([@addingIndexPath], withRowAnimation: UITableViewRowAnimationMiddle)
|
||||
@tableView.endUpdates
|
||||
end
|
||||
end
|
||||
elsif recognizer.state == UIGestureRecognizerStateChanged
|
||||
diffRowHeight = CGRectGetHeight(rect) - CGRectGetHeight(rect)/recognizer.scale
|
||||
if @addingRowHeight - diffRowHeight >= 1 || @addingRowHeight - diffRowHeight <= -1
|
||||
@addingRowHeight = diffRowHeight
|
||||
@tableView.reloadData
|
||||
end
|
||||
|
||||
newUpperPoint = upperPoint
|
||||
diffOffsetY = @startPinchingUpperPoint.y - newUpperPoint.y
|
||||
newOffset = CGPointMake(@tableView.contentOffset.x, @tableView.contentOffset.y + diffOffsetY)
|
||||
@tableView.setContentOffset(newOffset, animated: false)
|
||||
end
|
||||
end
|
||||
|
||||
def panGestureRecognizer(recognizer)
|
||||
if (recognizer.state == UIGestureRecognizerStateBegan ||
|
||||
recognizer.state == UIGestureRecognizerStateChanged) &&
|
||||
recognizer.numberOfTouches > 0
|
||||
|
||||
location1 = recognizer.locationOfTouch(0, inView: @tableView)
|
||||
indexPath = @addingIndexPath
|
||||
unless indexPath
|
||||
indexPath = @tableView.indexPathForRowAtPoint(location1)
|
||||
@addingIndexPath = indexPath
|
||||
end
|
||||
|
||||
@state = :panning
|
||||
cell = @tableView.cellForRowAtIndexPath(indexPath)
|
||||
translation = recognizer.translationInView(@tableView)
|
||||
cell.contentView.frame = CGRectOffset(cell.contentView.bounds, translation.x, 0)
|
||||
|
||||
if @delegate.respond_to? :"gestureRecognizer:didChangeContentViewTranslation:forRowAtIndexPath:"
|
||||
@delegate.gestureRecognizer(self, didChangeContentViewTranslation: translation, forRowAtIndexPath: indexPath)
|
||||
end
|
||||
|
||||
commitEditingLength = CommitEditingRowDefaultRowHeight
|
||||
if @delegate.respond_to? :"gestureRecognizer:lengthForCommitEditingRowAtIndexPath:"
|
||||
commitEditingLength = @delegate.gestureRecognizer(self, lengthForCommitEditingRowAtIndexPath: indexPath)
|
||||
end
|
||||
if translation.x.abs >= commitEditingLength
|
||||
if @addingCellState == :middle
|
||||
@addingCellState = translation.x > 0 ? :right : :left
|
||||
end
|
||||
else
|
||||
if @addingCellState != :middle
|
||||
@addingCellState = :middle
|
||||
end
|
||||
end
|
||||
|
||||
if @delegate.respond_to? :"gestureRecognizer:didEnterEditingState:forRowAtIndexPath:"
|
||||
@delegate.gestureRecognizer(self, didEnterEditingState: @addingCellState, forRowAtIndexPath: indexPath)
|
||||
end
|
||||
elsif recognizer.state == UIGestureRecognizerStateEnded
|
||||
cell = @tableView.cellForRowAtIndexPath(@addingIndexPath)
|
||||
translation = recognizer.translationInView(@tableView)
|
||||
|
||||
commitEditingLength = CommitEditingRowDefaultRowHeight
|
||||
if @delegate.respond_to? :"gestureRecognizer:lengthForCommitEditingRowAtIndexPath:"
|
||||
commitEditingLength = @delegate.gestureRecognizer(self, lengthForCommitEditingRowAtIndexPath: @addingIndexPath)
|
||||
end
|
||||
if translation.x.abs >= commitEditingLength
|
||||
if @delegate.respond_to? :"gestureRecognizer:commitEditingState:forRowAtIndexPath:"
|
||||
@delegate.gestureRecognizer(self, commitEditingState: @addingCellState, forRowAtIndexPath: @addingIndexPath)
|
||||
end
|
||||
else
|
||||
UIView.beginAnimations('', context: nil)
|
||||
cell.contentView.frame = cell.contentView.bounds
|
||||
UIView.commitAnimations
|
||||
end
|
||||
|
||||
@addingCellState = :middle
|
||||
@addingIndexPath = nil
|
||||
@state = :none
|
||||
end
|
||||
end
|
||||
|
||||
def longPressGestureRecognizer(recognizer)
|
||||
location = recognizer.locationInView(@tableView)
|
||||
indexPath = indexPathFromRecognizer(recognizer)
|
||||
|
||||
case recognizer.state
|
||||
when UIGestureRecognizerStateBegan
|
||||
@state = :moving
|
||||
|
||||
cell = @tableView.cellForRowAtIndexPath(indexPath)
|
||||
UIGraphicsBeginImageContextWithOptions(cell.bounds.size, false, 0)
|
||||
cell.layer.renderInContext(UIGraphicsGetCurrentContext())
|
||||
cellImage = UIGraphicsGetImageFromCurrentImageContext()
|
||||
UIGraphicsEndImageContext()
|
||||
|
||||
snapShotView = @tableView.viewWithTag(CellSnapshotTag)
|
||||
unless snapShotView
|
||||
snapShotView = UIImageView.alloc.initWithImage(cellImage)
|
||||
snapShotView.tag = CellSnapshotTag
|
||||
@tableView.addSubview(snapShotView)
|
||||
rect = @tableView.rectForRowAtIndexPath(indexPath)
|
||||
snapShotView.frame = CGRectOffset(snapShotView.bounds, rect.origin.x, rect.origin.y)
|
||||
end
|
||||
|
||||
UIView.beginAnimations('zoomCell', context: nil)
|
||||
snapShotView.transform = CGAffineTransformMakeScale(1.1, 1.1)
|
||||
snapShotView.center = CGPointMake(@tableView.center.x, location.y)
|
||||
UIView.commitAnimations
|
||||
|
||||
@tableView.beginUpdates
|
||||
@tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationNone)
|
||||
@tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationNone)
|
||||
@delegate.gestureRecognizer(self, needsCreatePlaceholderForRowAtIndexPath: indexPath)
|
||||
@addingIndexPath = indexPath
|
||||
@tableView.endUpdates
|
||||
|
||||
@movingTimer = NSTimer.timerWithTimeInterval((1/8.0), target: self, selector: :scrollTable, userInfo: nil, repeats: true)
|
||||
NSRunLoop.mainRunLoop.addTimer(@movingTimer, forMode: NSDefaultRunLoopMode)
|
||||
|
||||
when UIGestureRecognizerStateEnded
|
||||
snapShotView = @tableView.viewWithTag(CellSnapshotTag)
|
||||
indexPath = @addingIndexPath
|
||||
|
||||
@movingTimer.invalidate
|
||||
@movingTimer = nil
|
||||
@scrollingRate = 0
|
||||
|
||||
UIView.animateWithDuration(RowAnimationDuration,
|
||||
animations: -> do
|
||||
rect = @tableView.rectForRowAtIndexPath(indexPath)
|
||||
snapShotView.transform = CGAffineTransformIdentity
|
||||
snapShotView.frame = CGRectOffset(snapShotView.bounds, rect.origin.x, rect.origin.y)
|
||||
end,
|
||||
completion: ->(finished) do
|
||||
snapShotView.removeFromSuperview
|
||||
|
||||
@tableView.beginUpdates
|
||||
@tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationNone)
|
||||
@tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationNone)
|
||||
@delegate.gestureRecognizer(self, needsReplacePlaceholderForRowAtIndexPath: indexPath)
|
||||
@tableView.endUpdates
|
||||
|
||||
@tableView.reloadVisibleRowsExceptIndexPath(indexPath)
|
||||
@cellSnapshot = nil
|
||||
@addingIndexPath = nil
|
||||
@state = :none
|
||||
end)
|
||||
|
||||
when UIGestureRecognizerStateChanged
|
||||
snapShotView = @tableView.viewWithTag(CellSnapshotTag)
|
||||
snapShotView.center = CGPointMake(@tableView.center.x, location.y)
|
||||
|
||||
rect = @tableView.bounds
|
||||
location = @longPressRecognizer.locationInView(@tableView)
|
||||
location.y -= @tableView.contentOffset.y
|
||||
|
||||
self.updateAddingIndexPathForCurrentLocation
|
||||
|
||||
topDropZoneHeight = bottomDropZoneHeight = @tableView.bounds.size.height / 6.0
|
||||
bottomDiff = location.y - (rect.size.height - bottomDropZoneHeight)
|
||||
if bottomDiff > 0
|
||||
@scrollingRate = bottomDiff / (bottomDropZoneHeight / 1)
|
||||
elsif location.y <= topDropZoneHeight
|
||||
@scrollingRate = -(topDropZoneHeight - [location.y, 0].max) / bottomDropZoneHeight
|
||||
else
|
||||
@scrollingRate = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def gestureRecognizerShouldBegin(gestureRecognizer)
|
||||
indexPath = indexPathFromRecognizer(gestureRecognizer)
|
||||
|
||||
case gestureRecognizer
|
||||
when @panRecognizer
|
||||
point = gestureRecognizer.translationInView(@tableView)
|
||||
if point.y.abs > point.x.abs || indexPath.nil?
|
||||
false
|
||||
elsif indexPath
|
||||
@delegate.gestureRecognizer(self, canEditRowAtIndexPath: indexPath)
|
||||
end
|
||||
when @longPressRecognizer
|
||||
if indexPath
|
||||
@delegate.gestureRecognizer(self, canMoveRowAtIndexPath: indexPath)
|
||||
else
|
||||
false
|
||||
end
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def tableView(aTableView, heightForRowAtIndexPath: indexPath)
|
||||
if indexPath == @addingIndexPath && (@state == :pinching || @state == :dragging)
|
||||
[1, @addingRowHeight || 0].max
|
||||
else
|
||||
@tableViewDelegate.tableView(aTableView, heightForRowAtIndexPath: indexPath)
|
||||
end
|
||||
end
|
||||
|
||||
def scrollViewDidScroll(scrollView)
|
||||
if scrollView.contentOffset.y < 0
|
||||
if @addingIndexPath.nil? && @state == :none && !scrollView.isDecelerating
|
||||
@state = :dragging
|
||||
@addingIndexPath = NSIndexPath.indexPathForRow(0, inSection: 0)
|
||||
if @delegate.respond_to? :"gestureRecognizer:willCreateCellAtIndexPath:"
|
||||
@addingIndexPath = @delegate.gestureRecognizer(self, willCreateCellAtIndexPath: @addingIndexPath)
|
||||
end
|
||||
|
||||
@tableView.beginUpdates
|
||||
@delegate.gestureRecognizer(self, needsAddRowAtIndexPath: @addingIndexPath)
|
||||
@tableView.insertRowsAtIndexPaths([@addingIndexPath], withRowAnimation: UITableViewRowAnimationNone)
|
||||
@addingRowHeight = scrollView.contentOffset.y.abs
|
||||
@tableView.endUpdates
|
||||
end
|
||||
end
|
||||
|
||||
if @state == :dragging
|
||||
@addingRowHeight += scrollView.contentOffset.y * -1
|
||||
@tableView.reloadData
|
||||
scrollView.setContentOffset(CGPointZero)
|
||||
end
|
||||
end
|
||||
|
||||
def scrollViewDidEndDragging(scrollView, willDecelerate: decelerate)
|
||||
if @state == :dragging
|
||||
@state = :none
|
||||
self.commitOrDiscardCell
|
||||
end
|
||||
end
|
||||
|
||||
def forwardInvocation(anInvocation)
|
||||
anInvocation.invokeWithTarget(@tableViewDelegate)
|
||||
end
|
||||
|
||||
def methodSignatureForSelector(aSelector)
|
||||
@tableViewDelegate.methodSignatureForSelector(aSelector)
|
||||
end
|
||||
|
||||
def respondsToSelector(aSelector)
|
||||
if @tableViewDelegate.respondsToSelector(aSelector)
|
||||
true
|
||||
end
|
||||
self.class.instancesRespondToSelector(aSelector)
|
||||
end
|
||||
|
||||
private
|
||||
def indexPathFromRecognizer(recognizer)
|
||||
location = recognizer.locationInView(@tableView)
|
||||
@tableView.indexPathForRowAtPoint(location)
|
||||
end
|
||||
end
|
||||
|
||||
92
sample/gesture_table/app/transformable_cells.rb
Normal file
92
sample/gesture_table/app/transformable_cells.rb
Normal file
@@ -0,0 +1,92 @@
|
||||
class TransformableTableViewCell < UITableViewCell
|
||||
attr_accessor :finishedHeight, :tintColor
|
||||
|
||||
def self.transformableTableViewCellWithStyle(style, reuseIdentifier: reuseIdentifier)
|
||||
case style
|
||||
when :pullDown
|
||||
PullDownTableViewCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier: reuseIdentifier)
|
||||
when :unfolding
|
||||
UnfoldingTableViewCell.alloc.initWithStyle(UITableViewCellStyleSubtitle, reuseIdentifier: reuseIdentifier)
|
||||
else
|
||||
raise ArgumentError, "Style must be :pullDown or :unfolding"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class UnfoldingTableViewCell < TransformableTableViewCell
|
||||
def initWithStyle(style, reuseIdentifier: reuseIdentifier)
|
||||
if super
|
||||
transform = CATransform3DIdentity
|
||||
transform.m34 = -1 / 500.to_f
|
||||
contentView.layer.setSublayerTransform(transform)
|
||||
|
||||
textLabel.layer.anchorPoint = CGPointMake(0.5, 0.0)
|
||||
detailTextLabel.layer.anchorPoint = CGPointMake(0.5, 1.0)
|
||||
|
||||
textLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight
|
||||
detailTextLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight
|
||||
|
||||
self.selectionStyle = UITableViewCellSelectionStyleNone
|
||||
self.tintColor = UIColor.whiteColor
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def layoutSubviews
|
||||
super
|
||||
|
||||
fraction = self.frame.size.height / @finishedHeight.to_f
|
||||
fraction = [[1, fraction].min, 0].max
|
||||
|
||||
angle = (Math::PI / 2) - Math.asin(fraction)
|
||||
transform = CATransform3DMakeRotation(angle, -1, 0, 0)
|
||||
textLabel.layer.setTransform(transform)
|
||||
detailTextLabel.layer.setTransform(CATransform3DMakeRotation(angle, 1, 0, 0))
|
||||
|
||||
textLabel.backgroundColor = @tintColor.colorWithBrightness(0.3 + 0.7*fraction)
|
||||
detailTextLabel.backgroundColor = @tintColor.colorWithBrightness(0.5 + 0.5*fraction)
|
||||
|
||||
contentViewSize = contentView.frame.size
|
||||
contentViewMidY = contentViewSize.height / 2.0
|
||||
labelHeight = @finishedHeight / 2.0
|
||||
|
||||
textLabel.frame = [[0, contentViewMidY - (labelHeight * fraction)], [contentViewSize.width, labelHeight + 1]]
|
||||
detailTextLabel.frame = [[0, contentViewMidY - (labelHeight * (1 - fraction))], [contentViewSize.width, labelHeight]]
|
||||
end
|
||||
end
|
||||
|
||||
class PullDownTableViewCell < TransformableTableViewCell
|
||||
def initWithStyle(style, reuseIdentifier: reuseIdentifier)
|
||||
if super
|
||||
transform = CATransform3DIdentity
|
||||
transform.m34 = -1 / 500.to_f
|
||||
contentView.layer.setSublayerTransform(transform)
|
||||
|
||||
textLabel.layer.anchorPoint = CGPointMake(0.5, 1.0)
|
||||
textLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight
|
||||
|
||||
self.selectionStyle = UITableViewCellSelectionStyleNone
|
||||
|
||||
@tintColor = UIColor.whiteColor
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def layoutSubviews
|
||||
super
|
||||
|
||||
fraction = self.frame.size.height / @finishedHeight.to_f
|
||||
fraction = [[1, fraction].min, 0].max
|
||||
|
||||
angle = (Math::PI / 2) - Math.asin(fraction)
|
||||
transform = CATransform3DMakeRotation(angle, 1, 0, 0)
|
||||
textLabel.layer.setTransform(transform)
|
||||
|
||||
textLabel.backgroundColor = @tintColor.colorWithBrightness(0.3 + 0.7*fraction)
|
||||
|
||||
contentViewSize = self.contentView.frame.size
|
||||
labelHeight = @finishedHeight
|
||||
|
||||
self.textLabel.frame = [[0, contentViewSize.height - labelHeight], [contentViewSize.width, labelHeight]]
|
||||
end
|
||||
end
|
||||
173
sample/gesture_table/app/view_controller.rb
Normal file
173
sample/gesture_table/app/view_controller.rb
Normal file
@@ -0,0 +1,173 @@
|
||||
class ViewController < UITableViewController
|
||||
AddingCell = 'Continue...'
|
||||
DoneCell = 'Done'
|
||||
DummyCell = 'Dummy'
|
||||
CommittingCreateCellHeight = 60
|
||||
NormalCellFinishingHeight = 60
|
||||
|
||||
def loadView
|
||||
self.tableView = UITableView.new
|
||||
|
||||
@rows = ['Swipe to the right to complete', 'Swipe to left to delete', 'Drag down to create a new cell', 'Pinch two rows apart to create cell', 'Long hold to start reorder cell']
|
||||
@grabbedObject = nil
|
||||
@tableViewRecognizer = GestureRecognizer.alloc.initWithTableView(self.tableView, delegate:self)
|
||||
end
|
||||
|
||||
def viewWillAppear(animated)
|
||||
navigationController.setNavigationBarHidden(true, animated:false)
|
||||
end
|
||||
|
||||
def viewDidLoad
|
||||
tableView.backgroundColor = UIColor.blackColor
|
||||
tableView.separatorStyle = UITableViewCellSeparatorStyleNone
|
||||
tableView.rowHeight = NormalCellFinishingHeight
|
||||
end
|
||||
|
||||
def numberOfSectionsInTableView(tableView)
|
||||
1
|
||||
end
|
||||
|
||||
def tableView(tableView, numberOfRowsInSection: section)
|
||||
@rows.count
|
||||
end
|
||||
|
||||
def tableView(tableView, heightForRowAtIndexPath: indexPath)
|
||||
NormalCellFinishingHeight
|
||||
end
|
||||
|
||||
def tableView(tableView, cellForRowAtIndexPath: indexPath)
|
||||
object = @rows[indexPath.row]
|
||||
backgroundColor = backgroundColorForIndexPath(indexPath)
|
||||
|
||||
if object == AddingCell
|
||||
if indexPath.row == 0
|
||||
cellIdentifier = 'PullDownTableViewCell'
|
||||
cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier)
|
||||
unless cell
|
||||
cell = TransformableTableViewCell.transformableTableViewCellWithStyle(:pullDown, reuseIdentifier: cellIdentifier)
|
||||
cell.textLabel.adjustsFontSizeToFitWidth = true
|
||||
cell.textLabel.textColor = UIColor.whiteColor
|
||||
cell.textLabel.textAlignment = UITextAlignmentCenter
|
||||
end
|
||||
|
||||
cell.tintColor = backgroundColor
|
||||
cell.finishedHeight = CommittingCreateCellHeight
|
||||
cell.textLabel.text = cell.frame.size.height > CommittingCreateCellHeight ? 'Release to create cell...' : 'Continue Pulling...'
|
||||
cell.contentView.backgroundColor = UIColor.clearColor
|
||||
else
|
||||
cellIdentifier = 'UnfoldingTableViewCell'
|
||||
cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier)
|
||||
unless cell
|
||||
cell = TransformableTableViewCell.transformableTableViewCellWithStyle(:unfolding, reuseIdentifier: cellIdentifier)
|
||||
cell.textLabel.adjustsFontSizeToFitWidth = true
|
||||
cell.textLabel.textColor = UIColor.whiteColor
|
||||
cell.textLabel.textAlignment = UITextAlignmentCenter
|
||||
end
|
||||
|
||||
cell.tintColor = backgroundColor
|
||||
cell.finishedHeight = CommittingCreateCellHeight
|
||||
cell.textLabel.text = cell.frame.size.height > CommittingCreateCellHeight ? 'Release to create cell...' : 'Continue Pinching...'
|
||||
cell.contentView.backgroundColor = UIColor.clearColor
|
||||
cell.detailTextLabel.text = ' '
|
||||
end
|
||||
else
|
||||
cellIdentifier = 'MyCell'
|
||||
cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier)
|
||||
unless cell
|
||||
cell = UITableViewCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier: cellIdentifier)
|
||||
cell.textLabel.adjustsFontSizeToFitWidth = true
|
||||
cell.textLabel.backgroundColor = UIColor.clearColor
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone
|
||||
end
|
||||
|
||||
text = object.to_s
|
||||
textColor = UIColor.whiteColor
|
||||
if object == DoneCell
|
||||
textColor = UIColor.grayColor
|
||||
backgroundColor = UIColor.darkGrayColor
|
||||
elsif object == DummyCell
|
||||
text = ''
|
||||
backgroundColor = UIColor.clearColor
|
||||
end
|
||||
|
||||
cell.textLabel.text = text
|
||||
cell.textLabel.textColor = textColor
|
||||
cell.contentView.backgroundColor = backgroundColor
|
||||
end
|
||||
|
||||
cell
|
||||
end
|
||||
|
||||
def gestureRecognizer(gestureRecognizer, needsAddRowAtIndexPath: indexPath)
|
||||
@rows.insert(indexPath.row, AddingCell)
|
||||
end
|
||||
|
||||
def gestureRecognizer(gestureRecognizer, needsCommitRowAtIndexPath: indexPath)
|
||||
@rows[indexPath.row] = 'Added!'
|
||||
cell = gestureRecognizer.tableView.cellForRowAtIndexPath(indexPath)
|
||||
cell.finishedHeight = NormalCellFinishingHeight
|
||||
cell.textLabel.text = 'Just Added!'
|
||||
end
|
||||
|
||||
def gestureRecognizer(gestureRecognizer, needsDiscardRowAtIndexPath: indexPath)
|
||||
@rows.delete_at(indexPath.row)
|
||||
end
|
||||
|
||||
def gestureRecognizer(gestureRecognizer, didEnterEditingState: state, forRowAtIndexPath: indexPath)
|
||||
backgroundColor = case state
|
||||
when :middle
|
||||
backgroundColorForIndexPath(indexPath)
|
||||
when :right
|
||||
UIColor.greenColor
|
||||
else
|
||||
UIColor.darkGrayColor
|
||||
end
|
||||
|
||||
cell = tableView.cellForRowAtIndexPath(indexPath)
|
||||
cell.contentView.backgroundColor = backgroundColor
|
||||
cell.tintColor = backgroundColor if cell.kind_of? TransformableTableViewCell
|
||||
end
|
||||
|
||||
def gestureRecognizer(gestureRecognizer, canEditRowAtIndexPath: indexPath)
|
||||
true
|
||||
end
|
||||
|
||||
def gestureRecognizer(gestureRecognizer, commitEditingState: state, forRowAtIndexPath: indexPath)
|
||||
tableView.beginUpdates
|
||||
case state
|
||||
when :left
|
||||
@rows.delete_at(indexPath.row)
|
||||
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationLeft)
|
||||
when :right
|
||||
@rows[indexPath.row] = DoneCell
|
||||
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimationLeft)
|
||||
end
|
||||
tableView.endUpdates
|
||||
|
||||
tableView.performSelector(:"reloadVisibleRowsExceptIndexPath:", withObject: indexPath, afterDelay: GestureRecognizer::RowAnimationDuration)
|
||||
end
|
||||
|
||||
def gestureRecognizer(gestureRecognizer, canMoveRowAtIndexPath: indexPath)
|
||||
true
|
||||
end
|
||||
|
||||
def gestureRecognizer(gestureRecognizer, needsCreatePlaceholderForRowAtIndexPath: indexPath)
|
||||
@grabbedObject = @rows[indexPath.row]
|
||||
@rows[indexPath.row] = DummyCell
|
||||
end
|
||||
|
||||
def gestureRecognizer(gestureRecognizer, needsMoveRowAtIndexPath: sourceIndexPath, toIndexPath: destinationIndexPath)
|
||||
object = @rows[sourceIndexPath.row]
|
||||
@rows.delete_at(sourceIndexPath.row)
|
||||
@rows.insert(destinationIndexPath.row, object)
|
||||
end
|
||||
|
||||
def gestureRecognizer(gestureRecognizer, needsReplacePlaceholderForRowAtIndexPath: indexPath)
|
||||
@rows[indexPath.row] = @grabbedObject
|
||||
@grabbedObject = nil
|
||||
end
|
||||
|
||||
def backgroundColorForIndexPath(indexPath)
|
||||
UIColor.redColor.colorWithHueOffset(0.12 * indexPath.row / @rows.count)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user