Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kgn committed Jan 16, 2013
0 parents commit 2b0b90c
Show file tree
Hide file tree
Showing 16 changed files with 719 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.DS_Store
xcuserdata
32 changes: 32 additions & 0 deletions KGKeyboardChangeManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// KGKeyboardChangeManager.h
// KGKeyboardChangeManagerApp
//
// Created by David Keegan on 1/16/13.
// Copyright (c) 2013 David Keegan. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface KGKeyboardChangeManager : NSObject

typedef void (^KGKeyboardChangeManagerKeyboardOrientationBlock)(CGRect keyboardRect);
typedef void (^KGKeyboardChangeManagerKeyboardChangedBlock)(BOOL show, CGRect keyboardRect);

@property (nonatomic, readonly, getter=isKeyboardShowing) BOOL keyboardShowing;

+ (KGKeyboardChangeManager *)sharedManager;

// This block is run whenever the orientation of the keyboard changes.
- (id)addObserverForKeyboardOrientationChangedWithBlock:(KGKeyboardChangeManagerKeyboardOrientationBlock)block;

// The setup block is run before the animation block, this block can be used to configure anything that
// will be animated in the animation block. The animation block will be animated along with the keyboard animation.
- (id)addObserverForKeyboardChangedWithSetupBlock:(KGKeyboardChangeManagerKeyboardChangedBlock)setupBlock
andAnimationBlock:(KGKeyboardChangeManagerKeyboardChangedBlock)animationBlock;

// Observers should be removed so they are not run when the keyboard changes.
- (void)removeObserverWithKeyboardOrientationIdentifier:(id)identifier;
- (void)removeObserverWithKeyboardChangedIdentifier:(id)identifier;

@end
181 changes: 181 additions & 0 deletions KGKeyboardChangeManager.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
//
// KGKeyboardChangeManager.m
// KGKeyboardChangeManagerApp
//
// Created by David Keegan on 1/16/13.
// Copyright (c) 2013 David Keegan. All rights reserved.
//

#import "KGKeyboardChangeManager.h"

NSString *const kChangeSetupBlockKey = @"KGKeyboardChangeManagerChangeSetupBlockKey";
NSString *const kChangeAnimationBlockKey = @"KGKeyboardChangeManagerChangeAnimationBlockKey";

@interface KGKeyboardChangeManager()
@property (strong, atomic) NSMutableDictionary *changeCallbacks;
@property (strong, atomic) NSMutableDictionary *orientationCallbacks;
@property (nonatomic, readwrite, getter=isKeyboardShowing) BOOL keyboardShowing;
@property (nonatomic) BOOL orientationChange;
@end

@implementation KGKeyboardChangeManager

+ (KGKeyboardChangeManager *)sharedManager{
static dispatch_once_t onceToken;
static KGKeyboardChangeManager *sharedManager;
dispatch_once(&onceToken, ^{
sharedManager = [[self alloc] init];
});
return sharedManager;
}

- (id)init{
if(!(self = [super init])){
return nil;
}

self.changeCallbacks = [NSMutableDictionary dictionary];
self.orientationCallbacks = [NSMutableDictionary dictionary];

[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(keyboardWillShown:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationDidChange:)
name:UIDeviceOrientationDidChangeNotification object:nil];

return self;
}

- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - Observers

- (id)addObserverForKeyboardOrientationChangedWithBlock:(void(^)(CGRect keyboardRect))block{
NSString *identifier = [[NSProcessInfo processInfo] globallyUniqueString];
if(block){
self.orientationCallbacks[identifier] = block;
}
return identifier;
}

- (id)addObserverForKeyboardChangedWithSetupBlock:(KGKeyboardChangeManagerKeyboardChangedBlock)setupBlock andAnimationBlock:(KGKeyboardChangeManagerKeyboardChangedBlock)animationBlock{
NSString *identifier = [[NSProcessInfo processInfo] globallyUniqueString];
NSMutableDictionary *callbacks = [NSMutableDictionary dictionary];
if(setupBlock){
callbacks[kChangeSetupBlockKey] = setupBlock;
}
if(animationBlock){
callbacks[kChangeAnimationBlockKey] = animationBlock;
}
if([callbacks count]){
self.changeCallbacks[identifier] = [NSDictionary dictionaryWithDictionary:callbacks];
}
return identifier;
}

- (void)removeObserverWithKeyboardOrientationIdentifier:(id)identifier{
[self.orientationCallbacks removeObjectForKey:identifier];
}

- (void)removeObserverWithKeyboardChangedIdentifier:(id)identifier{
[self.changeCallbacks removeObjectForKey:identifier];
}

#pragma mark - Orientation

- (void)orientationDidChange:(NSNotification *)notification{
if(self.isKeyboardShowing){
self.orientationChange = YES;
}
}

#pragma mark - Keyboard

- (void)keyboardDidChange:(NSNotification *)notification show:(BOOL)show{
CGRect keyboardEndFrame;
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
NSDictionary *userInfo = [notification userInfo];

[userInfo[UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[userInfo[UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[userInfo[UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];

// The keyboard frame is in portrait space
CGRect newKeyboardEndFrame = CGRectZero;
UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
if(interfaceOrientation == UIInterfaceOrientationPortrait){
newKeyboardEndFrame = keyboardEndFrame;
}else if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft){
newKeyboardEndFrame.origin.y = CGRectGetMinX(keyboardEndFrame);
newKeyboardEndFrame.size.width = CGRectGetHeight(keyboardEndFrame);
newKeyboardEndFrame.size.height = CGRectGetWidth(keyboardEndFrame);
}else if(interfaceOrientation == UIInterfaceOrientationLandscapeRight){
newKeyboardEndFrame.size.width = CGRectGetHeight(keyboardEndFrame);
newKeyboardEndFrame.size.height = CGRectGetWidth(keyboardEndFrame);
newKeyboardEndFrame.origin.y = CGRectGetWidth([[UIScreen mainScreen] bounds])-CGRectGetHeight(newKeyboardEndFrame);
}else if(interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown){
newKeyboardEndFrame = keyboardEndFrame;
newKeyboardEndFrame.origin.y = CGRectGetHeight([[UIScreen mainScreen] bounds])-CGRectGetHeight(newKeyboardEndFrame);
}

// Call the appropriate callback
if(self.orientationChange){
[self.orientationCallbacks enumerateKeysAndObjectsUsingBlock:^(id key, KGKeyboardChangeManagerKeyboardOrientationBlock block, BOOL *stop){
if(block){
block(newKeyboardEndFrame);
}
}];
}else{
[self.changeCallbacks enumerateKeysAndObjectsUsingBlock:^(id key, NSDictionary *obj, BOOL *stop){
KGKeyboardChangeManagerKeyboardChangedBlock setupBlock = obj[kChangeSetupBlockKey];
if(setupBlock){
setupBlock(show, newKeyboardEndFrame);
}
}];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];

[self.changeCallbacks enumerateKeysAndObjectsUsingBlock:^(id key, NSDictionary *obj, BOOL *stop){
KGKeyboardChangeManagerKeyboardChangedBlock animationBlock = obj[kChangeAnimationBlockKey];
if(animationBlock){
animationBlock(show, newKeyboardEndFrame);
}
}];

[UIView commitAnimations];
}
}

- (void)keyboardWillHide:(NSNotification *)notification{
[self keyboardDidChange:notification show:NO];
}

- (void)keyboardDidHide:(NSNotification *)notification{
self.keyboardShowing = NO;
}

- (void)keyboardWillShown:(NSNotification *)notification{
[self keyboardDidChange:notification show:YES];
}

- (void)keyboardDidShow:(NSNotification *)notification{
self.keyboardShowing = YES;
self.orientationChange = NO;
}

@end
Binary file added SampleApp/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added SampleApp/Default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added SampleApp/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions SampleApp/KGKeyboardChangeManagerApp-Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.davidkeegan.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
14 changes: 14 additions & 0 deletions SampleApp/KGKeyboardChangeManagerApp-Prefix.pch
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// Prefix header for all source files of the 'KGKeyboardChangeManagerApp' target in the 'KGKeyboardChangeManagerApp' project
//

#import <Availability.h>

#ifndef __IPHONE_3_0
#warning "This project uses features only available in iOS SDK 3.0 and later."
#endif

#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
Loading

0 comments on commit 2b0b90c

Please sign in to comment.