Created
December 25, 2013 21:29
-
-
Save niw/8127127 to your computer and use it in GitHub Desktop.
あれ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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