diff --git a/SMCalloutView.h b/SMCalloutView.h index b6dafa4..26dffb7 100755 --- a/SMCalloutView.h +++ b/SMCalloutView.h @@ -6,26 +6,31 @@ SMCalloutView ------------- Created by Nick Farina (nfarina@gmail.com) -Version 2.0.3 +Version 2.1.2 */ -// options for which directions the callout is allowed to "point" in. +/// options for which directions the callout is allowed to "point" in. typedef NS_OPTIONS(NSUInteger, SMCalloutArrowDirection) { SMCalloutArrowDirectionUp = 1 << 0, SMCalloutArrowDirectionDown = 1 << 1, SMCalloutArrowDirectionAny = SMCalloutArrowDirectionUp | SMCalloutArrowDirectionDown }; -// options for the callout present/dismiss animation +/// options for the callout present/dismiss animation typedef NS_ENUM(NSInteger, SMCalloutAnimation) { - SMCalloutAnimationBounce, // the "bounce" animation we all know and love from UIAlertView - SMCalloutAnimationFade, // a simple fade in or out - SMCalloutAnimationStretch // grow or shrink linearly, like in the iPad Calendar app + /// the "bounce" animation we all know and love from @c UIAlertView + SMCalloutAnimationBounce, + /// a simple fade in or out + SMCalloutAnimationFade, + /// grow or shrink linearly, like in the iPad Calendar app + SMCalloutAnimationStretch }; -// when delaying our popup in order to scroll content into view, you can use this amount to match the -// animation duration of UIScrollView when using -setContentOffset:animated. +NS_ASSUME_NONNULL_BEGIN + +/// when delaying our popup in order to scroll content into view, you can use this amount to match the +/// animation duration of UIScrollView when using @c -setContentOffset:animated. extern NSTimeInterval const kSMCalloutViewRepositionDelayForUIScrollView; @protocol SMCalloutViewDelegate; @@ -37,47 +42,93 @@ extern NSTimeInterval const kSMCalloutViewRepositionDelayForUIScrollView; @interface SMCalloutView : UIView -@property (nonatomic, unsafe_unretained) id delegate; -@property (nonatomic, copy) NSString *title, *subtitle; // title/titleView relationship mimics UINavigationBar. -@property (nonatomic, retain) UIView *leftAccessoryView, *rightAccessoryView; -@property (nonatomic, assign) SMCalloutArrowDirection permittedArrowDirection; // default SMCalloutArrowDirectionDown +@property (nonatomic, weak, nullable) id delegate; +/// title/titleView relationship mimics UINavigationBar. +@property (nonatomic, copy, nullable) NSString *title; +@property (nonatomic, copy, nullable) NSString *subtitle; + +/// Left accessory view for the call out +@property (nonatomic, strong, nullable) UIView *leftAccessoryView; +/// Right accessoty view for the call out +@property (nonatomic, strong, nullable) UIView *rightAccessoryView; +/// Default @c SMCalloutArrowDirectionDown +@property (nonatomic, assign) SMCalloutArrowDirection permittedArrowDirection; +/// The current arrow direction @property (nonatomic, readonly) SMCalloutArrowDirection currentArrowDirection; -@property (nonatomic, assign) UIEdgeInsets constrainedInsets; // if the UIView you're constraining to has portions that are overlapped by nav bar, tab bar, etc. you'll need to tell us those insets. -@property (nonatomic, retain) SMCalloutBackgroundView *backgroundView; // default is SMCalloutMaskedBackgroundView, or SMCalloutDrawnBackgroundView when using SMClassicCalloutView - -// Custom title/subtitle views. if these are set, the respective title/subtitle properties will be ignored. -// Keep in mind that SMCalloutView calls -sizeThatFits on titleView/subtitleView if defined, so your view -// may be resized as a result of that (especially if you're using UILabel/UITextField). You may want to subclass -// and override -sizeThatFits, or just wrap your view in a "generic" UIView if you do not want it to be auto-sized. -@property (nonatomic, retain) UIView *titleView, *subtitleView; - -// Custom "content" view that can be any width/height. If this is set, title/subtitle/titleView/subtitleView are all ignored. +/// if the @c UIView you're constraining to has portions that are overlapped by nav bar, tab bar, etc. you'll need to tell us those insets. +@property (nonatomic, assign) UIEdgeInsets constrainedInsets; +/// default is @c SMCalloutMaskedBackgroundView, or @c SMCalloutDrawnBackgroundView when using @c SMClassicCalloutView +@property (nonatomic, strong) SMCalloutBackgroundView *backgroundView; + +/** + @brief Custom title view. + + @disucssion Keep in mind that @c SMCalloutView calls @c -sizeThatFits on titleView/subtitleView if defined, so your view + may be resized as a result of that (especially if you're using @c UILabel/UITextField). You may want to subclass and override @c -sizeThatFits, or just wrap your view in a "generic" @c UIView if you do not want it to be auto-sized. + + @warning If this is set, the respective @c title property will be ignored. + */ +@property (nonatomic, strong, nullable) UIView *titleView; + +/** + @brief Custom subtitle view. + + @discussion Keep in mind that @c SMCalloutView calls @c -sizeThatFits on subtitleView if defined, so your view + may be resized as a result of that (especially if you're using @c UILabel/UITextField). You may want to subclass and override @c -sizeThatFits, or just wrap your view in a "generic" @c UIView if you do not want it to be auto-sized. + + @warning If this is set, the respective @c subtitle property will be ignored. + */ +@property (nonatomic, strong, nullable) UIView *subtitleView; + +/// 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 +/// 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. +/// 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; -@property (nonatomic, assign) SMCalloutAnimation presentAnimation, dismissAnimation; // default SMCalloutAnimationBounce, SMCalloutAnimationFade respectively - +/// default SMCalloutAnimationBounce, SMCalloutAnimationFade respectively +@property (nonatomic, assign) SMCalloutAnimation presentAnimation, dismissAnimation; -// Returns a new instance of SMCalloutView if running on iOS 7 or better, otherwise a new instance of SMClassicCalloutView if available. +/// Returns a new instance of SMCalloutView if running on iOS 7 or better, otherwise a new instance of SMClassicCalloutView if available. + (SMCalloutView *)platformCalloutView; -// Presents a callout view by adding it to "inView" and pointing at the given rect of inView's bounds. -// Constrains the callout to the bounds of the given view. Optionally scrolls the given rect into view (plus margins) -// if -delegate is set and responds to -delayForRepositionWithSize. +/** + @brief Presents a callout view by adding it to "inView" and pointing at the given rect of inView's bounds. + + @discussion Constrains the callout to the bounds of the given view. Optionally scrolls the given rect into view (plus margins) + if @c -delegate is set and responds to @c -delayForRepositionWithSize. + + @param rect @c CGRect to present the view from + @param view view to 'constrain' the @c constrainedView to + @param constrainedView @c UIView to be constrainted in @c view + @param animated @c BOOL if presentation should be animated + */ - (void)presentCalloutFromRect:(CGRect)rect inView:(UIView *)view constrainedToView:(UIView *)constrainedView animated:(BOOL)animated; -// Same as the view-based presentation, but inserts the callout into a CALayer hierarchy instead. Be aware that you'll have to direct -// your own touches to any accessory views, since CALayer doesn't relay touch events. +/** + @brief Present a callout layer in the `layer` and pointing at the given rect of the `layer` bounds + + @discussion Same as the view-based presentation, but inserts the callout into a CALayer hierarchy instead. + @note Be aware that you'll have to direct your own touches to any accessory views, since CALayer doesn't relay touch events. + + @param rect @c CGRect to present the view from + @param layer layer to 'constrain' the @c constrainedLayer to + @param constrainedLayer @c CALayer to be constrained in @c layer + @param animated @c BOOL if presentation should be animated + */ - (void)presentCalloutFromRect:(CGRect)rect inLayer:(CALayer *)layer constrainedToLayer:(CALayer *)constrainedLayer animated:(BOOL)animated; +/** + Dismiss the callout view + + @param animated @c BOOL if dismissal should be animated + */ - (void)dismissCalloutAnimated:(BOOL)animated; -// For subclassers. You can override this method to provide your own custom animation for presenting/dismissing the callout. +/// For subclassers. You can override this method to provide your own custom animation for presenting/dismissing the callout. - (CAAnimation *)animationWithType:(SMCalloutAnimation)type presenting:(BOOL)presenting; @end @@ -86,17 +137,22 @@ extern NSTimeInterval const kSMCalloutViewRepositionDelayForUIScrollView; // Background view - default draws the iOS 7 system background style (translucent white with rounded arrow). // -// Abstract base class +/// Abstract base class @interface SMCalloutBackgroundView : UIView -@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 +/// indicates where the tip of the arrow should be drawn, as a pixel offset +@property (nonatomic, assign) CGPoint arrowPoint; +/// will be set by the callout when the callout is in a highlighted state +@property (nonatomic, assign) BOOL highlighted; +/// returns an optional layer whose contents should mask the callout view's contents (not honored by @c SMClassicCalloutView ) +@property (nonatomic, assign) CALayer *contentMask; +/// height of the callout "arrow" +@property (nonatomic, assign) CGFloat anchorHeight; +/// the smallest possible distance from the edge of our control to the "tip" of the anchor, from either left or right +@property (nonatomic, assign) CGFloat anchorMargin; @end -// Default for iOS 7, this reproduces the "masked" behavior of the iOS 7-style callout view. -// Accessories are masked by the shape of the callout (including the arrow itself). +/// Default for iOS 7, this reproduces the "masked" behavior of the iOS 7-style callout view. +/// Accessories are masked by the shape of the callout (including the arrow itself). @interface SMCalloutMaskedBackgroundView : SMCalloutBackgroundView @end @@ -107,32 +163,38 @@ extern NSTimeInterval const kSMCalloutViewRepositionDelayForUIScrollView; @protocol SMCalloutViewDelegate @optional -// Controls whether the callout "highlights" when pressed. default YES. You must also respond to `-calloutViewClicked` below. -// Not honored by SMClassicCalloutView. +/// Controls whether the callout "highlights" when pressed. default YES. You must also respond to @c -calloutViewClicked below. +/// Not honored by @c SMClassicCalloutView. - (BOOL)calloutViewShouldHighlight:(SMCalloutView *)calloutView; -// Called when the callout view is clicked. Not honored by SMClassicCalloutView. +/// Called when the callout view is clicked. Not honored by @c SMClassicCalloutView. - (void)calloutViewClicked:(SMCalloutView *)calloutView; -// Called when the callout view detects that it will be outside the constrained view when it appears, -// or if the target rect was already outside the constrained view. You can implement this selector to -// respond to this situation by repositioning your content first in order to make everything visible. The -// CGSize passed is the calculated offset necessary to make everything visible (plus a nice margin). -// It expects you to return the amount of time you need to reposition things so the popup can be delayed. -// Typically you would return kSMCalloutViewRepositionDelayForUIScrollView if you're repositioning by -// calling [UIScrollView setContentOffset:animated:]. +/** + Called when the callout view detects that it will be outside the constrained view when it appears, + or if the target rect was already outside the constrained view. You can implement this selector + to respond to this situation by repositioning your content first in order to make everything visible. + The @c CGSize passed is the calculated offset necessary to make everything visible (plus a nice margin). + It expects you to return the amount of time you need to reposition things so the popup can be delayed. + Typically you would return @c kSMCalloutViewRepositionDelayForUIScrollView if you're repositioning by calling @c [UIScrollView @c setContentOffset:animated:]. + + @param calloutView the @c SMCalloutView to reposition + @param offset caluclated offset necessary to make everything visible + @returns @c NSTimeInterval to delay the repositioning + */ - (NSTimeInterval)calloutView:(SMCalloutView *)calloutView delayForRepositionWithSize:(CGSize)offset; -// Called before the callout view appears on screen, or before the appearance animation will start. -- (void)calloutViewWillAppear:(SMCalloutView*)calloutView; +/// Called before the callout view appears on screen, or before the appearance animation will start. +- (void)calloutViewWillAppear:(SMCalloutView *)calloutView; -// Called after the callout view appears on screen, or after the appearance animation is complete. +/// Called after the callout view appears on screen, or after the appearance animation is complete. - (void)calloutViewDidAppear:(SMCalloutView *)calloutView; -// Called before the callout view is removed from the screen, or before the disappearance animation is complete. -- (void)calloutViewWillDisappear:(SMCalloutView*)calloutView; +/// Called before the callout view is removed from the screen, or before the disappearance animation is complete. +- (void)calloutViewWillDisappear:(SMCalloutView *)calloutView; -// Called after the callout view is removed from the screen, or after the disappearance animation is complete. +/// Called after the callout view is removed from the screen, or after the disappearance animation is complete. - (void)calloutViewDidDisappear:(SMCalloutView *)calloutView; +NS_ASSUME_NONNULL_END @end