Created
August 10, 2014 15:27
-
-
Save maojj/836fcd21e547894568fd to your computer and use it in GitHub Desktop.
UIView Utils Borrowed from Three20 / DTFoundation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UIView+Utils.h | |
// Borrowed from Three20 / DTFoundation | |
// | |
// Copyright (c) 2013 iOS. No rights reserved. | |
// | |
#import <UIKit/UIKit.h> | |
@interface UIView (Utils) | |
/** | |
* Shortcut for frame.origin.x. | |
* | |
* Sets frame.origin.x = left | |
*/ | |
@property (nonatomic) CGFloat left; | |
/** | |
* Shortcut for frame.origin.y | |
* | |
* Sets frame.origin.y = top | |
*/ | |
@property (nonatomic) CGFloat top; | |
/** | |
* Shortcut for frame.origin.x + frame.size.width | |
* | |
* Sets frame.origin.x = right - frame.size.width | |
*/ | |
@property (nonatomic) CGFloat right; | |
/** | |
* Shortcut for frame.origin.y + frame.size.height | |
* | |
* Sets frame.origin.y = bottom - frame.size.height | |
*/ | |
@property (nonatomic) CGFloat bottom; | |
/** | |
* Shortcut for frame.size.width | |
* | |
* Sets frame.size.width = width | |
*/ | |
@property (nonatomic) CGFloat width; | |
/** | |
* Shortcut for frame.size.height | |
* | |
* Sets frame.size.height = height | |
*/ | |
@property (nonatomic) CGFloat height; | |
/** | |
* Shortcut for center.x | |
* | |
* Sets center.x = centerX | |
*/ | |
@property (nonatomic) CGFloat centerX; | |
/** | |
* Shortcut for center.y | |
* | |
* Sets center.y = centerY | |
*/ | |
@property (nonatomic) CGFloat centerY; | |
/** | |
* Return the x coordinate on the screen. | |
*/ | |
@property (nonatomic, readonly) CGFloat screenX; | |
/** | |
* Return the y coordinate on the screen. | |
*/ | |
@property (nonatomic, readonly) CGFloat screenY; | |
/** | |
* Return the x coordinate on the screen, taking into account scroll views. | |
*/ | |
@property (nonatomic, readonly) CGFloat screenViewX; | |
/** | |
* Return the y coordinate on the screen, taking into account scroll views. | |
*/ | |
@property (nonatomic, readonly) CGFloat screenViewY; | |
/** | |
* Return the view frame on the screen, taking into account scroll views. | |
*/ | |
@property (nonatomic, readonly) CGRect screenFrame; | |
/** | |
* Shortcut for frame.origin | |
*/ | |
@property (nonatomic) CGPoint origin; | |
/** | |
* Shortcut for frame.size | |
*/ | |
@property (nonatomic) CGSize size; | |
/** | |
* Return the width in portrait or the height in landscape. | |
*/ | |
@property (nonatomic, readonly) CGFloat orientationWidth; | |
/** | |
* Return the height in portrait or the width in landscape. | |
*/ | |
@property (nonatomic, readonly) CGFloat orientationHeight; | |
/** | |
* Finds the first descendant view (including this view) that is a member of a particular class. | |
*/ | |
- (UIView*)descendantOrSelfWithClass:(Class)cls; | |
/** | |
* Finds the first ancestor view (including this view) that is a member of a particular class. | |
*/ | |
- (UIView*)ancestorOrSelfWithClass:(Class)cls; | |
/** | |
* Removes all subviews. | |
*/ | |
- (void)removeAllSubviews; | |
/** | |
Attaches the given block for a single tap action to the receiver. | |
@param block The block to execute. | |
*/ | |
- (void)setTapActionWithBlock:(void (^)(void))block; | |
/** | |
Attaches the given block for a long press action to the receiver. | |
@param block The block to execute. | |
*/ | |
- (void)setLongPressActionWithBlock:(void (^)(void))block; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UIView+Utils.m | |
// Borrowed from Three20 | |
// | |
// Copyright (c) 2013 iOS. No rights reserved. | |
// | |
#import "UIView+Utils.h" | |
#import <objc/runtime.h> | |
static char kDTActionHandlerTapBlockKey; | |
static char kDTActionHandlerTapGestureKey; | |
static char kDTActionHandlerLongPressBlockKey; | |
static char kDTActionHandlerLongPressGestureKey; | |
@implementation UIView (Utils) | |
- (CGFloat)left { | |
return self.frame.origin.x; | |
} | |
- (void)setLeft:(CGFloat)x { | |
CGRect frame = self.frame; | |
frame.origin.x = x; | |
self.frame = frame; | |
} | |
- (CGFloat)top { | |
return self.frame.origin.y; | |
} | |
- (void)setTop:(CGFloat)y { | |
CGRect frame = self.frame; | |
frame.origin.y = y; | |
self.frame = frame; | |
} | |
- (CGFloat)right { | |
return self.frame.origin.x + self.frame.size.width; | |
} | |
- (void)setRight:(CGFloat)right { | |
CGRect frame = self.frame; | |
frame.origin.x = right - frame.size.width; | |
self.frame = frame; | |
} | |
- (CGFloat)bottom { | |
return self.frame.origin.y + self.frame.size.height; | |
} | |
- (void)setBottom:(CGFloat)bottom { | |
CGRect frame = self.frame; | |
frame.origin.y = bottom - frame.size.height; | |
self.frame = frame; | |
} | |
- (CGFloat)centerX { | |
return self.center.x; | |
} | |
- (void)setCenterX:(CGFloat)centerX { | |
self.center = CGPointMake(centerX, self.center.y); | |
} | |
- (CGFloat)centerY { | |
return self.center.y; | |
} | |
- (void)setCenterY:(CGFloat)centerY { | |
self.center = CGPointMake(self.center.x, centerY); | |
} | |
- (CGFloat)width { | |
return self.frame.size.width; | |
} | |
- (void)setWidth:(CGFloat)width { | |
CGRect frame = self.frame; | |
frame.size.width = width; | |
self.frame = frame; | |
} | |
- (CGFloat)height { | |
return self.frame.size.height; | |
} | |
- (void)setHeight:(CGFloat)height { | |
CGRect frame = self.frame; | |
frame.size.height = height; | |
self.frame = frame; | |
} | |
- (CGFloat)screenX { | |
CGFloat x = 0.0f; | |
for (UIView* view = self; view; view = view.superview) { | |
x += view.left; | |
} | |
return x; | |
} | |
- (CGFloat)screenY { | |
CGFloat y = 0.0f; | |
for (UIView* view = self; view; view = view.superview) { | |
y += view.top; | |
} | |
return y; | |
} | |
- (CGFloat)screenViewX { | |
CGFloat x = 0.0f; | |
for (UIView* view = self; view; view = view.superview) { | |
x += view.left; | |
if ([view isKindOfClass:[UIScrollView class]]) { | |
UIScrollView* scrollView = (UIScrollView*)view; | |
x -= scrollView.contentOffset.x; | |
} | |
} | |
return x; | |
} | |
- (CGFloat)screenViewY { | |
CGFloat y = 0; | |
for (UIView* view = self; view; view = view.superview) { | |
y += view.top; | |
if ([view isKindOfClass:[UIScrollView class]]) { | |
UIScrollView* scrollView = (UIScrollView*)view; | |
y -= scrollView.contentOffset.y; | |
} | |
} | |
return y; | |
} | |
- (CGRect)screenFrame { | |
return CGRectMake(self.screenViewX, self.screenViewY, self.width, self.height); | |
} | |
- (CGPoint)origin { | |
return self.frame.origin; | |
} | |
- (void)setOrigin:(CGPoint)origin { | |
CGRect frame = self.frame; | |
frame.origin = origin; | |
self.frame = frame; | |
} | |
- (CGSize)size { | |
return self.frame.size; | |
} | |
- (void)setSize:(CGSize)size { | |
CGRect frame = self.frame; | |
frame.size = size; | |
self.frame = frame; | |
} | |
- (CGFloat)orientationWidth { | |
return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) | |
? self.height : self.width; | |
} | |
- (CGFloat)orientationHeight { | |
return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) | |
? self.width : self.height; | |
} | |
- (UIView*)descendantOrSelfWithClass:(Class)cls { | |
if ([self isKindOfClass:cls]) | |
return self; | |
for (UIView* child in self.subviews) { | |
UIView* it = [child descendantOrSelfWithClass:cls]; | |
if (it) | |
return it; | |
} | |
return nil; | |
} | |
- (UIView*)ancestorOrSelfWithClass:(Class)cls { | |
if ([self isKindOfClass:cls]) { | |
return self; | |
} else if (self.superview) { | |
return [self.superview ancestorOrSelfWithClass:cls]; | |
} else { | |
return nil; | |
} | |
} | |
- (void)removeAllSubviews { | |
while (self.subviews.count) { | |
UIView* child = self.subviews.lastObject; | |
[child removeFromSuperview]; | |
} | |
} | |
- (CGPoint)offsetFromView:(UIView*)otherView { | |
CGFloat x = 0.0f, y = 0.0f; | |
for (UIView* view = self; view && view != otherView; view = view.superview) { | |
x += view.left; | |
y += view.top; | |
} | |
return CGPointMake(x, y); | |
} | |
- (void)setTapActionWithBlock:(void (^)(void))block | |
{ | |
UITapGestureRecognizer *gesture = objc_getAssociatedObject(self, &kDTActionHandlerTapGestureKey); | |
if (!gesture) | |
{ | |
gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(__handleActionForTapGesture:)]; | |
[self addGestureRecognizer:gesture]; | |
objc_setAssociatedObject(self, &kDTActionHandlerTapGestureKey, gesture, OBJC_ASSOCIATION_RETAIN); | |
} | |
objc_setAssociatedObject(self, &kDTActionHandlerTapBlockKey, block, OBJC_ASSOCIATION_COPY); | |
} | |
- (void)__handleActionForTapGesture:(UITapGestureRecognizer *)gesture | |
{ | |
if (gesture.state == UIGestureRecognizerStateRecognized) | |
{ | |
void(^action)(void) = objc_getAssociatedObject(self, &kDTActionHandlerTapBlockKey); | |
if (action) | |
{ | |
action(); | |
} | |
} | |
} | |
- (void)setLongPressActionWithBlock:(void (^)(void))block | |
{ | |
UILongPressGestureRecognizer *gesture = objc_getAssociatedObject(self, &kDTActionHandlerLongPressGestureKey); | |
if (!gesture) | |
{ | |
gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(__handleActionForLongPressGesture:)]; | |
[self addGestureRecognizer:gesture]; | |
objc_setAssociatedObject(self, &kDTActionHandlerLongPressGestureKey, gesture, OBJC_ASSOCIATION_RETAIN); | |
} | |
objc_setAssociatedObject(self, &kDTActionHandlerLongPressBlockKey, block, OBJC_ASSOCIATION_COPY); | |
} | |
- (void)__handleActionForLongPressGesture:(UITapGestureRecognizer *)gesture | |
{ | |
if (gesture.state == UIGestureRecognizerStateBegan) | |
{ | |
void(^action)(void) = objc_getAssociatedObject(self, &kDTActionHandlerLongPressBlockKey); | |
if (action) | |
{ | |
action(); | |
} | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment