Skip to content

Instantly share code, notes, and snippets.

@niw
Created December 25, 2013 21:29
Show Gist options
  • Save niw/8127127 to your computer and use it in GitHub Desktop.
Save niw/8127127 to your computer and use it in GitHub Desktop.
あれ
#define ANIMATION_DURATION 0.2f
#define TRIGGER_DELTA 40.0f
@interface MainViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate>
@end
@implementation MainViewController
{
UITableView *_tableView;
UIView *_accessoryView;
UITextField *_textField;
CGRect _initialKeyboardFrame;
CGFloat _maxKeyboardViewY, _minKeyboardViewY;
CGPoint _initialContentOffset;
BOOL _isKeyboardDisplayed;
NSMutableArray *_items;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_items = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < 30; ++i) {
[_items addObject:[NSString stringWithFormat:@"Dummy Item %d", i]];
}
self.title = @"Keyboard View Test";
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (UIView *)_keyboardView
{
return _accessoryView.superview;
}
- (void)_setScrollViewBottomInset:(CGFloat)bottomInset
{
UIEdgeInsets insets;
insets = _tableView.contentInset;
insets.bottom = bottomInset;
_tableView.contentInset = insets;
insets = _tableView.scrollIndicatorInsets;
insets.bottom = bottomInset;
_tableView.scrollIndicatorInsets = insets;
}
#pragma UIViewController
- (void)loadView
{
[super loadView];
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
_tableView.delegate = self;
_tableView.dataSource = self;
[self.view addSubview:_tableView];
_accessoryView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.bounds.size.width, 40.0f)];
_accessoryView.backgroundColor = [UIColor lightGrayColor];
_accessoryView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
_textField = [[UITextField alloc] initWithFrame:_accessoryView.bounds];
_textField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
_textField.delegate = self;
[_accessoryView addSubview:_textField];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectZero];
textField.hidden = YES;
textField.inputAccessoryView = _accessoryView;
[self.view addSubview:textField];
[textField becomeFirstResponder];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
#pragma mark Notifications
- (void)_keyboardWillShow:(NSNotification *)notification
{
NSDictionary* userInfo = [notification userInfo];
CGRect frame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSNumber* duration = userInfo[UIKeyboardAnimationDurationUserInfoKey];
UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue];
[UIView animateWithDuration:[duration doubleValue] animations:^{
[UIView setAnimationCurve:animationCurve];
[self _setScrollViewBottomInset:frame.size.height];
}];
}
- (void)_keyboardDidShow:(NSNotification *)notification
{
CGRect frame = [self _keyboardView].frame;
_minKeyboardViewY = CGRectGetMinY(frame);
_maxKeyboardViewY = CGRectGetMaxY(frame) - _accessoryView.frame.size.height;
[_textField becomeFirstResponder];
_isKeyboardDisplayed = YES;
}
- (void)_keyboardWillHide:(NSNotification *)notification
{
_isKeyboardDisplayed = NO;
}
#pragma mark UITableViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if (!_isKeyboardDisplayed) {
return;
}
_initialKeyboardFrame = [self _keyboardView].frame;
_initialContentOffset = scrollView.contentOffset;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (!_isKeyboardDisplayed || !scrollView.tracking) {
return;
}
UIView *keyboardView = _accessoryView.superview;
CGFloat delta = scrollView.contentOffset.y - _initialContentOffset.y;
CGRect frame = _initialKeyboardFrame;
CGFloat y = fminf(fmaxf(frame.origin.y - delta, _minKeyboardViewY), _maxKeyboardViewY);
if (y != frame.origin.y) {
frame.origin.y = y;
keyboardView.frame = frame;
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!_isKeyboardDisplayed) {
return;
}
UIView *keyboardView = _accessoryView.superview;
CGRect frame = keyboardView.frame;
CGFloat delta = frame.origin.y - _initialKeyboardFrame.origin.y;
if (delta > TRIGGER_DELTA) {
frame.origin.y = _maxKeyboardViewY;
} else if (delta < -TRIGGER_DELTA) {
frame.origin.y = _minKeyboardViewY;
} else {
frame = _initialKeyboardFrame;
}
[UIView animateWithDuration:ANIMATION_DURATION animations:^{
keyboardView.frame = frame;
// FIXME assuming the view and keyboard view is using same corrdinate.
// These are not on the same window.
[self _setScrollViewBottomInset:(self.view.bounds.size.height - frame.origin.y)];
}];
}
#pragma mark UITableViewDataSource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.textLabel.text = [_items objectAtIndex:indexPath.row];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_items count];
}
#pragma mark UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[self _addText:textField.text];
textField.text = @"";
return NO;
}
- (void)_addText:(NSString *)text
{
[_items addObject:[NSString stringWithString:text]];
[_tableView reloadData];
NSUInteger row = [_items count] - 1;
[_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment