diff --git a/DerpDemo/Default-568h@2x.png b/DerpDemo/Default-568h@2x.png
new file mode 100644
index 0000000..0891b7a
Binary files /dev/null and b/DerpDemo/Default-568h@2x.png differ
diff --git a/DerpDemo/Default.png b/DerpDemo/Default.png
new file mode 100644
index 0000000..4c8ca6f
Binary files /dev/null and b/DerpDemo/Default.png differ
diff --git a/DerpDemo/Default@2x.png b/DerpDemo/Default@2x.png
new file mode 100644
index 0000000..35b84cf
Binary files /dev/null and b/DerpDemo/Default@2x.png differ
diff --git a/DerpDemo/DerpDemo-Info.plist b/DerpDemo/DerpDemo-Info.plist
new file mode 100644
index 0000000..16da1ab
--- /dev/null
+++ b/DerpDemo/DerpDemo-Info.plist
@@ -0,0 +1,47 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ ${PRODUCT_NAME}
+ CFBundleExecutable
+ ${EXECUTABLE_NAME}
+ CFBundleIdentifier
+ de.yangmeyer.${PRODUCT_NAME:rfc1034identifier}
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ ${PRODUCT_NAME}
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ UIMainStoryboardFile
+ MainStoryboard_iPhone
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/DerpDemo/DerpDemo-Prefix.pch b/DerpDemo/DerpDemo-Prefix.pch
new file mode 100644
index 0000000..e5b2656
--- /dev/null
+++ b/DerpDemo/DerpDemo-Prefix.pch
@@ -0,0 +1,14 @@
+//
+// Prefix header for all source files of the 'DerpDemo' target in the 'DerpDemo' project
+//
+
+#import
+
+#ifndef __IPHONE_5_0
+#warning "This project uses features only available in iOS SDK 5.0 and later."
+#endif
+
+#ifdef __OBJC__
+ #import
+ #import
+#endif
diff --git a/DerpDemo/YMAppDelegate.h b/DerpDemo/YMAppDelegate.h
new file mode 100644
index 0000000..05e1187
--- /dev/null
+++ b/DerpDemo/YMAppDelegate.h
@@ -0,0 +1,11 @@
+
+// Created by YangMeyer on 17.10.12.
+// Copyright (c) 2012 Yang Meyer. All rights reserved.
+
+#import
+
+@interface YMAppDelegate : UIResponder
+
+@property (strong, nonatomic) UIWindow *window;
+
+@end
diff --git a/DerpDemo/YMAppDelegate.m b/DerpDemo/YMAppDelegate.m
new file mode 100644
index 0000000..bb3b0af
--- /dev/null
+++ b/DerpDemo/YMAppDelegate.m
@@ -0,0 +1,9 @@
+
+// Created by YangMeyer on 17.10.12.
+// Copyright (c) 2012 Yang Meyer. All rights reserved.
+
+#import "YMAppDelegate.h"
+
+@implementation YMAppDelegate
+
+@end
diff --git a/DerpDemo/YMViewController.h b/DerpDemo/YMViewController.h
new file mode 100644
index 0000000..98d55f6
--- /dev/null
+++ b/DerpDemo/YMViewController.h
@@ -0,0 +1,9 @@
+
+// Created by YangMeyer on 17.10.12.
+// Copyright (c) 2012 Yang Meyer. All rights reserved.
+
+#import
+
+@interface YMViewController : UIViewController
+
+@end
diff --git a/DerpDemo/YMViewController.m b/DerpDemo/YMViewController.m
new file mode 100644
index 0000000..1c36bc8
--- /dev/null
+++ b/DerpDemo/YMViewController.m
@@ -0,0 +1,28 @@
+
+// Created by YangMeyer on 17.10.12.
+// Copyright (c) 2012 Yang Meyer. All rights reserved.
+
+#import "YMViewController.h"
+#import "UIViewController+Derp.h"
+
+@implementation YMViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+ [self derp_addKeyboardViewHandlers];
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ [self derp_removeKeyboardViewHandlers];
+}
+
+- (BOOL)textFieldShouldReturn:(UITextField *)textField
+{
+ [textField resignFirstResponder];
+ return YES;
+}
+
+@end
diff --git a/DerpDemo/en.lproj/InfoPlist.strings b/DerpDemo/en.lproj/InfoPlist.strings
new file mode 100644
index 0000000..477b28f
--- /dev/null
+++ b/DerpDemo/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/DerpDemo/en.lproj/MainStoryboard_iPhone.storyboard b/DerpDemo/en.lproj/MainStoryboard_iPhone.storyboard
new file mode 100644
index 0000000..40f6d80
--- /dev/null
+++ b/DerpDemo/en.lproj/MainStoryboard_iPhone.storyboard
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DerpDemo/main.m b/DerpDemo/main.m
new file mode 100644
index 0000000..e849ae5
--- /dev/null
+++ b/DerpDemo/main.m
@@ -0,0 +1,18 @@
+//
+// main.m
+// DerpDemo
+//
+// Created by YangMeyer on 17.10.12.
+// Copyright (c) 2012 Mustacheware. All rights reserved.
+//
+
+#import
+
+#import "YMAppDelegate.h"
+
+int main(int argc, char *argv[])
+{
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([YMAppDelegate class]));
+ }
+}
diff --git a/DerpKit.xcodeproj/project.pbxproj b/DerpKit.xcodeproj/project.pbxproj
index 48901ce..e5ca53c 100644
--- a/DerpKit.xcodeproj/project.pbxproj
+++ b/DerpKit.xcodeproj/project.pbxproj
@@ -16,13 +16,28 @@
1ED3F1C515B2AD3B0011D729 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1ED3F1C415B2AD3B0011D729 /* Foundation.framework */; };
1ED3F1CA15B2AD3B0011D729 /* DerpKit.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1ED3F1C915B2AD3B0011D729 /* DerpKit.h */; };
1ED3F1D415B2AD3C0011D729 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1ED3F1D315B2AD3C0011D729 /* SenTestingKit.framework */; };
- 1ED3F1D615B2AD3C0011D729 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1ED3F1D515B2AD3C0011D729 /* UIKit.framework */; };
1ED3F1D715B2AD3C0011D729 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1ED3F1C415B2AD3B0011D729 /* Foundation.framework */; };
- 1ED3F1DA15B2AD3C0011D729 /* libDerpKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1ED3F1C115B2AD3B0011D729 /* libDerpKit.a */; };
1ED3F1E015B2AD3C0011D729 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1ED3F1DE15B2AD3C0011D729 /* InfoPlist.strings */; };
1ED3F1E315B2AD3C0011D729 /* DerpKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1ED3F1E215B2AD3C0011D729 /* DerpKitTests.m */; };
1ED3F1F215B2ADA90011D729 /* NSString+Derp.m in Sources */ = {isa = PBXBuildFile; fileRef = 1ED3F1F115B2ADA90011D729 /* NSString+Derp.m */; };
1ED3F1F515B2AE760011D729 /* NSData+Derp.m in Sources */ = {isa = PBXBuildFile; fileRef = 1ED3F1F415B2AE760011D729 /* NSData+Derp.m */; };
+ 2FC0D79A162EE6CD00387091 /* NSObject+YMOptionsAndDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FC0D799162EE6CD00387091 /* NSObject+YMOptionsAndDefaults.m */; };
+ 2FC0D79B162EE6CD00387091 /* NSObject+YMOptionsAndDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FC0D799162EE6CD00387091 /* NSObject+YMOptionsAndDefaults.m */; };
+ 2FC0D7A3162EE7D700387091 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FC0D7A0162EE7BA00387091 /* UIKit.framework */; };
+ 2FC0D7A4162EE7DE00387091 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FC0D7A0162EE7BA00387091 /* UIKit.framework */; };
+ 2FC0D7AC162EE8AB00387091 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FC0D7A0162EE7BA00387091 /* UIKit.framework */; };
+ 2FC0D7AD162EE8AB00387091 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1ED3F1C415B2AD3B0011D729 /* Foundation.framework */; };
+ 2FC0D7AF162EE8AB00387091 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FC0D7AE162EE8AB00387091 /* CoreGraphics.framework */; };
+ 2FC0D7B5162EE8AB00387091 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2FC0D7B3162EE8AB00387091 /* InfoPlist.strings */; };
+ 2FC0D7B7162EE8AB00387091 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FC0D7B6162EE8AB00387091 /* main.m */; };
+ 2FC0D7BB162EE8AB00387091 /* YMAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FC0D7BA162EE8AB00387091 /* YMAppDelegate.m */; };
+ 2FC0D7BD162EE8AB00387091 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 2FC0D7BC162EE8AB00387091 /* Default.png */; };
+ 2FC0D7BF162EE8AB00387091 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2FC0D7BE162EE8AB00387091 /* Default@2x.png */; };
+ 2FC0D7C1162EE8AB00387091 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2FC0D7C0162EE8AB00387091 /* Default-568h@2x.png */; };
+ 2FC0D7C4162EE8AB00387091 /* MainStoryboard_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2FC0D7C2162EE8AB00387091 /* MainStoryboard_iPhone.storyboard */; };
+ 2FC0D7CA162EE8AB00387091 /* YMViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FC0D7C9162EE8AB00387091 /* YMViewController.m */; };
+ 2FC0D7CE162EE93300387091 /* UIViewController+Derp.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E11A54915B331F100500EBD /* UIViewController+Derp.m */; };
+ 2FC0D7CF162EE94800387091 /* NSObject+YMOptionsAndDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FC0D799162EE6CD00387091 /* NSObject+YMOptionsAndDefaults.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -63,7 +78,6 @@
1ED3F1C915B2AD3B0011D729 /* DerpKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DerpKit.h; sourceTree = ""; };
1ED3F1D215B2AD3C0011D729 /* DerpKitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DerpKitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
1ED3F1D315B2AD3C0011D729 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
- 1ED3F1D515B2AD3C0011D729 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
1ED3F1DD15B2AD3C0011D729 /* DerpKitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "DerpKitTests-Info.plist"; sourceTree = ""; };
1ED3F1DF15B2AD3C0011D729 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
1ED3F1E115B2AD3C0011D729 /* DerpKitTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DerpKitTests.h; sourceTree = ""; };
@@ -72,6 +86,23 @@
1ED3F1F115B2ADA90011D729 /* NSString+Derp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Derp.m"; sourceTree = ""; };
1ED3F1F315B2AE760011D729 /* NSData+Derp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Derp.h"; sourceTree = ""; };
1ED3F1F415B2AE760011D729 /* NSData+Derp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Derp.m"; sourceTree = ""; };
+ 2FC0D798162EE6CD00387091 /* NSObject+YMOptionsAndDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+YMOptionsAndDefaults.h"; sourceTree = ""; };
+ 2FC0D799162EE6CD00387091 /* NSObject+YMOptionsAndDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+YMOptionsAndDefaults.m"; sourceTree = ""; };
+ 2FC0D7A0162EE7BA00387091 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ 2FC0D7AA162EE8AB00387091 /* DerpDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DerpDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 2FC0D7AE162EE8AB00387091 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 2FC0D7B2162EE8AB00387091 /* DerpDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "DerpDemo-Info.plist"; sourceTree = ""; };
+ 2FC0D7B4162EE8AB00387091 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
+ 2FC0D7B6162EE8AB00387091 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
+ 2FC0D7B8162EE8AB00387091 /* DerpDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DerpDemo-Prefix.pch"; sourceTree = ""; };
+ 2FC0D7B9162EE8AB00387091 /* YMAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YMAppDelegate.h; sourceTree = ""; };
+ 2FC0D7BA162EE8AB00387091 /* YMAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = YMAppDelegate.m; sourceTree = ""; };
+ 2FC0D7BC162EE8AB00387091 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; };
+ 2FC0D7BE162EE8AB00387091 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; };
+ 2FC0D7C0162EE8AB00387091 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; };
+ 2FC0D7C3162EE8AB00387091 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard_iPhone.storyboard; sourceTree = ""; };
+ 2FC0D7C8162EE8AB00387091 /* YMViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YMViewController.h; sourceTree = ""; };
+ 2FC0D7C9162EE8AB00387091 /* YMViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = YMViewController.m; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -79,6 +110,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 2FC0D7A4162EE7DE00387091 /* UIKit.framework in Frameworks */,
1ED3F1C515B2AD3B0011D729 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -87,10 +119,19 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 2FC0D7A3162EE7D700387091 /* UIKit.framework in Frameworks */,
1ED3F1D415B2AD3C0011D729 /* SenTestingKit.framework in Frameworks */,
- 1ED3F1D615B2AD3C0011D729 /* UIKit.framework in Frameworks */,
1ED3F1D715B2AD3C0011D729 /* Foundation.framework in Frameworks */,
- 1ED3F1DA15B2AD3C0011D729 /* libDerpKit.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 2FC0D7A7162EE8AB00387091 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2FC0D7AC162EE8AB00387091 /* UIKit.framework in Frameworks */,
+ 2FC0D7AD162EE8AB00387091 /* Foundation.framework in Frameworks */,
+ 2FC0D7AF162EE8AB00387091 /* CoreGraphics.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -127,6 +168,7 @@
children = (
1ED3F1C615B2AD3B0011D729 /* DerpKit */,
1ED3F1DB15B2AD3C0011D729 /* DerpKitTests */,
+ 2FC0D7B0162EE8AB00387091 /* DerpDemo */,
1ED3F1C315B2AD3B0011D729 /* Frameworks */,
1ED3F1C215B2AD3B0011D729 /* Products */,
);
@@ -137,6 +179,7 @@
children = (
1ED3F1C115B2AD3B0011D729 /* libDerpKit.a */,
1ED3F1D215B2AD3C0011D729 /* DerpKitTests.octest */,
+ 2FC0D7AA162EE8AB00387091 /* DerpDemo.app */,
);
name = Products;
sourceTree = "";
@@ -146,7 +189,8 @@
children = (
1ED3F1C415B2AD3B0011D729 /* Foundation.framework */,
1ED3F1D315B2AD3C0011D729 /* SenTestingKit.framework */,
- 1ED3F1D515B2AD3C0011D729 /* UIKit.framework */,
+ 2FC0D7A0162EE7BA00387091 /* UIKit.framework */,
+ 2FC0D7AE162EE8AB00387091 /* CoreGraphics.framework */,
);
name = Frameworks;
sourceTree = "";
@@ -198,10 +242,39 @@
1ED3F1F415B2AE760011D729 /* NSData+Derp.m */,
1EABBD6116223801001B9331 /* NSObject+Derp.h */,
1EABBD6216223801001B9331 /* NSObject+Derp.m */,
+ 2FC0D798162EE6CD00387091 /* NSObject+YMOptionsAndDefaults.h */,
+ 2FC0D799162EE6CD00387091 /* NSObject+YMOptionsAndDefaults.m */,
);
path = Categories;
sourceTree = "";
};
+ 2FC0D7B0162EE8AB00387091 /* DerpDemo */ = {
+ isa = PBXGroup;
+ children = (
+ 2FC0D7B9162EE8AB00387091 /* YMAppDelegate.h */,
+ 2FC0D7BA162EE8AB00387091 /* YMAppDelegate.m */,
+ 2FC0D7C2162EE8AB00387091 /* MainStoryboard_iPhone.storyboard */,
+ 2FC0D7C8162EE8AB00387091 /* YMViewController.h */,
+ 2FC0D7C9162EE8AB00387091 /* YMViewController.m */,
+ 2FC0D7B1162EE8AB00387091 /* Supporting Files */,
+ );
+ path = DerpDemo;
+ sourceTree = "";
+ };
+ 2FC0D7B1162EE8AB00387091 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 2FC0D7B2162EE8AB00387091 /* DerpDemo-Info.plist */,
+ 2FC0D7B3162EE8AB00387091 /* InfoPlist.strings */,
+ 2FC0D7B6162EE8AB00387091 /* main.m */,
+ 2FC0D7B8162EE8AB00387091 /* DerpDemo-Prefix.pch */,
+ 2FC0D7BC162EE8AB00387091 /* Default.png */,
+ 2FC0D7BE162EE8AB00387091 /* Default@2x.png */,
+ 2FC0D7C0162EE8AB00387091 /* Default-568h@2x.png */,
+ );
+ name = "Supporting Files";
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -241,6 +314,23 @@
productReference = 1ED3F1D215B2AD3C0011D729 /* DerpKitTests.octest */;
productType = "com.apple.product-type.bundle";
};
+ 2FC0D7A9162EE8AB00387091 /* DerpDemo */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 2FC0D7CB162EE8AB00387091 /* Build configuration list for PBXNativeTarget "DerpDemo" */;
+ buildPhases = (
+ 2FC0D7A6162EE8AB00387091 /* Sources */,
+ 2FC0D7A7162EE8AB00387091 /* Frameworks */,
+ 2FC0D7A8162EE8AB00387091 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = DerpDemo;
+ productName = DerpDemo;
+ productReference = 2FC0D7AA162EE8AB00387091 /* DerpDemo.app */;
+ productType = "com.apple.product-type.application";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -264,6 +354,7 @@
targets = (
1ED3F1C015B2AD3B0011D729 /* DerpKit */,
1ED3F1D115B2AD3C0011D729 /* DerpKitTests */,
+ 2FC0D7A9162EE8AB00387091 /* DerpDemo */,
);
};
/* End PBXProject section */
@@ -277,6 +368,18 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 2FC0D7A8162EE8AB00387091 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2FC0D7B5162EE8AB00387091 /* InfoPlist.strings in Resources */,
+ 2FC0D7BD162EE8AB00387091 /* Default.png in Resources */,
+ 2FC0D7BF162EE8AB00387091 /* Default@2x.png in Resources */,
+ 2FC0D7C1162EE8AB00387091 /* Default-568h@2x.png in Resources */,
+ 2FC0D7C4162EE8AB00387091 /* MainStoryboard_iPhone.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@@ -304,6 +407,7 @@
1ED3F1F515B2AE760011D729 /* NSData+Derp.m in Sources */,
1E11A54A15B331F100500EBD /* UIViewController+Derp.m in Sources */,
1EABBD6316223801001B9331 /* NSObject+Derp.m in Sources */,
+ 2FC0D79A162EE6CD00387091 /* NSObject+YMOptionsAndDefaults.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -312,6 +416,19 @@
buildActionMask = 2147483647;
files = (
1ED3F1E315B2AD3C0011D729 /* DerpKitTests.m in Sources */,
+ 2FC0D79B162EE6CD00387091 /* NSObject+YMOptionsAndDefaults.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 2FC0D7A6162EE8AB00387091 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2FC0D7B7162EE8AB00387091 /* main.m in Sources */,
+ 2FC0D7BB162EE8AB00387091 /* YMAppDelegate.m in Sources */,
+ 2FC0D7CA162EE8AB00387091 /* YMViewController.m in Sources */,
+ 2FC0D7CE162EE93300387091 /* UIViewController+Derp.m in Sources */,
+ 2FC0D7CF162EE94800387091 /* NSObject+YMOptionsAndDefaults.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -334,6 +451,22 @@
name = InfoPlist.strings;
sourceTree = "";
};
+ 2FC0D7B3162EE8AB00387091 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 2FC0D7B4162EE8AB00387091 /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "";
+ };
+ 2FC0D7C2162EE8AB00387091 /* MainStoryboard_iPhone.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 2FC0D7C3162EE8AB00387091 /* en */,
+ );
+ name = MainStoryboard_iPhone.storyboard;
+ sourceTree = "";
+ };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
@@ -441,6 +574,37 @@
};
name = Release;
};
+ 2FC0D7CC162EE8AB00387091 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_WARN_EMPTY_BODY = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "DerpDemo/DerpDemo-Prefix.pch";
+ INFOPLIST_FILE = "DerpDemo/DerpDemo-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = 1;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ 2FC0D7CD162EE8AB00387091 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_WARN_EMPTY_BODY = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "DerpDemo/DerpDemo-Prefix.pch";
+ INFOPLIST_FILE = "DerpDemo/DerpDemo-Info.plist";
+ OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = 1;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -471,6 +635,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 2FC0D7CB162EE8AB00387091 /* Build configuration list for PBXNativeTarget "DerpDemo" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 2FC0D7CC162EE8AB00387091 /* Debug */,
+ 2FC0D7CD162EE8AB00387091 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = 1ED3F1B815B2AD3B0011D729 /* Project object */;
diff --git a/DerpKit/Foundation/Categories/NSObject+YMOptionsAndDefaults.h b/DerpKit/Foundation/Categories/NSObject+YMOptionsAndDefaults.h
new file mode 100644
index 0000000..105299b
--- /dev/null
+++ b/DerpKit/Foundation/Categories/NSObject+YMOptionsAndDefaults.h
@@ -0,0 +1,14 @@
+
+// Created by YangMeyer on 08.10.12.
+// Copyright (c) 2012 Yang Meyer. All rights reserved.
+
+#import
+
+@interface NSObject (YMOptionsAndDefaults)
+
+- (void)ym_registerOptions:(NSDictionary *)options
+ defaults:(NSDictionary *)defaults;
+
+- (id)ym_optionOrDefaultForKey:(NSString*)optionKey;
+
+@end
diff --git a/DerpKit/Foundation/Categories/NSObject+YMOptionsAndDefaults.m b/DerpKit/Foundation/Categories/NSObject+YMOptionsAndDefaults.m
new file mode 100644
index 0000000..a5e48db
--- /dev/null
+++ b/DerpKit/Foundation/Categories/NSObject+YMOptionsAndDefaults.m
@@ -0,0 +1,28 @@
+
+// Created by YangMeyer on 08.10.12.
+// Copyright (c) 2012 Yang Meyer. All rights reserved.
+
+#import "NSObject+YMOptionsAndDefaults.h"
+#import
+
+@implementation NSObject (YMOptionsAndDefaults)
+
+#define kYMStandardOptionsTableName @"YMStandardOptionsTableName"
+#define kYMStandardDefaultsTableName @"YMStandardDefaultsTableName"
+
+- (void)ym_registerOptions:(NSDictionary *)options
+ defaults:(NSDictionary *)defaults
+{
+ objc_setAssociatedObject(self, (__bridge const void *)(kYMStandardOptionsTableName), options, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ objc_setAssociatedObject(self, (__bridge const void *)(kYMStandardDefaultsTableName), defaults, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (id)ym_optionOrDefaultForKey:(NSString*)optionKey
+{
+ NSDictionary *options = objc_getAssociatedObject(self, (__bridge const void *)(kYMStandardOptionsTableName));
+ NSDictionary *defaults = objc_getAssociatedObject(self, (__bridge const void *)(kYMStandardDefaultsTableName));
+ NSAssert(defaults, @"Defaults must have been set when accessing options.");
+ return options[optionKey] ?: defaults[optionKey];
+}
+
+@end
diff --git a/DerpKit/UIKit/Categories/UIViewController+Derp.h b/DerpKit/UIKit/Categories/UIViewController+Derp.h
index 5e312f9..1de0111 100644
--- a/DerpKit/UIKit/Categories/UIViewController+Derp.h
+++ b/DerpKit/UIKit/Categories/UIViewController+Derp.h
@@ -8,12 +8,34 @@
#import
+extern const struct DerpKeyboardViewHandlerOptions {
+ __unsafe_unretained NSString *minHeight; // boxed CGFloat. default is 0.0.
+
+} DerpKeyboardViewHandlerOptions;
+
@interface UIViewController (Derp)
-(BOOL)derp_isViewVisible;
-(void)derp_performIfVisible:(dispatch_block_t)handler;
+/**
+ For Auto Layout, use `-derp_addKeyboardViewHandlersWithConstraint:options:` instead.
+ */
-(void)derp_addKeyboardViewHandlers;
+
+/**
+ For Auto Layout, use `-derp_addKeyboardViewHandlersWithConstraint:options:` instead.
+ @param options see options keys above
+ */
+-(void)derp_addKeyboardViewHandlersWithOptions:(NSDictionary*)options;
+
+/**
+ Supports Auto Layout.
+ @param options see options keys above
+ @param constraints pass flush-bottom constraint (bottom space to superview is 0) - its constant will be increased to make space for the keyboard, and reset to 0 when the keyboard is dismissed
+ */
+-(void)derp_addKeyboardViewHandlersWithConstraint:(NSLayoutConstraint *)constraint options:(NSDictionary*)options;
+
-(void)derp_removeKeyboardViewHandlers;
@end
diff --git a/DerpKit/UIKit/Categories/UIViewController+Derp.m b/DerpKit/UIKit/Categories/UIViewController+Derp.m
index 8cad42e..1210525 100644
--- a/DerpKit/UIKit/Categories/UIViewController+Derp.m
+++ b/DerpKit/UIKit/Categories/UIViewController+Derp.m
@@ -8,6 +8,11 @@
#import "UIViewController+Derp.h"
#import
+#import "NSObject+YMOptionsAndDefaults.h"
+
+const struct DerpKeyboardViewHandlerOptions DerpKeyboardViewHandlerOptions = {
+ .minHeight = @"DerpKeyboardViewHandlerOptionMinimumHeight",
+};
@implementation UIViewController (Derp)
@@ -22,46 +27,66 @@ -(void)derp_performIfVisible:(dispatch_block_t)handler{
}
-(void)derp_addKeyboardViewHandlers{
+ [self derp_addKeyboardViewHandlersWithConstraint:nil options:nil];
+}
+
+-(void)derp_adaptViewFrameAfterKeyboardNotification:(NSNotification*)note appearing:(BOOL)appearing constraint:(NSLayoutConstraint*)constraint{
+ [self derp_performIfVisible:^{
+ CGRect userInfoKeyboardEndFrame = [(NSValue *)note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
+ CGRect keyboardFrame = [self.view convertRect:userInfoKeyboardEndFrame fromView:nil];
+
+ [UIView beginAnimations:@"UIKeyboard" context:nil];
+ [UIView setAnimationDuration:[note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
+ [UIView setAnimationCurve:[note.userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue]];
+ if (constraint) { // Auto Layout
+ constraint.constant = (appearing ? -keyboardFrame.size.height : 0.0);
+ [self.view layoutIfNeeded];
+ } else {
+ CGRect viewFrame = [self derp_viewFrameForKeyboardAppearing:appearing toFrame:keyboardFrame];
+ self.view.frame = viewFrame;
+ }
+
+ [UIView commitAnimations];
+ }];
+}
+
+-(void)derp_addKeyboardViewHandlersWithOptions:(NSDictionary*)options {
+ [self derp_addKeyboardViewHandlersWithConstraint:nil options:options];
+}
+
+-(void)derp_addKeyboardViewHandlersWithConstraint:(NSLayoutConstraint *)constraint options:(NSDictionary*)options {
+ [self ym_registerOptions:options defaults:@{
+ DerpKeyboardViewHandlerOptions.minHeight : @0.0,
+ }];
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
id willShow = [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification object:nil queue:mainQueue usingBlock:^(NSNotification *note) {
- [self derp_performIfVisible:^{
- CGRect keyboardFrame = [self.view convertRect:[(NSValue *)note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]
- fromView:nil];
- CGRect viewFrame = self.view.frame;
- viewFrame.size.height -= keyboardFrame.size.height;
-
- [UIView beginAnimations:@"UIKeyboard" context:nil];
-
- [UIView setAnimationDuration:[note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
- [UIView setAnimationCurve:[note.userInfo[UIKeyboardAnimationCurveUserInfoKey] intValue]];
-
- self.view.frame = viewFrame;
-
- [UIView commitAnimations];
- }];
+ [self derp_adaptViewFrameAfterKeyboardNotification:note appearing:YES constraint:constraint];
}];
id willHide = [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillHideNotification object:nil queue:mainQueue usingBlock:^(NSNotification *note) {
- [self derp_performIfVisible:^{
- CGRect keyboardFrame = [(NSValue *)note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
- CGRect viewFrame = self.view.frame;
- viewFrame.size.height += keyboardFrame.size.height;
-
- [UIView beginAnimations:@"UIKeyboard" context:nil];
-
- [UIView setAnimationDuration:[note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
- [UIView setAnimationCurve:[note.userInfo[UIKeyboardAnimationCurveUserInfoKey] intValue]];
-
- self.view.frame = viewFrame;
-
- [UIView commitAnimations];
- }];
+ [self derp_adaptViewFrameAfterKeyboardNotification:note appearing:NO constraint:constraint];
}];
objc_setAssociatedObject(self, "derp_willShowKeyboardNotification", willShow, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(self, "derp_willHideKeyboardNotification", willHide, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+-(CGRect)derp_viewFrameForKeyboardAppearing:(BOOL)isAppearing toFrame:(CGRect)keyboardFrame{
+ CGFloat minimumHeight = [[self ym_optionOrDefaultForKey:DerpKeyboardViewHandlerOptions.minHeight] floatValue];
+ CGRect viewFrame = self.view.frame;
+ CGFloat keyboardHeight = (isAppearing ? -1.0 : +1.0) * keyboardFrame.size.height;
+ if (viewFrame.size.height - keyboardFrame.size.height < minimumHeight) {
+ // pin at minimum height and nudge the whole frame up/down
+ viewFrame.size.height = minimumHeight;
+ viewFrame.origin.y = viewFrame.origin.y + keyboardHeight;
+ }
+ else {
+ // just adapt height
+ viewFrame.size.height = viewFrame.size.height + keyboardHeight;
+ }
+ return viewFrame;
+}
+
-(void)derp_removeKeyboardViewHandlers{
id willShow = objc_getAssociatedObject(self, "derp_willShowKeyboardNotification");
id willHide = objc_getAssociatedObject(self, "derp_willHideKeyboardNotification");