diff --git a/SMCalloutView.h b/SMCalloutView.h index 0ff0b31..b6dafa4 100755 --- a/SMCalloutView.h +++ b/SMCalloutView.h @@ -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; @@ -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. diff --git a/SMCalloutView.m b/SMCalloutView.m index 3c38c61..ac31978 100755 --- a/SMCalloutView.m +++ b/SMCalloutView.m @@ -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 @@ -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]; @@ -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 @@ -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; @@ -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; } } @@ -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];