Skip to content
Browse files

initial commit

  • Loading branch information...
0 parents commit 82ea4dbfad8f98d4f0cb319790d6332ae78fb80a Patrick Perini committed
Showing with 320 additions and 0 deletions.
  1. +18 −0 .gitignore
  2. +18 −0 PCPopoverController.h
  3. +223 −0 PCPopoverController.m
  4. +61 −0 README.md
18 .gitignore
@@ -0,0 +1,18 @@
+# osx noise
+.DS_Store
+profile
+
+# xcode noise
+build/*
+*.mode1
+*.mode1v3
+*.mode2v3
+*.perspective
+*.perspectivev3
+*.pbxuser
+*.xcworkspace
+xcuserdata
+
+# svn & cvs
+.svn
+CVS
18 PCPopoverController.h
@@ -0,0 +1,18 @@
+//
+// PCPopoverController.h
+// PCPopoverControllerTests
+//
+// Created by Patrick Perini on 5/16/12.
+// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import <QuartzCore/QuartzCore.h>
+
+@interface PCPopoverController : UIPopoverController
+
+@property (readonly) UIColor *tintColor;
+
+- (id)initWithContentViewController:(UIViewController *)viewController andTintColor: (UIColor *)tintColor;
+
+@end
223 PCPopoverController.m
@@ -0,0 +1,223 @@
+//
+// PCPopoverController.m
+// PCPopoverControllerTests
+//
+// Created by Patrick Perini on 5/16/12.
+// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
+//
+
+#import "PCPopoverController.h"
+
+#pragma mark - Internal Constants
+CGFloat const contentInset = 10.0;
+CGFloat const capInset = 25.0;
+CGFloat const arrowHeight = 15.0;
+CGFloat const arrowBase = 24.0;
+
+@interface PCPopoverControllerBackgroundView : UIPopoverBackgroundView
+{
+ UIImageView *borderImageView;
+ UIImageView *arrowImageView;
+}
+
++ (UIColor *)currentTintColor;
++ (void)setCurrentTintColor: (UIColor *)tintColor;
+
+@end
+
+@implementation PCPopoverControllerBackgroundView
+
+#pragma mark - Internal Class Variables
+static UIColor *currentTintColor;
+
+#pragma mark - Initializers
+- (id)initWithFrame:(CGRect)frame
+{
+ self = [super initWithFrame: frame];
+ if (!self)
+ return nil;
+
+ UIGraphicsBeginImageContext(CGSizeMake(60, 60));
+
+ UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(0, 0, 60, 60)
+ cornerRadius: 8];
+ [currentTintColor setFill];
+ [borderPath fill];
+
+ UIImage *borderImage = UIGraphicsGetImageFromCurrentImageContext();
+
+ UIGraphicsEndImageContext();
+
+ UIEdgeInsets capInsets = UIEdgeInsetsMake(capInset, capInset, capInset, capInset);
+ borderImageView = [[UIImageView alloc] initWithImage: [borderImage resizableImageWithCapInsets: capInsets]];
+
+ borderImageView.layer.shadowColor = [UIColor blackColor].CGColor;
+ borderImageView.layer.shadowOpacity = .4;
+ borderImageView.layer.shadowRadius = 2;
+ borderImageView.layer.shadowOffset = CGSizeMake(0, 2);
+
+ UIGraphicsBeginImageContext(CGSizeMake(25, 25));
+
+ UIBezierPath *arrowPath = [UIBezierPath bezierPath];
+ [arrowPath moveToPoint: CGPointMake(12.5, 0)];
+ [arrowPath addLineToPoint: CGPointMake(25, 25)];
+ [arrowPath addLineToPoint: CGPointMake(0, 25)];
+ [arrowPath addLineToPoint: CGPointMake(12.5, 0)];
+
+ [currentTintColor setFill];
+ [arrowPath fill];
+
+ UIImage *arrowImage = UIGraphicsGetImageFromCurrentImageContext();
+
+ UIGraphicsEndImageContext();
+
+ arrowImageView = [[UIImageView alloc] initWithImage: arrowImage];
+
+ arrowImageView.layer.shadowColor = [UIColor blackColor].CGColor;
+ arrowImageView.layer.shadowOpacity = .4;
+ arrowImageView.layer.shadowRadius = 2;
+ arrowImageView.layer.shadowOffset = CGSizeMake(0, 1);
+ arrowImageView.layer.masksToBounds = YES;
+
+ [self addSubview: borderImageView];
+ [self addSubview: arrowImageView];
+
+ return self;
+}
+
+#pragma mark - Class Accessors and Mutators
++ (UIColor *)currentTintColor
+{
+ return currentTintColor;
+}
+
++ (void)setCurrentTintColor:(UIColor *)tintColor
+{
+ currentTintColor = tintColor;
+}
+
+#pragma mark - Class Handlers
++ (UIEdgeInsets)contentViewInsets
+{
+ return UIEdgeInsetsMake(contentInset, contentInset, contentInset, contentInset);
+}
+
++ (CGFloat)arrowHeight
+{
+ return arrowHeight;
+}
+
++ (CGFloat)arrowBase
+{
+ return arrowBase;
+}
+
+#pragma mark - View Handlers
+@synthesize arrowOffset;
+@synthesize arrowDirection;
+
+- (void)layoutSubviews
+{
+ [super layoutSubviews];
+
+ CGFloat height = CGRectGetHeight(self.frame);
+ CGFloat width = CGRectGetWidth(self.frame);
+ CGFloat left = 0;
+ CGFloat top = 0;
+ CGFloat coordinate = 0;
+ CGAffineTransform rotation = CGAffineTransformIdentity;
+
+ switch (arrowDirection)
+ {
+ case UIPopoverArrowDirectionUp:
+ {
+ top += arrowHeight;
+ height -= arrowHeight;
+ coordinate = ((CGRectGetWidth(self.frame) / 2.0) + arrowOffset) - (arrowBase / 2.0);
+ arrowImageView.frame = CGRectMake(coordinate, 0, arrowBase, arrowHeight);
+ break;
+ }
+
+ case UIPopoverArrowDirectionDown:
+ {
+ height -= arrowHeight;
+ coordinate = ((CGRectGetWidth(self.frame) / 2.0) + arrowOffset) - (arrowBase / 2.0);
+ arrowImageView.frame = CGRectMake(coordinate, height, arrowBase, arrowHeight);
+ rotation = CGAffineTransformMakeRotation(M_PI);
+ break;
+ }
+
+ case UIPopoverArrowDirectionLeft:
+ {
+ left += arrowBase - ceil((arrowBase - arrowHeight) / 2.0);
+ width -= arrowBase;
+ coordinate = ((CGRectGetHeight(self.frame) / 2.0) + arrowOffset) - (arrowHeight / 2.0);
+ arrowImageView.frame = CGRectMake(0, coordinate, arrowBase, arrowHeight);
+ rotation = CGAffineTransformMakeRotation(-M_PI_2);
+ break;
+ }
+
+ case UIPopoverArrowDirectionRight:
+ {
+ left += ceil((arrowBase - arrowHeight) / 2.0);
+ width -= arrowBase;
+ coordinate = ((CGRectGetHeight(self.frame) / 2.0) + arrowOffset) - (arrowHeight / 2.0);
+ arrowImageView.frame = CGRectMake(width, coordinate, arrowBase, arrowHeight);
+ rotation = CGAffineTransformMakeRotation(M_PI_2);
+ break;
+ }
+ }
+
+ borderImageView.frame = CGRectMake(left, top, width, height);
+ [arrowImageView setTransform: rotation];
+}
+
+@end
+
+@implementation PCPopoverController
+
+#pragma mark - Properties
+@synthesize tintColor;
+
+#pragma mark - Initializers
+- (id)initWithContentViewController:(UIViewController *)viewController
+{
+ self = [self initWithContentViewController: viewController
+ andTintColor: [UIColor blackColor]];
+ return self;
+}
+
+- (id)initWithContentViewController:(UIViewController *)viewController andTintColor:(UIColor *)aTintColor
+{
+ self = [super initWithContentViewController: viewController];
+ if (!self)
+ return nil;
+
+ [super setPopoverBackgroundViewClass: [PCPopoverControllerBackgroundView class]];
+ tintColor = aTintColor;
+
+ return self;
+}
+
+#pragma mark - Overriders
+- (void)setPopoverBackgroundViewClass:(Class)popoverBackgroundViewClass {}
+
+- (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated
+{
+ @synchronized(self)
+ {
+ [[PCPopoverControllerBackgroundView class] setCurrentTintColor: tintColor];
+ [super presentPopoverFromRect: rect inView: view permittedArrowDirections: arrowDirections animated: animated];
+ }
+}
+
+- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated
+{
+ @synchronized(self)
+ {
+ [[PCPopoverControllerBackgroundView class] setCurrentTintColor: tintColor];
+ [super presentPopoverFromBarButtonItem: item permittedArrowDirections: arrowDirections animated: animated];
+ }
+}
+
+@end
61 README.md
@@ -0,0 +1,61 @@
+#PCPopoverController#
+
+
+Inherits From: UIPopoverController
+
+Declared In: PCPopoverController.h
+
+
+##Overview##
+
+The `PCPopoverController` class is a drop-in replacement for `UIPopoverController` with the ability to add a tint color.
+
+The tint color, as of yet, is in lieu of the various gradient effects seen in the default `UIPopoverController` class. Support for this gradient effects in conjunction with tint colors will be supported later.
+
+##Tasks##
+
+###Initializing the Switch Object###
+ - initWithContentViewController:andTintColor:
+
+###Reading the Tint Color###
+ tintColor (property)
+
+
+##Properties##
+
+**tintColor**
+
+>The color used to tint the popover.
+
+ (readonly) UIColor *tintColor
+
+
+##Instance Methods##
+
+**initWithContentViewController:andTintColor:**
+
+>Returns an initalized popover controller object.
+
+ - (id)initWithContentViewController:(UIViewController *)viewController andTintColor:(UIColor *)tintColor
+
+>*Parameters:*
+
+>`viewController`
+
+>>The view controller for managing the popover's content. This parameter must not be `nil`.
+
+>`tintColor`
+
+>>The color used to tint the popover.
+
+#License#
+
+License Agreement for Source Code provided by Patrick Perini
+
+This software is supplied to you by Patrick Perini in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this software.
+
+In consideration of your agreement to abide by the following terms, and subject to these terms, Patrick Perini grants you a personal, non-exclusive license, to use, reproduce, modify and redistribute the software, with or without modifications, in source and/or binary forms; provided that if you redistribute the software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the software, and that in all cases attribution of Patrick Perini as the original author of the source code shall be included in all such resulting software products or distributions. Neither the name, trademarks, service marks or logos of Patrick Perini may be used to endorse or promote products derived from the software without specific prior written permission from Patrick Perini. Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Patrick Perini herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the software may be incorporated.
+
+The software is provided by Patrick Perini on an "AS IS" basis. Patrick Perini MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE SOFTWARE OR PCS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL Patrick Perini BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF Patrick Perini HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

0 comments on commit 82ea4db

Please sign in to comment.
Something went wrong with that request. Please try again.