class Motion::KeyboardAvoiding

Constants

KEYBOARD_ANIMATION_DURATION
LANDSCAPE_KEYBOARD_HEIGHT
MAXIMUM_SCROLL_FRACTION
MINIMUM_SCROLL_FRACTION
PORTRAIT_KEYBOARD_HEIGHT

Attributes

active_text_field[RW]
animated_distance[RW]
view[RW]

Public Class Methods

new(view) click to toggle source
# File lib/project/motion-keyboard-avoiding.rb, line 11
def initialize(view)
  self.view = view

  listen

  view.instance_eval do
    def willMoveToWindow(window)
      NSNotificationCenter.defaultCenter.postNotificationName('WillMoveToWindow', object: self)
    end
  end

  add_tap_recognizer
end

Public Instance Methods

add_tap_recognizer() click to toggle source
# File lib/project/motion-keyboard-avoiding.rb, line 33
def add_tap_recognizer
  view.addGestureRecognizer(tap_recognizer)
end
dismiss_keyboard() click to toggle source
# File lib/project/motion-keyboard-avoiding.rb, line 41
def dismiss_keyboard
  active_text_field.resignFirstResponder if active_text_field
end
listen() click to toggle source
# File lib/project/motion-keyboard-avoiding.rb, line 25
def listen
  NSNotificationCenter.defaultCenter.addObserver(self, selector: 'reset:', name: 'WillMoveToWindow', object: view)
end
reset(notification) click to toggle source
# File lib/project/motion-keyboard-avoiding.rb, line 29
def reset(notification)
  active_text_field.resignFirstResponder if active_text_field
end
set_frame(frame) click to toggle source
# File lib/project/motion-keyboard-avoiding.rb, line 81
def set_frame(frame)
  UIView.beginAnimations(nil, context: nil)
  UIView.setAnimationBeginsFromCurrentState(true)
  UIView.setAnimationDuration(KEYBOARD_ANIMATION_DURATION)

  view.setFrame(frame)

  UIView.commitAnimations
end
tap_recognizer() click to toggle source
# File lib/project/motion-keyboard-avoiding.rb, line 37
def tap_recognizer
  UITapGestureRecognizer.alloc.initWithTarget(self, action: 'dismiss_keyboard')
end
textFieldDidBeginEditing(text_field) click to toggle source
# File lib/project/motion-keyboard-avoiding.rb, line 45
def textFieldDidBeginEditing(text_field)
  self.active_text_field = text_field

  text_field_rect = view.window.convertRect(text_field.bounds, fromView: text_field)
  view_rect       = view.window.convertRect(view.bounds, fromView: view)
  midline         = text_field_rect.origin.y + 0.5 * text_field_rect.size.height
  numerator       = midline - view_rect.origin.y - MINIMUM_SCROLL_FRACTION * view_rect.size.height
  denominator     = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * view_rect.size.height
  height_fraction = numerator / denominator

  if height_fraction < 0.0
    height_fraction = 0.0
  elsif height_fraction > 1.0
    height_fraction = 1.0
  end

  orientation = UIApplication.sharedApplication.statusBarOrientation
  if orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown
    self.animated_distance = (PORTRAIT_KEYBOARD_HEIGHT * height_fraction).floor
  else
    self.animated_distance = (LANDSCAPE_KEYBOARD_HEIGHT * height_fraction).floor
  end

  view_frame = view.frame
  view_frame.origin.y -= animated_distance

  set_frame(view_frame)
end
textFieldDidEndEditing(text_field) click to toggle source
# File lib/project/motion-keyboard-avoiding.rb, line 74
def textFieldDidEndEditing(text_field)
  view_frame = view.frame
  view_frame.origin.y += animated_distance || 0.0

  set_frame(view_frame)
end
textFieldShouldReturn(text_field) click to toggle source
# File lib/project/motion-keyboard-avoiding.rb, line 91
def textFieldShouldReturn(text_field)
  text_field.resignFirstResponder

  true
end
willMoveToWindow(window) click to toggle source
# File lib/project/motion-keyboard-avoiding.rb, line 17
def willMoveToWindow(window)
  NSNotificationCenter.defaultCenter.postNotificationName('WillMoveToWindow', object: self)
end