Skip to content

Commit

Permalink
Merge branch 'pr/76'
Browse files Browse the repository at this point in the history
Adds support for `contentViewInset`, `anchorHeight`, and `anchorMargin`
properties.
  • Loading branch information
nfarina committed Mar 24, 2015
2 parents da691ec + 9c14b9f commit 14a8d87
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 11 deletions.
5 changes: 5 additions & 0 deletions SMCalloutView.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ extern NSTimeInterval const kSMCalloutViewRepositionDelayForUIScrollView;
// Custom "content" view that can be any width/height. If this is set, title/subtitle/titleView/subtitleView are all ignored.
@property (nonatomic, retain) UIView *contentView;

// Custom content view margin
@property (nonatomic, assign) UIEdgeInsets contentViewInset;

// calloutOffset is the offset in screen points from the top-middle of the target view, where the anchor of the callout should be shown.
@property (nonatomic, assign) CGPoint calloutOffset;

Expand Down Expand Up @@ -88,6 +91,8 @@ extern NSTimeInterval const kSMCalloutViewRepositionDelayForUIScrollView;
@property (nonatomic, assign) CGPoint arrowPoint; // indicates where the tip of the arrow should be drawn, as a pixel offset
@property (nonatomic, assign) BOOL highlighted; // will be set by the callout when the callout is in a highlighted state
@property (nonatomic, assign) CALayer *contentMask; // returns an optional layer whose contents should mask the callout view's contents (not honored by SMClassicCalloutView)
@property (nonatomic, assign) CGFloat anchorHeight; // height of the callout "arrow"
@property (nonatomic, assign) CGFloat anchorMargin; // the smallest possible distance from the edge of our control to the "tip" of the anchor, from either left or right
@end

// Default for iOS 7, this reproduces the "masked" behavior of the iOS 7-style callout view.
Expand Down
23 changes: 12 additions & 11 deletions SMCalloutView.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ @interface UIView (SMFrameAdditions)
#define SUBTITLE_TOP 28 // the top of the subtitle, when present
#define SUBTITLE_HEIGHT 15 // subtitle height, fixed
#define BETWEEN_ACCESSORIES_MARGIN 7 // margin between accessories when no title/subtitle is present
#define CONTENT_VIEW_MARGIN 12 // margin around content view when present
#define ANCHOR_MARGIN 27 // the smallest possible distance from the edge of our control to the "tip" of the anchor, from either left or right
#define ANCHOR_HEIGHT 13 // effective height of the anchor
#define TOP_ANCHOR_MARGIN 13 // all the above measurements assume a bottom anchor! if we're pointing "up" we'll need to add this top margin to everything.
#define COMFORTABLE_MARGIN 10 // when we try to reposition content to be visible, we'll consider this margin around your target rect

Expand Down Expand Up @@ -62,6 +59,7 @@ - (id)initWithFrame:(CGRect)frame {
self.dismissAnimation = SMCalloutAnimationFade;
self.backgroundColor = [UIColor clearColor];
self.containerView = [UIButton new];
self.contentViewInset = UIEdgeInsetsMake(12, 12, 12, 12);

[self.containerView addTarget:self action:@selector(highlightIfNecessary) forControlEvents:UIControlEventTouchDown | UIControlEventTouchDragInside];
[self.containerView addTarget:self action:@selector(unhighlightIfNecessary) forControlEvents:UIControlEventTouchDragOutside | UIControlEventTouchCancel | UIControlEventTouchUpOutside | UIControlEventTouchUpInside];
Expand Down Expand Up @@ -180,23 +178,23 @@ - (CGFloat)innerContentMarginLeft {
if (self.leftAccessoryView)
return self.leftAccessoryHorizontalMargin + self.leftAccessoryView.frameWidth + TITLE_HMARGIN;
else
return TITLE_HMARGIN;
return self.contentViewInset.left;
}

- (CGFloat)innerContentMarginRight {
if (self.rightAccessoryView)
return self.rightAccessoryHorizontalMargin + self.rightAccessoryView.frameWidth + TITLE_HMARGIN;
else
return TITLE_HMARGIN;
return self.contentViewInset.right;
}

- (CGFloat)calloutHeight {
return self.calloutContainerHeight + ANCHOR_HEIGHT;
return self.calloutContainerHeight + self.backgroundView.anchorHeight;
}

- (CGFloat)calloutContainerHeight {
if (self.contentView)
return self.contentView.frameHeight + CONTENT_VIEW_MARGIN * 2;
return self.contentView.frameHeight + self.contentViewInset.bottom + self.contentViewInset.top;
else if (self.subtitleView || self.subtitle.length > 0)
return CALLOUT_SUB_DEFAULT_CONTAINER_HEIGHT;
else
Expand Down Expand Up @@ -324,8 +322,8 @@ - (void)presentCalloutFromRect:(CGRect)rect inLayer:(CALayer *)layer ofView:(UIV
calloutX = constrainedRect.origin.x+constrainedRect.size.width-self.frameWidth;

// what's the farthest to the left and right that we could point to, given our background image constraints?
CGFloat minPointX = calloutX + ANCHOR_MARGIN;
CGFloat maxPointX = calloutX + self.frameWidth - ANCHOR_MARGIN;
CGFloat minPointX = calloutX + self.backgroundView.anchorMargin;
CGFloat maxPointX = calloutX + self.frameWidth - self.backgroundView.anchorMargin;

// we may need to scoot over to the left or right to point at the correct spot
CGFloat adjustX = 0;
Expand Down Expand Up @@ -530,12 +528,12 @@ - (void)layoutSubviews {
self.leftAccessoryView.frameX = self.leftAccessoryHorizontalMargin;
self.leftAccessoryView.frameY = self.leftAccessoryVerticalMargin + dy;

self.rightAccessoryView.frameX = self.frameWidth-self.rightAccessoryHorizontalMargin-self.rightAccessoryView.frameWidth;
self.rightAccessoryView.frameX = self.frameWidth - self.rightAccessoryHorizontalMargin - self.rightAccessoryView.frameWidth;
self.rightAccessoryView.frameY = self.rightAccessoryVerticalMargin + dy;

if (self.contentView) {
self.contentView.frameX = self.innerContentMarginLeft;
self.contentView.frameY = CONTENT_VIEW_MARGIN + dy;
self.contentView.frameY = self.contentViewInset.top + dy;
}
}

Expand Down Expand Up @@ -583,6 +581,9 @@ - (id)initWithFrame:(CGRect)frame {
grayArrowImage = [self image:blackArrowImage withColor:[UIColor colorWithWhite:0.85 alpha:1]];
}

self.anchorHeight = 13;
self.anchorMargin = 27;

self.arrowView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, blackArrowImage.size.width, blackArrowImage.size.height)];
self.arrowView.alpha = 0.96;
self.arrowImageView = [[UIImageView alloc] initWithImage:whiteArrowImage];
Expand Down

0 comments on commit 14a8d87

Please sign in to comment.