├── DemoApp ├── DemoApp │ ├── en.lproj │ │ ├── InfoPlist.strings │ │ └── POViewController.xib │ ├── DemoApp-Prefix.pch │ ├── main.m │ ├── POAppDelegate.h │ ├── POViewController.h │ ├── DemoApp-Info.plist │ ├── POAppDelegate.m │ └── POViewController.m └── DemoApp.xcodeproj │ └── project.pbxproj ├── POViewFrameBuilder ├── UIView+POViewFrameBuilder.m ├── UIView+POViewFrameBuilder.h ├── POGeometry.h ├── POViewFrameBuilder.h └── POViewFrameBuilder.m ├── .gitignore ├── POViewFrameBuilder.podspec ├── LICENSE └── README.md /DemoApp/DemoApp/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /DemoApp/DemoApp/DemoApp-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'DemoApp' target in the 'DemoApp' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /DemoApp/DemoApp/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DemoApp 4 | // 5 | // Created by Sebastian Rehnby on 11/11/12. 6 | // Copyright (c) 2012 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "POAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([POAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /POViewFrameBuilder/UIView+POViewFrameBuilder.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+POViewFrameBuilder.m 3 | // 4 | // Created by Sebastian Rehnby on 10/11/12. 5 | // Copyright (c) 2012 Citrix Systems, Inc. All rights reserved. 6 | // 7 | 8 | #import "UIView+POViewFrameBuilder.h" 9 | 10 | @implementation UIView (POViewFrameBuilder) 11 | 12 | - (POViewFrameBuilder *)po_frameBuilder { 13 | return [POViewFrameBuilder frameBuilderForView:self]; 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /POViewFrameBuilder/UIView+POViewFrameBuilder.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+POViewFrameBuilder.h 3 | // 4 | // Created by Sebastian Rehnby on 10/11/12. 5 | // Copyright (c) 2012 Citrix Systems, Inc. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "POViewFrameBuilder.h" 10 | 11 | @interface UIView (POViewFrameBuilder) 12 | 13 | /** 14 | * Convenience method to return a new frame builder for this view. 15 | */ 16 | - (POViewFrameBuilder *)po_frameBuilder; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /DemoApp/DemoApp/POAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // POAppDelegate.h 3 | // DemoApp 4 | // 5 | // Created by Sebastian Rehnby on 11/11/12. 6 | // Copyright (c) 2012 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class POViewController; 12 | 13 | @interface POAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) POViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /DemoApp/DemoApp/POViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // POViewController.h 3 | // DemoApp 4 | // 5 | // Created by Sebastian Rehnby on 11/11/12. 6 | // Copyright (c) 2012 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface POViewController : UIViewController 12 | 13 | @property (weak, nonatomic) IBOutlet UIView *squareView; 14 | @property (weak, nonatomic) IBOutlet UIButton *animateButton; 15 | 16 | - (IBAction)animateButtonPressed; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | */build/* 3 | */Build/* 4 | DerivedData/* 5 | *.pbxuser 6 | !default.pbxuser 7 | *.mode1v3 8 | !default.mode1v3 9 | *.mode2v3 10 | !default.mode2v3 11 | *.perspectivev3 12 | !default.perspectivev3 13 | !default.xcworkspace 14 | project.xcworkspace 15 | xcuserdata 16 | profile 17 | *.moved-aside 18 | 19 | .DS_Store? 20 | 21 | # Thumbnails 22 | ._* 23 | 24 | # Files that might appear on external disk 25 | .Spotlight-V100 26 | .Trashes 27 | .DS_Store 28 | 29 | # opendiff merge 30 | *.BASE.* 31 | *.LOCAL.* 32 | *.REMOTE.* 33 | *.BACKUP.* 34 | *.orig 35 | 36 | # CocoaPods 37 | Pods 38 | -------------------------------------------------------------------------------- /POViewFrameBuilder.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "POViewFrameBuilder" 3 | s.version = "1.0.2" 4 | s.summary = "A small library for semantic layout of UIViews." 5 | s.homepage = "https://github.com/podio/ios-view-frame-builder" 6 | s.license = 'MIT' 7 | s.author = { "Sebastian Rehnby" => "sebastian@podio.com" } 8 | 9 | s.source = { :git => "https://github.com/podio/ios-view-frame-builder.git", :tag => s.version.to_s } 10 | s.platform = :ios, '5.0' 11 | s.source_files = 'POViewFrameBuilder/**/*.{h,m}' 12 | s.requires_arc = true 13 | end 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012 Copyright Citrix Systems, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to 8 | do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /DemoApp/DemoApp/DemoApp-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.podio.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # POViewFrameBuilder 2 | 3 | POViewFrameBuilder aims to provide a simple way to layout UIViews programatically while maintaining the semantics and readability of the code. It lets you modify a view's frame by chaining a series of readable layout methods. It reduces the amount of frame calculation code and keeps the intent of your layout clear. A handy tool for your average layoutSubviews, animation block etc. 4 | 5 | It is by no means complete, but rather contains a number of methods I have happened to need at various occasions. Feedback and pull requests are very welcome. 6 | 7 | ## Usage 8 | 9 | The following two examples give you a brief introduction on how POViewFrameBuilder can be used. Just include the `UIView+POViewFrameBuilder.h` category where you want to use it, and then you can access the `po_frameBuilder` convenience property to instantiate a frame builder for any `UIView` subclass. 10 | 11 | Resizing a view: 12 | 13 | [view.po_frameBuilder setWidth:100.0f height:40.0f]; 14 | 15 | Moving a view to be centered within it's superview: 16 | 17 | [view.po_frameBuilder centerInSuperview]; 18 | 19 | You can combine these methods to your own liking: 20 | 21 | [[view.po_frameBuilder setWidth:100.0f height:40.0f] centerHorizontallyInSuperview]; 22 | 23 | ## Demo 24 | 25 | The DemoApp project shows how POViewFrameBuilder can be used in animation blocks. One thing to note is that by default, the `automaticallyCommitChanges` property is set to `YES`. This means that the frame changes are committed after every modifying method in the chain. However, having multiple frame changes in an animation doesn't work, and the view ends up jumping around. To avoid this, begin the method chain by calling `disableAutoCommit` and finish the series of changes by calling the `commit` method, which will update the view's frame: 26 | 27 | [[[[view.po_frameBuilder disableAutoCommit] setWidth:100.0f height:40.0f] centerHorizontallyInSuperview] commit]; 28 | 29 | Thanks to [@rsobik](https://github.com/rsobik), there is now also a shorter and more readable way to create these transactions: 30 | 31 | [self.squareView.po_frameBuilder update:^(POViewFrameBuilder *builder) { 32 | [builder setWidth:100.0f height:40.0f]; 33 | [builder centerHorizontallyInSuperview]; 34 | }]; -------------------------------------------------------------------------------- /DemoApp/DemoApp/POAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // POAppDelegate.m 3 | // DemoApp 4 | // 5 | // Created by Sebastian Rehnby on 11/11/12. 6 | // Copyright (c) 2012 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import "POAppDelegate.h" 10 | 11 | #import "POViewController.h" 12 | 13 | @implementation POAppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 18 | // Override point for customization after application launch. 19 | self.viewController = [[POViewController alloc] initWithNibName:@"POViewController" bundle:nil]; 20 | self.window.rootViewController = self.viewController; 21 | [self.window makeKeyAndVisible]; 22 | return YES; 23 | } 24 | 25 | - (void)applicationWillResignActive:(UIApplication *)application 26 | { 27 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 28 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 29 | } 30 | 31 | - (void)applicationDidEnterBackground:(UIApplication *)application 32 | { 33 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 34 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 35 | } 36 | 37 | - (void)applicationWillEnterForeground:(UIApplication *)application 38 | { 39 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 40 | } 41 | 42 | - (void)applicationDidBecomeActive:(UIApplication *)application 43 | { 44 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 45 | } 46 | 47 | - (void)applicationWillTerminate:(UIApplication *)application 48 | { 49 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /DemoApp/DemoApp/POViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // POViewController.m 3 | // DemoApp 4 | // 5 | // Created by Sebastian Rehnby on 11/11/12. 6 | // Copyright (c) 2012 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import "POViewController.h" 10 | #import "UIView+POViewFrameBuilder.h" 11 | 12 | static NSTimeInterval kAnimationDuration = 1.0; 13 | static CGFloat kEdgeInset = 10.0f; 14 | 15 | @interface POViewController () 16 | 17 | @end 18 | 19 | @implementation POViewController 20 | 21 | - (void)resetSquareView { 22 | self.animateButton.enabled = YES; 23 | [[[[self.squareView.po_frameBuilder disableAutoCommit] setSizeWithWidth:40.0f height:40.0f] centerInSuperview] commit]; 24 | } 25 | 26 | - (void)animateSquareView { 27 | self.animateButton.enabled = NO; 28 | 29 | [UIView animateWithDuration:kAnimationDuration animations:^{ 30 | // Left and resize 31 | [self.squareView.po_frameBuilder update:^(POViewFrameBuilder *builder) { 32 | [builder setSizeWithWidth:60.0f height:60.0f]; 33 | [builder alignLeftInSuperviewWithInset:kEdgeInset]; 34 | }]; 35 | } completion:^(BOOL finished) { 36 | [UIView animateWithDuration:kAnimationDuration animations:^{ 37 | // Center at top 38 | [self.squareView.po_frameBuilder update:^(POViewFrameBuilder *builder) { 39 | [builder centerHorizontallyInSuperview]; 40 | [builder alignToTopInSuperviewWithInset:kEdgeInset]; 41 | }]; 42 | } completion:^(BOOL finished) { 43 | [UIView animateWithDuration:kAnimationDuration animations:^{ 44 | // Right 45 | [self.squareView.po_frameBuilder alignRightInSuperviewWithInset:kEdgeInset]; 46 | } completion:^(BOOL finished) { 47 | [UIView animateWithDuration:kAnimationDuration animations:^{ 48 | // Bottom 49 | [self.squareView.po_frameBuilder alignToBottomInSuperviewWithInset:kEdgeInset]; 50 | } completion:^(BOOL finished) { 51 | [UIView animateWithDuration:kAnimationDuration animations:^{ 52 | // Left 53 | [self.squareView.po_frameBuilder alignLeftInSuperviewWithInset:kEdgeInset]; 54 | } completion:^(BOOL finished) { 55 | // Back to the start 56 | [UIView animateWithDuration:kAnimationDuration animations:^{ 57 | [self resetSquareView]; 58 | } completion:nil]; 59 | }]; 60 | }]; 61 | }]; 62 | }]; 63 | }]; 64 | } 65 | 66 | - (void)viewWillAppear:(BOOL)animated { 67 | [super viewWillAppear:animated]; 68 | [self resetSquareView]; 69 | } 70 | 71 | - (IBAction)animateButtonPressed { 72 | [self animateSquareView]; 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /POViewFrameBuilder/POGeometry.h: -------------------------------------------------------------------------------- 1 | // 2 | // POGeometry.h 3 | // 4 | // Created by Sebastian Rehnby on 6/1/12. 5 | // Copyright (c) 2012 Citrix Systems, Inc. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | static inline CGRect PORectInsets(CGRect rect, CGFloat top, CGFloat left, CGFloat bottom, CGFloat right) { 11 | return UIEdgeInsetsInsetRect(rect, UIEdgeInsetsMake(top, left, bottom, right)); 12 | } 13 | 14 | static inline CGRect PORectWithSize(CGRect rect, CGFloat width, CGFloat height) { 15 | rect.size.width = width; 16 | rect.size.height = height; 17 | 18 | return rect; 19 | } 20 | 21 | static inline CGRect PORectFromSize(CGFloat width, CGFloat height) { 22 | return PORectWithSize(CGRectZero, width, height); 23 | } 24 | 25 | static inline CGRect PORectWithWidth(CGRect rect, CGFloat width) { 26 | rect.size.width = width; 27 | 28 | return rect; 29 | } 30 | 31 | static inline CGRect PORectWithHeight(CGRect rect, CGFloat height) { 32 | rect.size.height = height; 33 | 34 | return rect; 35 | } 36 | 37 | static inline CGRect PORectWithOrigin(CGRect rect, CGFloat x, CGFloat y) { 38 | rect.origin.x = x; 39 | rect.origin.y = y; 40 | 41 | return rect; 42 | } 43 | 44 | static inline CGRect PORectWithX(CGRect rect, CGFloat x) { 45 | rect.origin.x = x; 46 | 47 | return rect; 48 | } 49 | 50 | static inline CGRect PORectWithY(CGRect rect, CGFloat y) { 51 | rect.origin.y = y; 52 | 53 | return rect; 54 | } 55 | 56 | static inline CGPoint POPointWithOffset(CGPoint p, CGFloat dx, CGFloat dy) { 57 | return CGPointMake(p.x + dx, p.y + dy); 58 | } 59 | 60 | static inline CGPoint POPointCenterInSize(CGSize s) { 61 | return CGPointMake(roundf(s.width / 2), roundf(s.height / 2)); 62 | } 63 | 64 | static inline CGPoint POPointIntegral(CGPoint point) { 65 | point.x = floorf(point.x); 66 | point.y = floorf(point.y); 67 | return point; 68 | } 69 | 70 | static inline CGPoint PORectCenter(CGRect rect) { 71 | return POPointIntegral((CGPoint){ 72 | .x = CGRectGetMidX(rect), 73 | .y = CGRectGetMidY(rect) 74 | }); 75 | } 76 | 77 | static inline CGRect PORectMove(CGRect rect, CGFloat dx, CGFloat dy) { 78 | rect.origin.x += dx; 79 | rect.origin.y += dy; 80 | 81 | return rect; 82 | } 83 | 84 | static inline CGSize POEdgeInsetsInsetSize(CGSize size, UIEdgeInsets insets) { 85 | size.width -= (insets.left + insets.right); 86 | size.height -= (insets.top + insets.bottom); 87 | return size; 88 | } 89 | 90 | static inline UIEdgeInsets POEdgeInsetsUnion(UIEdgeInsets insets1, UIEdgeInsets insets2) { 91 | insets1.top += insets2.top; 92 | insets1.left += insets2.left; 93 | insets1.bottom += insets2.bottom; 94 | insets1.right += insets2.right; 95 | return insets1; 96 | } 97 | -------------------------------------------------------------------------------- /POViewFrameBuilder/POViewFrameBuilder.h: -------------------------------------------------------------------------------- 1 | // 2 | // POViewFrameBuilder.h 3 | // 4 | // Created by Sebastian Rehnby on 10/11/12. 5 | // Copyright (c) 2012 Citrix Systems, Inc. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | typedef NS_ENUM(NSUInteger, POViewFrameBuilderDirection) { 11 | POViewFrameBuilderDirectionRight = 0, 12 | POViewFrameBuilderDirectionLeft, 13 | POViewFrameBuilderDirectionUp, 14 | POViewFrameBuilderDirectionDown, 15 | }; 16 | 17 | @interface POViewFrameBuilder : NSObject 18 | 19 | @property (nonatomic, weak, readonly) UIView *view; 20 | @property (nonatomic) BOOL automaticallyCommitChanges; // Default is YES 21 | 22 | - (id)initWithView:(UIView *)view; 23 | 24 | + (POViewFrameBuilder *)frameBuilderForView:(UIView *)view; 25 | 26 | - (void)commit; 27 | - (void)reset; 28 | - (void)update:(void (^)(POViewFrameBuilder *builder))block; 29 | 30 | // Configure 31 | - (POViewFrameBuilder *)enableAutoCommit; 32 | - (POViewFrameBuilder *)disableAutoCommit; 33 | 34 | // Move 35 | - (POViewFrameBuilder *)setX:(CGFloat)x; 36 | - (POViewFrameBuilder *)setY:(CGFloat)y; 37 | - (POViewFrameBuilder *)setOriginWithX:(CGFloat)x y:(CGFloat)y; 38 | 39 | - (POViewFrameBuilder *)moveWithOffsetX:(CGFloat)offsetX; 40 | - (POViewFrameBuilder *)moveWithOffsetY:(CGFloat)offsetY; 41 | - (POViewFrameBuilder *)moveWithOffsetX:(CGFloat)offsetX offsetY:(CGFloat)offsetY; 42 | 43 | - (POViewFrameBuilder *)centerInSuperview; 44 | - (POViewFrameBuilder *)centerHorizontallyInSuperview; 45 | - (POViewFrameBuilder *)centerVerticallyInSuperview; 46 | 47 | - (POViewFrameBuilder *)alignToTopInSuperviewWithInset:(CGFloat)inset; 48 | - (POViewFrameBuilder *)alignToBottomInSuperviewWithInset:(CGFloat)inset; 49 | - (POViewFrameBuilder *)alignLeftInSuperviewWithInset:(CGFloat)inset; 50 | - (POViewFrameBuilder *)alignRightInSuperviewWithInset:(CGFloat)inset; 51 | 52 | - (POViewFrameBuilder *)alignToTopInSuperviewWithInsets:(UIEdgeInsets)insets; 53 | - (POViewFrameBuilder *)alignToBottomInSuperviewWithInsets:(UIEdgeInsets)insets; 54 | - (POViewFrameBuilder *)alignLeftInSuperviewWithInsets:(UIEdgeInsets)insets; 55 | - (POViewFrameBuilder *)alignRightInSuperviewWithInsets:(UIEdgeInsets)insets; 56 | 57 | - (POViewFrameBuilder *)alignToTopOfView:(UIView *)view offset:(CGFloat)offset; 58 | - (POViewFrameBuilder *)alignToBottomOfView:(UIView *)view offset:(CGFloat)offset; 59 | - (POViewFrameBuilder *)alignLeftOfView:(UIView *)view offset:(CGFloat)offset; 60 | - (POViewFrameBuilder *)alignRightOfView:(UIView *)view offset:(CGFloat)offset; 61 | 62 | + (void)alignViews:(NSArray *)views direction:(POViewFrameBuilderDirection)direction spacing:(CGFloat)spacing; 63 | + (void)alignViews:(NSArray *)views direction:(POViewFrameBuilderDirection)direction spacingWithBlock:(CGFloat (^)(UIView *firstView, UIView *secondView))block; 64 | 65 | + (void)alignViewsVertically:(NSArray *)views spacing:(CGFloat)spacing; 66 | + (void)alignViewsVertically:(NSArray *)views spacingWithBlock:(CGFloat (^)(UIView *firstView, UIView *secondView))block; 67 | + (void)alignViewsHorizontally:(NSArray *)views spacing:(CGFloat)spacing; 68 | + (void)alignViewsHorizontally:(NSArray *)views spacingWithBlock:(CGFloat (^)(UIView *firstView, UIView *secondView))block; 69 | 70 | + (CGFloat)heightForViewsAlignedVertically:(NSArray *)views spacing:(CGFloat)spacing; 71 | + (CGFloat)heightForViewsAlignedVertically:(NSArray *)views spacingWithBlock:(CGFloat (^)(UIView *firstView, UIView *secondView))block; 72 | 73 | + (CGFloat)heightForViewsAlignedVertically:(NSArray *)views constrainedToWidth:(CGFloat)constrainedWidth spacing:(CGFloat)spacing; 74 | + (CGFloat)heightForViewsAlignedVertically:(NSArray *)views constrainedToWidth:(CGFloat)constrainedWidth spacingWithBlock:(CGFloat (^)(UIView *firstView, UIView *secondView))block; 75 | 76 | // Resize 77 | - (POViewFrameBuilder *)setWidth:(CGFloat)width; 78 | - (POViewFrameBuilder *)setHeight:(CGFloat)height; 79 | - (POViewFrameBuilder *)setSize:(CGSize)size; 80 | - (POViewFrameBuilder *)setSizeWithWidth:(CGFloat)width height:(CGFloat)height; 81 | - (POViewFrameBuilder *)setSizeToFitWidth; 82 | - (POViewFrameBuilder *)setSizeToFitHeight; 83 | - (POViewFrameBuilder *)setSizeToFit; 84 | 85 | + (void)sizeToFitViews:(NSArray *)views; 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /DemoApp/DemoApp/en.lproj/POViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1536 5 | 12C60 6 | 2844 7 | 1187.34 8 | 625.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 1930 12 | 13 | 14 | IBProxyObject 15 | IBUIButton 16 | IBUIView 17 | 18 | 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | PluginDependencyRecalculationVersion 23 | 24 | 25 | 26 | 27 | IBFilesOwner 28 | IBCocoaTouchFramework 29 | 30 | 31 | IBFirstResponder 32 | IBCocoaTouchFramework 33 | 34 | 35 | 36 | 274 37 | 38 | 39 | 40 | 301 41 | {{140, 254}, {40, 40}} 42 | 43 | 44 | _NS:9 45 | 46 | 2 47 | MC40NTA5ODA0MjQ5IDAuNzU2ODYyODE5MiAwLjA5MDE5NjA4MDUxAA 48 | 49 | IBCocoaTouchFramework 50 | 51 | 52 | 53 | 301 54 | {{92, 104}, {137, 44}} 55 | 56 | 57 | _NS:9 58 | 59 | 1 60 | MC4zMTM3MjU0OTAyIDAuNTcyNTQ5MDE5NiAwLjc0MTE3NjQ3MDYAA 61 | 62 | NO 63 | IBCocoaTouchFramework 64 | 0 65 | 0 66 | Tap to Animate! 67 | 68 | 3 69 | MQA 70 | 71 | 72 | 1 73 | MSAxIDEAA 74 | 75 | 76 | 3 77 | MC41AA 78 | 79 | 80 | 2 81 | 15 82 | 83 | 84 | Helvetica-Bold 85 | 15 86 | 16 87 | 88 | 89 | 90 | {{0, 20}, {320, 548}} 91 | 92 | 93 | 94 | 95 | 1 96 | MC43NTI5NDExNzY1IDAuODQ3MDU4ODIzNSAwLjkxMzcyNTQ5MDIAA 97 | 98 | NO 99 | 100 | 101 | IBUIScreenMetrics 102 | 103 | YES 104 | 105 | 106 | 107 | 108 | 109 | {320, 568} 110 | {568, 320} 111 | 112 | 113 | IBCocoaTouchFramework 114 | Retina 4 Full Screen 115 | 2 116 | 117 | IBCocoaTouchFramework 118 | 119 | 120 | 121 | 122 | 123 | 124 | view 125 | 126 | 127 | 128 | 7 129 | 130 | 131 | 132 | squareView 133 | 134 | 135 | 136 | 17 137 | 138 | 139 | 140 | animateButton 141 | 142 | 143 | 144 | 20 145 | 146 | 147 | 148 | animateButtonPressed 149 | 150 | 151 | 7 152 | 153 | 19 154 | 155 | 156 | 157 | 158 | 159 | 0 160 | 161 | 162 | 163 | 164 | 165 | -1 166 | 167 | 168 | File's Owner 169 | 170 | 171 | -2 172 | 173 | 174 | 175 | 176 | 6 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 8 186 | 187 | 188 | 189 | 190 | 18 191 | 192 | 193 | 194 | 195 | 196 | 197 | POViewController 198 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 199 | UIResponder 200 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 201 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 202 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 203 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 204 | 205 | 206 | 207 | 208 | 209 | 20 210 | 211 | 212 | 213 | 214 | POViewController 215 | UIViewController 216 | 217 | animateButtonPressed 218 | id 219 | 220 | 221 | animateButtonPressed 222 | 223 | animateButtonPressed 224 | id 225 | 226 | 227 | 228 | UIButton 229 | UIView 230 | 231 | 232 | 233 | animateButton 234 | UIButton 235 | 236 | 237 | squareView 238 | UIView 239 | 240 | 241 | 242 | IBProjectSource 243 | ./Classes/POViewController.h 244 | 245 | 246 | 247 | 248 | 0 249 | IBCocoaTouchFramework 250 | YES 251 | 3 252 | 1930 253 | 254 | 255 | -------------------------------------------------------------------------------- /POViewFrameBuilder/POViewFrameBuilder.m: -------------------------------------------------------------------------------- 1 | // 2 | // POViewFrameBuilder.m 3 | // 4 | // Created by Sebastian Rehnby on 10/11/12. 5 | // Copyright (c) 2012 Citrix Systems, Inc. All rights reserved. 6 | // 7 | 8 | #import "POViewFrameBuilder.h" 9 | #import "POGeometry.h" 10 | 11 | // We define NS_ENUM in case we build for iOS 5 12 | #ifndef NS_ENUM 13 | #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type 14 | #endif 15 | 16 | typedef NS_ENUM(NSUInteger, POViewFrameBuilderEdge) { 17 | POViewFrameBuilderEdgeTop, 18 | POViewFrameBuilderEdgeBottom, 19 | POViewFrameBuilderEdgeLeft, 20 | POViewFrameBuilderEdgeRight, 21 | }; 22 | 23 | @interface POViewFrameBuilder () 24 | 25 | @property (nonatomic) CGRect frame; 26 | 27 | @end 28 | 29 | @implementation POViewFrameBuilder 30 | 31 | - (id)initWithView:(UIView *)view { 32 | self = [super init]; 33 | if (self) { 34 | _view = view; 35 | _frame = view.frame; 36 | _automaticallyCommitChanges = YES; 37 | } 38 | return self; 39 | } 40 | 41 | + (POViewFrameBuilder *)frameBuilderForView:(UIView *)view { 42 | return [[[self class] alloc] initWithView:view]; 43 | } 44 | 45 | #pragma mark - Properties 46 | 47 | - (void)setFrame:(CGRect)frame { 48 | _frame = frame; 49 | 50 | if (self.automaticallyCommitChanges) { 51 | [self commit]; 52 | } 53 | } 54 | 55 | #pragma mark - Impl 56 | 57 | - (void)commit { 58 | self.view.frame = self.frame; 59 | } 60 | 61 | - (void)reset { 62 | self.frame = self.view.frame; 63 | } 64 | 65 | - (void)update:(void (^)(POViewFrameBuilder *builder))block { 66 | [self disableAutoCommit]; 67 | block(self); 68 | [self commit]; 69 | } 70 | 71 | - (POViewFrameBuilder *)performChangesInGroupWithBlock:(void (^)(void))block { 72 | BOOL automaticCommitEnabled = self.automaticallyCommitChanges; 73 | 74 | self.automaticallyCommitChanges = NO; 75 | block(); 76 | self.automaticallyCommitChanges = automaticCommitEnabled; 77 | 78 | if (self.automaticallyCommitChanges) { 79 | [self commit]; 80 | } 81 | 82 | return self; 83 | } 84 | 85 | #pragma mark - Configure 86 | 87 | - (POViewFrameBuilder *)enableAutoCommit { 88 | self.automaticallyCommitChanges = YES; 89 | 90 | return self; 91 | } 92 | 93 | - (POViewFrameBuilder *)disableAutoCommit { 94 | self.automaticallyCommitChanges = NO; 95 | 96 | return self; 97 | } 98 | 99 | #pragma mark - Move 100 | 101 | - (POViewFrameBuilder *)setX:(CGFloat)x { 102 | self.frame = PORectWithX(self.frame, x); 103 | 104 | return self; 105 | } 106 | 107 | - (POViewFrameBuilder *)setY:(CGFloat)y { 108 | self.frame = PORectWithY(self.frame, y); 109 | 110 | return self; 111 | } 112 | 113 | - (POViewFrameBuilder *)setOriginWithX:(CGFloat)x y:(CGFloat)y { 114 | return [self performChangesInGroupWithBlock:^{ 115 | [[self setX:x] setY:y]; 116 | }]; 117 | } 118 | 119 | - (POViewFrameBuilder *)moveWithOffsetX:(CGFloat)offsetX { 120 | self.frame = PORectWithX(self.frame, self.frame.origin.x + offsetX); 121 | 122 | return self; 123 | } 124 | 125 | - (POViewFrameBuilder *)moveWithOffsetY:(CGFloat)offsetY { 126 | self.frame = PORectWithY(self.frame, self.frame.origin.y + offsetY); 127 | 128 | return self; 129 | } 130 | 131 | - (POViewFrameBuilder *)moveWithOffsetX:(CGFloat)offsetX offsetY:(CGFloat)offsetY { 132 | return [self performChangesInGroupWithBlock:^{ 133 | [[self moveWithOffsetX:offsetX] moveWithOffsetY:offsetY]; 134 | }]; 135 | } 136 | 137 | - (POViewFrameBuilder *)centerInSuperview { 138 | return [self performChangesInGroupWithBlock:^{ 139 | [[self centerHorizontallyInSuperview] centerVerticallyInSuperview]; 140 | }]; 141 | } 142 | 143 | - (POViewFrameBuilder *)centerHorizontallyInSuperview { 144 | if (!self.view.superview) { 145 | return self; 146 | } 147 | 148 | self.frame = PORectWithX(self.frame, roundf((self.view.superview.bounds.size.width - self.frame.size.width) / 2)); 149 | 150 | return self; 151 | } 152 | 153 | - (POViewFrameBuilder *)centerVerticallyInSuperview { 154 | if (!self.view.superview) { 155 | return self; 156 | } 157 | 158 | self.frame = PORectWithY(self.frame, roundf((self.view.superview.bounds.size.height - self.frame.size.height) / 2)); 159 | 160 | return self; 161 | } 162 | 163 | - (POViewFrameBuilder *)alignToTopInSuperviewWithInset:(CGFloat)inset { 164 | [self alignToTopInSuperviewWithInsets:UIEdgeInsetsMake(inset, 0.0f, 0.0f, 0.0f)]; 165 | 166 | return self; 167 | } 168 | 169 | - (POViewFrameBuilder *)alignToBottomInSuperviewWithInset:(CGFloat)inset { 170 | [self alignToBottomInSuperviewWithInsets:UIEdgeInsetsMake(0.0f, 0.0f, inset, 0.0f)]; 171 | 172 | return self; 173 | } 174 | 175 | - (POViewFrameBuilder *)alignLeftInSuperviewWithInset:(CGFloat)inset { 176 | [self alignLeftInSuperviewWithInsets:UIEdgeInsetsMake(0.0f, inset, 0.0f, 0.0f)]; 177 | 178 | return self; 179 | 180 | } 181 | 182 | - (POViewFrameBuilder *)alignRightInSuperviewWithInset:(CGFloat)inset { 183 | [self alignRightInSuperviewWithInsets:UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, inset)]; 184 | 185 | return self; 186 | } 187 | 188 | - (POViewFrameBuilder *)alignToTopInSuperviewWithInsets:(UIEdgeInsets)insets { 189 | self.frame = PORectWithOrigin(self.frame, 190 | self.frame.origin.x + insets.left - insets.right, 191 | insets.top - insets.bottom); 192 | 193 | return self; 194 | } 195 | 196 | - (POViewFrameBuilder *)alignToBottomInSuperviewWithInsets:(UIEdgeInsets)insets { 197 | self.frame = PORectWithOrigin(self.frame, 198 | self.frame.origin.x + insets.left - insets.right, 199 | self.view.superview.bounds.size.height - self.frame.size.height + insets.top - insets.bottom); 200 | 201 | return self; 202 | } 203 | 204 | - (POViewFrameBuilder *)alignLeftInSuperviewWithInsets:(UIEdgeInsets)insets { 205 | self.frame = PORectWithOrigin(self.frame, 206 | insets.left - insets.right, 207 | self.frame.origin.y + insets.top - insets.bottom); 208 | 209 | return self; 210 | } 211 | 212 | - (POViewFrameBuilder *)alignRightInSuperviewWithInsets:(UIEdgeInsets)insets { 213 | self.frame = PORectWithOrigin(self.frame, 214 | self.view.superview.bounds.size.width - self.frame.size.width + insets.left - insets.right, 215 | self.frame.origin.y + insets.top - insets.bottom); 216 | 217 | return self; 218 | } 219 | 220 | - (POViewFrameBuilder *)alignToView:(UIView *)view edge:(POViewFrameBuilderEdge)edge offset:(CGFloat)offset { 221 | CGRect viewFrame = [view.superview convertRect:view.frame toView:self.view.superview]; 222 | 223 | switch (edge) { 224 | case POViewFrameBuilderEdgeTop: 225 | self.frame = PORectWithY(self.frame, viewFrame.origin.y - offset - self.frame.size.height); 226 | break; 227 | case POViewFrameBuilderEdgeBottom: 228 | self.frame = PORectWithY(self.frame, CGRectGetMaxY(viewFrame) + offset); 229 | break; 230 | case POViewFrameBuilderEdgeLeft: 231 | self.frame = PORectWithX(self.frame, viewFrame.origin.x - offset - self.frame.size.width); 232 | break; 233 | case POViewFrameBuilderEdgeRight: 234 | self.frame = PORectWithX(self.frame, CGRectGetMaxX(viewFrame) + offset); 235 | break; 236 | default: 237 | break; 238 | } 239 | 240 | return self; 241 | } 242 | 243 | - (POViewFrameBuilder *)alignToTopOfView:(UIView *)view offset:(CGFloat)offset { 244 | return [self alignToView:view edge:POViewFrameBuilderEdgeTop offset:offset]; 245 | } 246 | 247 | - (POViewFrameBuilder *)alignToBottomOfView:(UIView *)view offset:(CGFloat)offset { 248 | return [self alignToView:view edge:POViewFrameBuilderEdgeBottom offset:offset]; 249 | } 250 | 251 | - (POViewFrameBuilder *)alignLeftOfView:(UIView *)view offset:(CGFloat)offset { 252 | return [self alignToView:view edge:POViewFrameBuilderEdgeLeft offset:offset]; 253 | } 254 | 255 | - (POViewFrameBuilder *)alignRightOfView:(UIView *)view offset:(CGFloat)offset { 256 | return [self alignToView:view edge:POViewFrameBuilderEdgeRight offset:offset]; 257 | } 258 | 259 | + (void)alignViews:(NSArray *)views direction:(POViewFrameBuilderDirection)direction spacing:(CGFloat)spacing { 260 | return [self alignViews:views direction:direction spacingWithBlock:^CGFloat(UIView *firstView, UIView *secondView) { 261 | return spacing; 262 | }];; 263 | } 264 | 265 | + (void)alignViews:(NSArray *)views direction:(POViewFrameBuilderDirection)direction spacingWithBlock:(CGFloat (^)(UIView *firstView, UIView *secondView))block { 266 | UIView *previousView = nil; 267 | for (UIView *view in views) { 268 | if (previousView) { 269 | CGFloat spacing = block != nil ? block(previousView, view) : 0.0f; 270 | 271 | switch (direction) { 272 | case POViewFrameBuilderDirectionRight: 273 | [[[self alloc] initWithView:view] alignRightOfView:previousView offset:spacing]; 274 | break; 275 | case POViewFrameBuilderDirectionLeft: 276 | [[[self alloc] initWithView:view] alignLeftOfView:previousView offset:spacing]; 277 | break; 278 | case POViewFrameBuilderDirectionUp: 279 | [[[self alloc] initWithView:view] alignToTopOfView:previousView offset:spacing]; 280 | break; 281 | case POViewFrameBuilderDirectionDown: 282 | [[[self alloc] initWithView:view] alignToBottomOfView:previousView offset:spacing]; 283 | break; 284 | default: 285 | break; 286 | } 287 | } 288 | 289 | previousView = view; 290 | } 291 | } 292 | 293 | + (void)alignViewsVertically:(NSArray *)views spacing:(CGFloat)spacing { 294 | [self alignViewsVertically:views spacingWithBlock:^CGFloat(UIView *firstView, UIView *secondView) { 295 | return spacing; 296 | }]; 297 | } 298 | 299 | + (void)alignViewsVertically:(NSArray *)views spacingWithBlock:(CGFloat (^)(UIView *firstView, UIView *secondView))block { 300 | [self alignViews:views direction:POViewFrameBuilderDirectionDown spacingWithBlock:block]; 301 | } 302 | 303 | + (void)alignViewsHorizontally:(NSArray *)views spacing:(CGFloat)spacing { 304 | [self alignViewsHorizontally:views spacingWithBlock:^CGFloat(UIView *firstView, UIView *secondView) { 305 | return spacing; 306 | }]; 307 | } 308 | 309 | + (void)alignViewsHorizontally:(NSArray *)views spacingWithBlock:(CGFloat (^)(UIView *firstView, UIView *secondView))block { 310 | [self alignViews:views direction:POViewFrameBuilderDirectionRight spacingWithBlock:block]; 311 | } 312 | 313 | + (CGFloat)heightForViewsAlignedVertically:(NSArray *)views spacing:(CGFloat)spacing { 314 | return [self heightForViewsAlignedVertically:views constrainedToWidth:0.0f spacing:spacing]; 315 | } 316 | 317 | + (CGFloat)heightForViewsAlignedVertically:(NSArray *)views spacingWithBlock:(CGFloat (^)(UIView *firstView, UIView *secondView))block { 318 | return [self heightForViewsAlignedVertically:views constrainedToWidth:0.0f spacingWithBlock:block]; 319 | } 320 | 321 | + (CGFloat)heightForViewsAlignedVertically:(NSArray *)views constrainedToWidth:(CGFloat)constrainedWidth spacing:(CGFloat)spacing { 322 | return [self heightForViewsAlignedVertically:views constrainedToWidth:constrainedWidth spacingWithBlock:^CGFloat(UIView *firstView, UIView *secondView) { 323 | return spacing; 324 | }]; 325 | } 326 | 327 | + (CGFloat)heightForViewsAlignedVertically:(NSArray *)views constrainedToWidth:(CGFloat)constrainedWidth spacingWithBlock:(CGFloat (^)(UIView *firstView, UIView *secondView))block { 328 | CGFloat height = 0.0f; 329 | 330 | UIView *previousView = nil; 331 | for (UIView *view in views) { 332 | if (constrainedWidth > FLT_EPSILON) { 333 | height += [view sizeThatFits:CGSizeMake(constrainedWidth, CGFLOAT_MAX)].height; 334 | } else { 335 | height += view.bounds.size.height; 336 | } 337 | 338 | if (previousView) { 339 | height += block != nil ? block(previousView, view) : 0.0f; 340 | } 341 | 342 | previousView = view; 343 | } 344 | 345 | return height; 346 | } 347 | 348 | #pragma mark - Resize 349 | 350 | - (POViewFrameBuilder *)setWidth:(CGFloat)width { 351 | self.frame = PORectWithWidth(self.frame, width); 352 | 353 | return self; 354 | } 355 | 356 | - (POViewFrameBuilder *)setHeight:(CGFloat)height { 357 | self.frame = PORectWithHeight(self.frame, height); 358 | 359 | return self; 360 | } 361 | 362 | - (POViewFrameBuilder *)setSize:(CGSize)size { 363 | self.frame = PORectWithSize(self.frame, size.width, size.height); 364 | 365 | return self; 366 | } 367 | 368 | - (POViewFrameBuilder *)setSizeWithWidth:(CGFloat)width height:(CGFloat)height { 369 | return [self performChangesInGroupWithBlock:^{ 370 | [[self setWidth:width] setHeight:height]; 371 | }]; 372 | } 373 | 374 | - (POViewFrameBuilder *)setSizeToFitWidth { 375 | CGRect frame = self.frame; 376 | frame.size.width = [self.view sizeThatFits:CGSizeMake(CGFLOAT_MAX, self.frame.size.height)].width; 377 | self.frame = frame; 378 | 379 | return self; 380 | } 381 | 382 | - (POViewFrameBuilder *)setSizeToFitHeight { 383 | CGRect frame = self.frame; 384 | frame.size.height = [self.view sizeThatFits:CGSizeMake(self.frame.size.width, CGFLOAT_MAX)].height; 385 | self.frame = frame; 386 | 387 | return self; 388 | } 389 | 390 | - (POViewFrameBuilder *)setSizeToFit { 391 | CGSize size = [self.view sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; 392 | 393 | CGRect frame = self.frame; 394 | frame.size.height = size.height; 395 | frame.size.width = size.width; 396 | self.frame = frame; 397 | 398 | return self; 399 | } 400 | 401 | + (void)sizeToFitViews:(NSArray *)views { 402 | for (UIView *view in views) { 403 | [view sizeToFit]; 404 | } 405 | } 406 | 407 | @end 408 | -------------------------------------------------------------------------------- /DemoApp/DemoApp.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 50A095E7164FD7A80096E97A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50A095E6164FD7A80096E97A /* UIKit.framework */; }; 11 | 50A095E9164FD7A80096E97A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50A095E8164FD7A80096E97A /* Foundation.framework */; }; 12 | 50A095EB164FD7A80096E97A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50A095EA164FD7A80096E97A /* CoreGraphics.framework */; }; 13 | 50A095F1164FD7A80096E97A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 50A095EF164FD7A80096E97A /* InfoPlist.strings */; }; 14 | 50A095F3164FD7A80096E97A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 50A095F2164FD7A80096E97A /* main.m */; }; 15 | 50A095F7164FD7A80096E97A /* POAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 50A095F6164FD7A80096E97A /* POAppDelegate.m */; }; 16 | 50A09600164FD7A80096E97A /* POViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50A095FF164FD7A80096E97A /* POViewController.m */; }; 17 | 50A09603164FD7A80096E97A /* POViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 50A09601164FD7A80096E97A /* POViewController.xib */; }; 18 | 50A09633164FE0770096E97A /* POViewFrameBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 50A0962F164FE0770096E97A /* POViewFrameBuilder.m */; }; 19 | 50A09634164FE0770096E97A /* UIView+POViewFrameBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 50A09631164FE0770096E97A /* UIView+POViewFrameBuilder.m */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | 50A095E2164FD7A80096E97A /* DemoApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | 50A095E6164FD7A80096E97A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 25 | 50A095E8164FD7A80096E97A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 26 | 50A095EA164FD7A80096E97A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 27 | 50A095EE164FD7A80096E97A /* DemoApp-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "DemoApp-Info.plist"; sourceTree = ""; }; 28 | 50A095F0164FD7A80096E97A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 29 | 50A095F2164FD7A80096E97A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 30 | 50A095F4164FD7A80096E97A /* DemoApp-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DemoApp-Prefix.pch"; sourceTree = ""; }; 31 | 50A095F5164FD7A80096E97A /* POAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = POAppDelegate.h; sourceTree = ""; }; 32 | 50A095F6164FD7A80096E97A /* POAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = POAppDelegate.m; sourceTree = ""; }; 33 | 50A095FE164FD7A80096E97A /* POViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = POViewController.h; sourceTree = ""; }; 34 | 50A095FF164FD7A80096E97A /* POViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = POViewController.m; sourceTree = ""; }; 35 | 50A09602164FD7A80096E97A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/POViewController.xib; sourceTree = ""; }; 36 | 50A0960A164FD7A80096E97A /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; 37 | 50A0962C164FE0770096E97A /* POGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = POGeometry.h; sourceTree = ""; }; 38 | 50A0962E164FE0770096E97A /* POViewFrameBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = POViewFrameBuilder.h; sourceTree = ""; }; 39 | 50A0962F164FE0770096E97A /* POViewFrameBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = POViewFrameBuilder.m; sourceTree = ""; }; 40 | 50A09630164FE0770096E97A /* UIView+POViewFrameBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+POViewFrameBuilder.h"; sourceTree = ""; }; 41 | 50A09631164FE0770096E97A /* UIView+POViewFrameBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+POViewFrameBuilder.m"; sourceTree = ""; }; 42 | /* End PBXFileReference section */ 43 | 44 | /* Begin PBXFrameworksBuildPhase section */ 45 | 50A095DF164FD7A80096E97A /* Frameworks */ = { 46 | isa = PBXFrameworksBuildPhase; 47 | buildActionMask = 2147483647; 48 | files = ( 49 | 50A095E7164FD7A80096E97A /* UIKit.framework in Frameworks */, 50 | 50A095E9164FD7A80096E97A /* Foundation.framework in Frameworks */, 51 | 50A095EB164FD7A80096E97A /* CoreGraphics.framework in Frameworks */, 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 50A095D7164FD7A80096E97A = { 59 | isa = PBXGroup; 60 | children = ( 61 | 50A095EC164FD7A80096E97A /* DemoApp */, 62 | 50A0962B164FE0760096E97A /* POViewFrameBuilder */, 63 | 50A095E5164FD7A80096E97A /* Frameworks */, 64 | 50A095E3164FD7A80096E97A /* Products */, 65 | ); 66 | sourceTree = ""; 67 | }; 68 | 50A095E3164FD7A80096E97A /* Products */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 50A095E2164FD7A80096E97A /* DemoApp.app */, 72 | ); 73 | name = Products; 74 | sourceTree = ""; 75 | }; 76 | 50A095E5164FD7A80096E97A /* Frameworks */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 50A095E6164FD7A80096E97A /* UIKit.framework */, 80 | 50A095E8164FD7A80096E97A /* Foundation.framework */, 81 | 50A095EA164FD7A80096E97A /* CoreGraphics.framework */, 82 | 50A0960A164FD7A80096E97A /* SenTestingKit.framework */, 83 | ); 84 | name = Frameworks; 85 | sourceTree = ""; 86 | }; 87 | 50A095EC164FD7A80096E97A /* DemoApp */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 50A095F5164FD7A80096E97A /* POAppDelegate.h */, 91 | 50A095F6164FD7A80096E97A /* POAppDelegate.m */, 92 | 50A095FE164FD7A80096E97A /* POViewController.h */, 93 | 50A095FF164FD7A80096E97A /* POViewController.m */, 94 | 50A09601164FD7A80096E97A /* POViewController.xib */, 95 | 50A095ED164FD7A80096E97A /* Supporting Files */, 96 | ); 97 | path = DemoApp; 98 | sourceTree = ""; 99 | }; 100 | 50A095ED164FD7A80096E97A /* Supporting Files */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 50A095EE164FD7A80096E97A /* DemoApp-Info.plist */, 104 | 50A095EF164FD7A80096E97A /* InfoPlist.strings */, 105 | 50A095F2164FD7A80096E97A /* main.m */, 106 | 50A095F4164FD7A80096E97A /* DemoApp-Prefix.pch */, 107 | ); 108 | name = "Supporting Files"; 109 | sourceTree = ""; 110 | }; 111 | 50A0962B164FE0760096E97A /* POViewFrameBuilder */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 50A0962C164FE0770096E97A /* POGeometry.h */, 115 | 50A0962E164FE0770096E97A /* POViewFrameBuilder.h */, 116 | 50A0962F164FE0770096E97A /* POViewFrameBuilder.m */, 117 | 50A09630164FE0770096E97A /* UIView+POViewFrameBuilder.h */, 118 | 50A09631164FE0770096E97A /* UIView+POViewFrameBuilder.m */, 119 | ); 120 | name = POViewFrameBuilder; 121 | path = ../POViewFrameBuilder; 122 | sourceTree = ""; 123 | }; 124 | /* End PBXGroup section */ 125 | 126 | /* Begin PBXNativeTarget section */ 127 | 50A095E1164FD7A80096E97A /* DemoApp */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = 50A0961B164FD7A90096E97A /* Build configuration list for PBXNativeTarget "DemoApp" */; 130 | buildPhases = ( 131 | 50A095DE164FD7A80096E97A /* Sources */, 132 | 50A095DF164FD7A80096E97A /* Frameworks */, 133 | 50A095E0164FD7A80096E97A /* Resources */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | ); 139 | name = DemoApp; 140 | productName = DemoApp; 141 | productReference = 50A095E2164FD7A80096E97A /* DemoApp.app */; 142 | productType = "com.apple.product-type.application"; 143 | }; 144 | /* End PBXNativeTarget section */ 145 | 146 | /* Begin PBXProject section */ 147 | 50A095D9164FD7A80096E97A /* Project object */ = { 148 | isa = PBXProject; 149 | attributes = { 150 | CLASSPREFIX = PO; 151 | LastUpgradeCheck = 0450; 152 | ORGANIZATIONNAME = "Citrix Systems, Inc."; 153 | }; 154 | buildConfigurationList = 50A095DC164FD7A80096E97A /* Build configuration list for PBXProject "DemoApp" */; 155 | compatibilityVersion = "Xcode 3.2"; 156 | developmentRegion = English; 157 | hasScannedForEncodings = 0; 158 | knownRegions = ( 159 | en, 160 | ); 161 | mainGroup = 50A095D7164FD7A80096E97A; 162 | productRefGroup = 50A095E3164FD7A80096E97A /* Products */; 163 | projectDirPath = ""; 164 | projectRoot = ""; 165 | targets = ( 166 | 50A095E1164FD7A80096E97A /* DemoApp */, 167 | ); 168 | }; 169 | /* End PBXProject section */ 170 | 171 | /* Begin PBXResourcesBuildPhase section */ 172 | 50A095E0164FD7A80096E97A /* Resources */ = { 173 | isa = PBXResourcesBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | 50A095F1164FD7A80096E97A /* InfoPlist.strings in Resources */, 177 | 50A09603164FD7A80096E97A /* POViewController.xib in Resources */, 178 | ); 179 | runOnlyForDeploymentPostprocessing = 0; 180 | }; 181 | /* End PBXResourcesBuildPhase section */ 182 | 183 | /* Begin PBXSourcesBuildPhase section */ 184 | 50A095DE164FD7A80096E97A /* Sources */ = { 185 | isa = PBXSourcesBuildPhase; 186 | buildActionMask = 2147483647; 187 | files = ( 188 | 50A095F3164FD7A80096E97A /* main.m in Sources */, 189 | 50A095F7164FD7A80096E97A /* POAppDelegate.m in Sources */, 190 | 50A09600164FD7A80096E97A /* POViewController.m in Sources */, 191 | 50A09633164FE0770096E97A /* POViewFrameBuilder.m in Sources */, 192 | 50A09634164FE0770096E97A /* UIView+POViewFrameBuilder.m in Sources */, 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | /* End PBXSourcesBuildPhase section */ 197 | 198 | /* Begin PBXVariantGroup section */ 199 | 50A095EF164FD7A80096E97A /* InfoPlist.strings */ = { 200 | isa = PBXVariantGroup; 201 | children = ( 202 | 50A095F0164FD7A80096E97A /* en */, 203 | ); 204 | name = InfoPlist.strings; 205 | sourceTree = ""; 206 | }; 207 | 50A09601164FD7A80096E97A /* POViewController.xib */ = { 208 | isa = PBXVariantGroup; 209 | children = ( 210 | 50A09602164FD7A80096E97A /* en */, 211 | ); 212 | name = POViewController.xib; 213 | sourceTree = ""; 214 | }; 215 | /* End PBXVariantGroup section */ 216 | 217 | /* Begin XCBuildConfiguration section */ 218 | 50A09619164FD7A90096E97A /* Debug */ = { 219 | isa = XCBuildConfiguration; 220 | buildSettings = { 221 | ALWAYS_SEARCH_USER_PATHS = NO; 222 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 223 | CLANG_CXX_LIBRARY = "libc++"; 224 | CLANG_ENABLE_OBJC_ARC = YES; 225 | CLANG_WARN_EMPTY_BODY = YES; 226 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 227 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 228 | COPY_PHASE_STRIP = NO; 229 | GCC_C_LANGUAGE_STANDARD = gnu99; 230 | GCC_DYNAMIC_NO_PIC = NO; 231 | GCC_OPTIMIZATION_LEVEL = 0; 232 | GCC_PREPROCESSOR_DEFINITIONS = ( 233 | "DEBUG=1", 234 | "$(inherited)", 235 | ); 236 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 237 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 238 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 239 | GCC_WARN_UNUSED_VARIABLE = YES; 240 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 241 | ONLY_ACTIVE_ARCH = YES; 242 | SDKROOT = iphoneos; 243 | }; 244 | name = Debug; 245 | }; 246 | 50A0961A164FD7A90096E97A /* Release */ = { 247 | isa = XCBuildConfiguration; 248 | buildSettings = { 249 | ALWAYS_SEARCH_USER_PATHS = NO; 250 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 251 | CLANG_CXX_LIBRARY = "libc++"; 252 | CLANG_ENABLE_OBJC_ARC = YES; 253 | CLANG_WARN_EMPTY_BODY = YES; 254 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 255 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 256 | COPY_PHASE_STRIP = YES; 257 | GCC_C_LANGUAGE_STANDARD = gnu99; 258 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 259 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 260 | GCC_WARN_UNUSED_VARIABLE = YES; 261 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 262 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 263 | SDKROOT = iphoneos; 264 | VALIDATE_PRODUCT = YES; 265 | }; 266 | name = Release; 267 | }; 268 | 50A0961C164FD7A90096E97A /* Debug */ = { 269 | isa = XCBuildConfiguration; 270 | buildSettings = { 271 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 272 | GCC_PREFIX_HEADER = "DemoApp/DemoApp-Prefix.pch"; 273 | INFOPLIST_FILE = "DemoApp/DemoApp-Info.plist"; 274 | PRODUCT_NAME = "$(TARGET_NAME)"; 275 | WRAPPER_EXTENSION = app; 276 | }; 277 | name = Debug; 278 | }; 279 | 50A0961D164FD7A90096E97A /* Release */ = { 280 | isa = XCBuildConfiguration; 281 | buildSettings = { 282 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 283 | GCC_PREFIX_HEADER = "DemoApp/DemoApp-Prefix.pch"; 284 | INFOPLIST_FILE = "DemoApp/DemoApp-Info.plist"; 285 | PRODUCT_NAME = "$(TARGET_NAME)"; 286 | WRAPPER_EXTENSION = app; 287 | }; 288 | name = Release; 289 | }; 290 | /* End XCBuildConfiguration section */ 291 | 292 | /* Begin XCConfigurationList section */ 293 | 50A095DC164FD7A80096E97A /* Build configuration list for PBXProject "DemoApp" */ = { 294 | isa = XCConfigurationList; 295 | buildConfigurations = ( 296 | 50A09619164FD7A90096E97A /* Debug */, 297 | 50A0961A164FD7A90096E97A /* Release */, 298 | ); 299 | defaultConfigurationIsVisible = 0; 300 | defaultConfigurationName = Release; 301 | }; 302 | 50A0961B164FD7A90096E97A /* Build configuration list for PBXNativeTarget "DemoApp" */ = { 303 | isa = XCConfigurationList; 304 | buildConfigurations = ( 305 | 50A0961C164FD7A90096E97A /* Debug */, 306 | 50A0961D164FD7A90096E97A /* Release */, 307 | ); 308 | defaultConfigurationIsVisible = 0; 309 | defaultConfigurationName = Release; 310 | }; 311 | /* End XCConfigurationList section */ 312 | }; 313 | rootObject = 50A095D9164FD7A80096E97A /* Project object */; 314 | } 315 | --------------------------------------------------------------------------------