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");