QMUIPopupContainerView
@interface QMUIPopupContainerView : UIControl {
CAShapeLayer *_backgroundLayer;
CGFloat _arrowMinX;
CGFloat _arrowMinY;
}
带箭头的小tips浮层,自带 imageView 和 textLabel,可展示简单的图文信息,支持 UIViewContentModeTop/UIViewContentModeBottom/UIViewContentModeCenter 三种布局方式。 QMUIPopupContainerView 支持以两种方式显示在界面上:
- 添加到某个 UIView 上(适合于 viewController 切换时浮层跟着一起切换的场景),这种场景只能手动隐藏浮层。
- 在 QMUIPopupContainerView 自带的 UIWindow 里显示(适合于用完就消失的场景,不要涉及界面切换),这种场景支持点击空白地方自动隐藏浮层。
使用步骤:
- 调用 init 方法初始化。
- 选择一种显示方式: 2.1 如果要添加到某个 UIView 上,则先设置浮层 hidden = YES,然后调用 addSubview: 把浮层添加到目标 UIView 上。 2.2 如果是轻量的场景用完即走,则 init 完浮层即可,无需设置 hidden,也无需调用 addSubview:,在后面第 4 步里会自动把浮层添加到 UIWindow 上显示出来。
- 通过为 sourceBarItem/sourceView/sourceRect 三者中的一个赋值,来决定浮层布局的位置。
- 调用 showWithAnimated: 或 showWithAnimated:completion: 显示浮层。
- 调用 hideWithAnimated: 或 hideWithAnimated:completion: 隐藏浮层。
Warning
如果使用方法 2.2,并且没有打开 automaticallyHidesWhenUserTap 属性,则记得在适当的时机(例如 viewWillDisappear:)隐藏浮层。如果默认功能无法满足需求,可继承它重写一个子类,继承要点:
- 初始化时要做的事情请放在 didInitialize 里。
- 所有 subviews 请加到 contentView 上。
- 通过重写 sizeThatFitsInContentView:,在里面返回当前 subviews 的大小。
- 在 layoutSubviews: 里,所有 subviews 请相对于 contentView 布局。
-
Undocumented
Declaration
Objective-C
CAShapeLayer *_backgroundLayer
-
Undocumented
Declaration
Objective-C
CGFloat _arrowMinX
-
Undocumented
Declaration
Objective-C
CGFloat _arrowMinY
-
Undocumented
Declaration
Objective-C
@property(nonatomic, assign) BOOL debug
Swift
var debug: Bool { get set }
-
在浮层显示时,点击空白地方是否要自动隐藏浮层,仅在用方法 2 显示时有效。 默认为 NO,也即需要手动调用代码去隐藏浮层。
Declaration
Objective-C
@property (nonatomic) BOOL automaticallyHidesWhenUserTap;
Swift
var automaticallyHidesWhenUserTap: Bool { get set }
-
所有subview都应该添加到contentView上,默认contentView.userInteractionEnabled = NO,需要事件操作时自行打开
Declaration
Objective-C
@property (nonatomic, strong, readonly) UIView *contentView;
Swift
var contentView: UIView! { get }
-
预提供的UIImageView,默认为nil,调用到的时候才初始化
Declaration
Objective-C
@property (nonatomic, strong, readonly) UIImageView *imageView;
Swift
var imageView: UIImageView! { get }
-
预提供的UILabel,默认为nil,调用到的时候才初始化。默认支持多行。
Declaration
Objective-C
@property (nonatomic, strong, readonly) UILabel *textLabel;
Swift
var textLabel: UILabel! { get }
-
圆角矩形气泡内的padding(不包括三角箭头),默认是(8, 8, 8, 8)
Declaration
Objective-C
@property (nonatomic) UIEdgeInsets contentEdgeInsets;
Swift
var contentEdgeInsets: UIEdgeInsets { get set }
-
调整imageView的位置,默认为UIEdgeInsetsZero。top/left正值表示往下/右方偏移,bottom/right仅在对应位置存在下一个子View时生效(例如只有同时存在imageView和textLabel时,imageEdgeInsets.right才会生效)。
Declaration
Objective-C
@property (nonatomic) UIEdgeInsets imageEdgeInsets;
Swift
var imageEdgeInsets: UIEdgeInsets { get set }
-
调整textLabel的位置,默认为UIEdgeInsetsZero。top/left/bottom/right的作用同imageEdgeInsets
Declaration
Objective-C
@property (nonatomic) UIEdgeInsets textEdgeInsets;
Swift
var textEdgeInsets: UIEdgeInsets { get set }
-
三角箭头的大小,默认为 CGSizeMake(18, 9)
Declaration
Objective-C
@property (nonatomic) CGSize arrowSize;
Swift
var arrowSize: CGSize { get set }
-
最大宽度(指整个控件的宽度,而不是contentView部分),默认为CGFLOAT_MAX
Declaration
Objective-C
@property (nonatomic) CGFloat maximumWidth;
Swift
var maximumWidth: CGFloat { get set }
-
最小宽度(指整个控件的宽度,而不是contentView部分),默认为0
Declaration
Objective-C
@property (nonatomic) CGFloat minimumWidth;
Swift
var minimumWidth: CGFloat { get set }
-
最大高度(指整个控件的高度,而不是contentView部分),默认为CGFLOAT_MAX
Declaration
Objective-C
@property (nonatomic) CGFloat maximumHeight;
Swift
var maximumHeight: CGFloat { get set }
-
最小高度(指整个控件的高度,而不是contentView部分),默认为0
Declaration
Objective-C
@property (nonatomic) CGFloat minimumHeight;
Swift
var minimumHeight: CGFloat { get set }
-
计算布局时期望的默认位置,默认为QMUIPopupContainerViewLayoutDirectionAbove,也即在目标的上方
Declaration
Objective-C
@property (nonatomic) QMUIPopupContainerViewLayoutDirection preferLayoutDirection;
Swift
var preferLayoutDirection: QMUIPopupContainerViewLayoutDirection { get set }
-
最终的布局方向(preferLayoutDirection只是期望的方向,但有可能那个方向已经没有剩余空间可摆放控件了,所以会自动变换)
Declaration
Objective-C
@property (nonatomic, readonly) QMUIPopupContainerViewLayoutDirection currentLayoutDirection;
Swift
var currentLayoutDirection: QMUIPopupContainerViewLayoutDirection { get }
-
最终布局时箭头距离目标边缘的距离,默认为5
Declaration
Objective-C
@property (nonatomic) CGFloat distanceBetweenSource;
Swift
var distanceBetweenSource: CGFloat { get set }
-
最终布局时与父节点的边缘的临界点,默认为(10, 10, 10, 10)
Declaration
Objective-C
@property (nonatomic) UIEdgeInsets safetyMarginsOfSuperview;
Swift
var safetyMarginsOfSuperview: UIEdgeInsets { get set }
-
Undocumented
Declaration
Objective-C
@property(nonatomic, strong) UIColor *backgroundColor
Swift
var backgroundColor: UIColor! { get set }
-
Undocumented
Declaration
Objective-C
@property(nonatomic, strong) UIColor *highlightedBackgroundColor
Swift
var highlightedBackgroundColor: UIColor! { get set }
-
当使用方法 2 显示并且打开了 automaticallyHidesWhenUserTap 时,可修改背景遮罩的颜色,默认为 UIColorMask,若非使用方法 2,或者没有打开 automaticallyHidesWhenUserTap,则背景遮罩为透明(可视为不存在背景遮罩)
Declaration
Objective-C
@property (nonatomic, strong) UIColor *maskViewBackgroundColor;
Swift
var maskViewBackgroundColor: UIColor! { get set }
-
Undocumented
Declaration
Objective-C
@property(nonatomic, strong) UIColor *shadowColor
Swift
var shadowColor: UIColor! { get set }
-
Undocumented
Declaration
Objective-C
@property(nonatomic, strong) UIColor *borderColor
Swift
var borderColor: UIColor! { get set }
-
Undocumented
Declaration
Objective-C
@property(nonatomic, assign) CGFloat borderWidth
Swift
var borderWidth: CGFloat { get set }
-
Undocumented
Declaration
Objective-C
@property(nonatomic, assign) CGFloat cornerRadius
Swift
var cornerRadius: CGFloat { get set }
-
可以是 UINavigationBar、UIToolbar 上的 UIBarButtonItem,或者 UITabBar 上的 UITabBarItem
Declaration
Objective-C
@property (nonatomic, weak) __kindof UIBarItem *sourceBarItem;
Swift
weak var sourceBarItem: UIBarItem! { get set }
-
Undocumented
Declaration
Objective-C
@property(nonatomic, weak) __kindof UIView *sourceView
Swift
weak var sourceView: UIView! { get set }
-
rect 需要处于 QMUIPopupContainerView 所在的坐标系内,例如如果 popup 使用 addSubview: 的方式添加到界面,则 sourceRect 应该是 superview 坐标系内的;如果 popup 使用 window 的方式展示,则 sourceRect 需要转换为 window 坐标系内。
Declaration
Objective-C
@property (nonatomic) CGRect sourceRect;
Swift
var sourceRect: CGRect { get set }
-
立即刷新当前 popup 的布局,前提是 popup 已经被 show 过。
Declaration
Objective-C
- (void)updateLayout;
Swift
func updateLayout()
-
Undocumented
Declaration
Objective-C
- (void)showWithAnimated:(BOOL)animated;
Swift
func showWith(animated: Bool)
-
Undocumented
Declaration
Objective-C
- (void)showWithAnimated:(BOOL)animated completion:(void (^)(BOOL finished))completion;
Swift
func showWith(animated: Bool, completion: ((Bool) -> Void)!)
-
Undocumented
Declaration
Objective-C
- (void)hideWithAnimated:(BOOL)animated;
Swift
func hideWith(animated: Bool)
-
Undocumented
Declaration
Objective-C
- (void)hideWithAnimated:(BOOL)animated completion:(void (^)(BOOL finished))completion;
Swift
func hideWith(animated: Bool, completion: ((Bool) -> Void)!)
-
Undocumented
Declaration
Objective-C
- (BOOL)isShowing;
Swift
func isShowing() -> Bool
-
即将显示时的回调 注:如果需要使用例如 didShowBlock 的时机,请使用 @showWithAnimated:completion: 的 completion 参数来实现。 @argv animated 是否需要动画
Declaration
Objective-C
@property (nonatomic, copy) void (^)(BOOL) willShowBlock;
Swift
var willShowBlock: ((Bool) -> Void)! { get set }
-
即将隐藏时的回调 @argv hidesByUserTap 用于区分此次隐藏是否因为用户手动点击空白区域导致浮层被隐藏 @argv animated 是否需要动画
Declaration
Objective-C
@property (nonatomic, copy) void (^)(BOOL, BOOL) willHideBlock;
Swift
var willHideBlock: ((Bool, Bool) -> Void)! { get set }
-
已经隐藏后的回调 @argv hidesByUserTap 用于区分此次隐藏是否因为用户手动点击空白区域导致浮层被隐藏
Declaration
Objective-C
@property (nonatomic, copy) void (^)(BOOL) didHideBlock;
Swift
var didHideBlock: ((Bool) -> Void)! { get set }
-
子类重写,在初始化时做一些操作
Declaration
Objective-C
- (void)didInitialize;
Swift
func didInitialize()
-
子类重写,告诉父类subviews的合适大小
Declaration
Objective-C
- (CGSize)sizeThatFitsInContentView:(CGSize)size;
Swift
func sizeThatFits(inContentView size: CGSize) -> CGSize
Parameters
size
浮层里除去 safetyMarginsOfSuperview、arrowSize、contentEdgeInsets 之外后,留给内容的实际大小,计算 subview 大小时均应使用这个参数来计算
Return Value
自定义内容实际占据的大小