Skip to content

Instantly share code, notes, and snippets.

@takasek
Last active September 25, 2016 12:57
Show Gist options
  • Save takasek/441dc37f5b5df5f9cd0b to your computer and use it in GitHub Desktop.
Save takasek/441dc37f5b5df5f9cd0b to your computer and use it in GitHub Desktop.
ソフトウェアキーボードのinputAccessoryViewは、高さが可変だと辛い ref: http://qiita.com/takasek/items/db385a12cbc323e87832
@interface TSInputAccessoryView()
{
CGSize _keyboardSize;
BOOL _isKeyboardShown;
}
@end
@implementation TSInputAccessoryView
- (id)init
{
self = [super init];
if (self) {
_keyboardSize = CGSizeZero;
self.clipsToBounds = YES;
//ここポイント!アンカーポイントを下に設定しないと、iavが中空から現れる妙なアニメーションになる
self.layer.anchorPoint = CGPointMake(0.5, 1.0);
__weak typeof(self) weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardDidShowNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
LOG(@"%@", [note description]);
NSDictionary *userInfo = note.userInfo;
NSValue* value = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGFloat keyboardHeight = [value CGRectValue].size.height-weakSelf.bounds.size.height;
NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
LOG(@": duration(%f), %@",duration, [value description]);
if (keyboardHeight == 0) {
//キーボードが隠れる時に呼ばれた。処理不要なのでスルー
_isKeyboardShown = NO;
return;
} else {
_isKeyboardShown = YES;
}
if (duration == 0 && _keyboardSize.height == keyboardHeight) {
//inputAccessoryViewのフレーム変更。キーボードサイズの変更は不要。
return;
}
[weakSelf resizeWithKeyboardRect:value duration:duration/2];
}];
[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardDidHideNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
[weakSelf minimizeMyFrame];
}];
}
return self;
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)resizeWithKeyboardRect:(NSValue*)newKeyboardRectFromNotification duration:(NSTimeInterval)duration
{
LOG(@"■resizeWithKeyboardRect: => %@", newKeyboardRectFromNotification );
if (!_isKeyboardShown) {
//キーボードが表示されていない場合なにもしない
return;
}
CGSize keyboardSize = ({
CGSize result = CGSizeZero;
if (newKeyboardRectFromNotification) {
//存在する時のみ更新
CGSize wholeKeyboardSize = [newKeyboardRectFromNotification CGRectValue].size;
result = CGSizeMake(wholeKeyboardSize.width, [newKeyboardRectFromNotification CGRectValue].size.height - self.frame.size.height);
}
result;
});
if (!CGSizeEqualToSize(keyboardSize, CGSizeZero)) {
if (_keyboardSize.height != keyboardSize.height) {
LOG(@"resizeWithKeyboardRect:size changed from notification!: %@", NSStringFromCGSize(keyboardSize) );
_keyboardSize = keyboardSize;
}
}
//最終的な目標値を算出
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
CGFloat aimingHeight = MIN(
screenHeight - _keyboardSize.height - self.minimumUpperAreaHeight,
self.targetTextViewHeight
);
CGRect newFrame = CGRectMake(0, 0, _keyboardSize.width, aimingHeight);
[self setFrame:CGRectMake(0, aimingHeight, _keyboardSize.width, 0)];
LOG(@"resizeWithKeyboardRect: set frame %@ => %@", NSStringFromCGRect(self.frame), NSStringFromCGRect(newFrame));
__weak typeof(self) weakSelf = self;
[UIView animateKeyframesWithDuration:duration delay:0 options:UIViewKeyframeAnimationOptionBeginFromCurrentState animations:^{
[weakSelf setFrame:newFrame];
} completion:nil];
}
-(void)minimizeMyFrame
{
[self setFrame:CGRectMake(0, 0, _keyboardSize.width, 0)];
}
@end
@interface TSInputAccessoryView()
{
CGSize _keyboardSize;
BOOL _isKeyboardShown;
}
@end
@implementation TSInputAccessoryView
- (id)init
{
self = [super init];
if (self) {
_keyboardSize = CGSizeZero;
self.clipsToBounds = YES;
//ここポイント!アンカーポイントを下に設定しないと、iavが中空から現れる妙なアニメーションになる
self.layer.anchorPoint = CGPointMake(0.5, 1.0);
__weak typeof(self) weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardDidShowNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
LOG(@"%@", [note description]);
NSDictionary *userInfo = note.userInfo;
NSValue* value = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGFloat keyboardHeight = [value CGRectValue].size.height-weakSelf.bounds.size.height;
NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
LOG(@": duration(%f), %@",duration, [value description]);
if (keyboardHeight == 0) {
//キーボードが隠れる時に呼ばれた。処理不要なのでスルー
_isKeyboardShown = NO;
return;
} else {
_isKeyboardShown = YES;
}
if (duration == 0 && _keyboardSize.height == keyboardHeight) {
//inputAccessoryViewのフレーム変更。キーボードサイズの変更は不要。
return;
}
[weakSelf resizeWithKeyboardRect:value duration:duration/2];
}];
[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardDidHideNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
[weakSelf minimizeMyFrame];
}];
}
return self;
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)resizeWithKeyboardRect:(NSValue*)newKeyboardRectFromNotification duration:(NSTimeInterval)duration
{
LOG(@"■resizeWithKeyboardRect: => %@", newKeyboardRectFromNotification );
if (!_isKeyboardShown) {
//キーボードが表示されていない場合なにもしない
return;
}
CGSize keyboardSize = ({
CGSize result = CGSizeZero;
if (newKeyboardRectFromNotification) {
//存在する時のみ更新
CGSize wholeKeyboardSize = [newKeyboardRectFromNotification CGRectValue].size;
result = CGSizeMake(wholeKeyboardSize.width, [newKeyboardRectFromNotification CGRectValue].size.height - self.frame.size.height);
}
result;
});
if (!CGSizeEqualToSize(keyboardSize, CGSizeZero)) {
if (_keyboardSize.height != keyboardSize.height) {
LOG(@"resizeWithKeyboardRect:size changed from notification!: %@", NSStringFromCGSize(keyboardSize) );
_keyboardSize = keyboardSize;
}
}
//最終的な目標値を算出
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
CGFloat aimingHeight = MIN(
screenHeight - _keyboardSize.height - self.minimumUpperAreaHeight,
self.targetTextViewHeight
);
CGRect newFrame = CGRectMake(0, 0, _keyboardSize.width, aimingHeight);
[self setFrame:CGRectMake(0, aimingHeight, _keyboardSize.width, 0)];
LOG(@"resizeWithKeyboardRect: set frame %@ => %@", NSStringFromCGRect(self.frame), NSStringFromCGRect(newFrame));
__weak typeof(self) weakSelf = self;
[UIView animateKeyframesWithDuration:duration delay:0 options:UIViewKeyframeAnimationOptionBeginFromCurrentState animations:^{
[weakSelf setFrame:newFrame];
} completion:nil];
}
-(void)minimizeMyFrame
{
[self setFrame:CGRectMake(0, 0, _keyboardSize.width, 0)];
}
@end
2014-05-22 19:32:32.408 iOS[10476:60b] NSConcreteNotification 0x170441050 {name = UIKeyboardWillChangeFrameNotification; userInfo = {
UIKeyboardAnimationCurveUserInfoKey = 7;
UIKeyboardAnimationDurationUserInfoKey = 0;
UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 252}}";
UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 478}";
UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 442}";
UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 352}, {320, 216}}";
UIKeyboardFrameChangedByUserInteraction = 0;
UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 316}, {320, 252}}";
}}
2014-05-22 19:32:32.409 iOS[10476:60b] NSConcreteNotification 0x170441050 {name = UIKeyboardWillShowNotification; userInfo = {
UIKeyboardAnimationCurveUserInfoKey = 7;
UIKeyboardAnimationDurationUserInfoKey = 0;
UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 252}}";
UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 478}";
UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 442}";
UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 352}, {320, 216}}";
UIKeyboardFrameChangedByUserInteraction = 0;
UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 316}, {320, 252}}";
}}
2014-05-22 19:32:32.417 iOS[10476:60b] NSConcreteNotification 0x17825a0d0 {name = UIKeyboardDidChangeFrameNotification; userInfo = {
UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 252}}";
UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 478}";
UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 442}";
UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 352}, {320, 216}}";
UIKeyboardFrameChangedByUserInteraction = 0;
UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 316}, {320, 252}}";
}}
2014-05-22 19:32:32.418 iOS[10476:60b] : duration(0.000000), NSRect: {{0, 316}, {320, 252}}
2014-05-22 19:32:32.418 iOS[10476:60b] NSConcreteNotification 0x17825a0d0 {name = UIKeyboardDidShowNotification; userInfo = {
UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 252}}";
UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 478}";
UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 442}";
UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 352}, {320, 216}}";
UIKeyboardFrameChangedByUserInteraction = 0;
UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 316}, {320, 252}}";
}}
2014-05-22 19:32:32.408 TenSec iOS[10476:60b] NSConcreteNotification 0x170441050 {name = UIKeyboardWillChangeFrameNotification; userInfo = {
UIKeyboardAnimationCurveUserInfoKey = 7;
UIKeyboardAnimationDurationUserInfoKey = 0;
UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 252}}";
UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 478}";
UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 442}";
UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 352}, {320, 216}}";
UIKeyboardFrameChangedByUserInteraction = 0;
UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 316}, {320, 252}}";
}}
2014-05-22 19:32:32.409 TenSec iOS[10476:60b] NSConcreteNotification 0x170441050 {name = UIKeyboardWillShowNotification; userInfo = {
UIKeyboardAnimationCurveUserInfoKey = 7;
UIKeyboardAnimationDurationUserInfoKey = 0;
UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 252}}";
UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 478}";
UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 442}";
UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 352}, {320, 216}}";
UIKeyboardFrameChangedByUserInteraction = 0;
UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 316}, {320, 252}}";
}}
2014-05-22 19:32:32.417 TenSec iOS[10476:60b] NSConcreteNotification 0x17825a0d0 {name = UIKeyboardDidChangeFrameNotification; userInfo = {
UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 252}}";
UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 478}";
UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 442}";
UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 352}, {320, 216}}";
UIKeyboardFrameChangedByUserInteraction = 0;
UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 316}, {320, 252}}";
}}
2014-05-22 19:32:32.418 TenSec iOS[10476:60b] : duration(0.000000), NSRect: {{0, 316}, {320, 252}}
2014-05-22 19:32:32.418 TenSec iOS[10476:60b] NSConcreteNotification 0x17825a0d0 {name = UIKeyboardDidShowNotification; userInfo = {
UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 252}}";
UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 478}";
UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 442}";
UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 352}, {320, 216}}";
UIKeyboardFrameChangedByUserInteraction = 0;
UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 316}, {320, 252}}";
}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment