Skip to content

Commit 73f3915

Browse files
committed
1. 为 QMUITableViewCell 增加 accessoryEdgeInsets 用于控制 accessoryView 的间距。
2. 修复 QMUINavigationTitleView 里用 appearance 设置 tintColor 导致 UIBarButtonItem 的 tintColor 失效。 3. 优化 UINavigationBar 的返回动画效果,支持 UITableViewController。 4. 调整配置表 QMUIConfigurationTemplate 里 tableView 部分的赋值顺序。 5. 在 QMUITextField 里修复系统的 UITextField 中文输入超过文本框宽度后删除文字,文字往下掉的 bug。 6. 优化 UINavigationBar 的返回动画效果,支持 UITableViewController。 7. QMUIPopupContainerView 支持点击空白地方消失。 8. 增加弹出菜单控件 QMUIPopupMenuView。
1 parent a2d12b7 commit 73f3915

20 files changed

Lines changed: 827 additions & 254 deletions

QMUIKit/QMUIKit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ FOUNDATION_EXPORT const unsigned char QMUIKitVersionString[];
9191
#import <QMUIKit/QMUIQQEmotionManager.h>
9292
#import <QMUIKit/QMUIPieProgressView.h>
9393
#import <QMUIKit/QMUIPopupContainerView.h>
94+
#import <QMUIKit/QMUIPopupMenuView.h>
9495
#import <QMUIKit/QMUIModalPresentationViewController.h>
9596
#import <QMUIKit/QMUIAlertController.h>
9697
#import <QMUIKit/QMUIAlbumViewController.h>
@@ -180,6 +181,7 @@ FOUNDATION_EXPORT const unsigned char QMUIKitVersionString[];
180181
#import "QMUIQQEmotionManager.h"
181182
#import "QMUIPieProgressView.h"
182183
#import "QMUIPopupContainerView.h"
184+
#import "QMUIPopupMenuView.h"
183185
#import "QMUIModalPresentationViewController.h"
184186
#import "QMUIAlertController.h"
185187
#import "QMUIAlbumViewController.h"

QMUIKit/UICommon/QMUIConfigurationManager.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,18 @@
154154
@property(nonatomic, strong) UIColor *tableSectionIndexBackgroundColor;
155155
@property(nonatomic, strong) UIColor *tableSectionIndexTrackingBackgroundColor;
156156
@property(nonatomic, strong) UIColor *tableViewSeparatorColor;
157+
158+
@property(nonatomic, assign) CGFloat tableViewCellNormalHeight;
159+
@property(nonatomic, strong) UIColor *tableViewCellTitleLabelColor;
160+
@property(nonatomic, strong) UIColor *tableViewCellDetailLabelColor;
161+
@property(nonatomic, assign) CGFloat tableViewCellContentDefaultPaddingLeft;
162+
@property(nonatomic, assign) CGFloat tableViewCellContentDefaultPaddingRight;
157163
@property(nonatomic, strong) UIColor *tableViewCellBackgroundColor;
158164
@property(nonatomic, strong) UIColor *tableViewCellSelectedBackgroundColor;
159165
@property(nonatomic, strong) UIColor *tableViewCellWarningBackgroundColor;
160-
@property(nonatomic, assign) CGFloat tableViewCellNormalHeight;
161-
162166
@property(nonatomic, strong) UIImage *tableViewCellDisclosureIndicatorImage;
163167
@property(nonatomic, strong) UIImage *tableViewCellCheckmarkImage;
168+
164169
@property(nonatomic, strong) UIColor *tableViewSectionHeaderBackgroundColor;
165170
@property(nonatomic, strong) UIColor *tableViewSectionFooterBackgroundColor;
166171
@property(nonatomic, strong) UIFont *tableViewSectionHeaderFont;
@@ -181,11 +186,6 @@
181186
@property(nonatomic, assign) UIEdgeInsets tableViewGroupedSectionHeaderContentInset;
182187
@property(nonatomic, assign) UIEdgeInsets tableViewGroupedSectionFooterContentInset;
183188

184-
@property(nonatomic, strong) UIColor *tableViewCellTitleLabelColor;
185-
@property(nonatomic, strong) UIColor *tableViewCellDetailLabelColor;
186-
@property(nonatomic, assign) CGFloat tableViewCellContentDefaultPaddingLeft;
187-
@property(nonatomic, assign) CGFloat tableViewCellContentDefaultPaddingRight;
188-
189189
#pragma mark - Others
190190

191191
@property(nonatomic, assign) UIInterfaceOrientationMask supportedOrientationMask;

QMUIKit/UICommon/QMUIConfigurationTemplate.m

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,18 @@ + (void)setupConfigurationTemplate {
164164
//- QMUICMI.tableSectionIndexBackgroundColor = UIColorClear; // TableSectionIndexBackgroundColor
165165
//- QMUICMI.tableSectionIndexTrackingBackgroundColor = UIColorClear; // TableSectionIndexTrackingBackgroundColor
166166
//- QMUICMI.tableViewSeparatorColor = UIColorSeparator; // TableViewSeparatorColor
167+
168+
//- QMUICMI.tableViewCellNormalHeight = 44; // TableViewCellNormalHeight
169+
//- QMUICMI.tableViewCellTitleLabelColor = UIColorBlack; // TableViewCellTitleLabelColor
170+
//- QMUICMI.tableViewCellDetailLabelColor = UIColorGray; // TableViewCellDetailLabelColor
171+
//- QMUICMI.tableViewCellContentDefaultPaddingLeft = 15; // TableViewCellContentDefaultPaddingLeft
172+
//- QMUICMI.tableViewCellContentDefaultPaddingRight = 10; // TableViewCellContentDefaultPaddingRight
167173
//- QMUICMI.tableViewCellBackgroundColor = UIColorWhite; // TableViewCellBackgroundColor
168174
//- QMUICMI.tableViewCellSelectedBackgroundColor = UIColorMake(232, 232, 232); // TableViewCellSelectedBackgroundColor
169175
//- QMUICMI.tableViewCellWarningBackgroundColor = UIColorYellow; // TableViewCellWarningBackgroundColor
170-
//- QMUICMI.tableViewCellNormalHeight = 44; // TableViewCellNormalHeight
171-
172176
//- QMUICMI.tableViewCellDisclosureIndicatorImage = [UIImage qmui_imageWithShape:QMUIImageShapeDisclosureIndicator size:CGSizeMake(8, 13) tintColor:UIColorMakeWithRGBA(0, 0, 0, .2)]; // TableViewCellDisclosureIndicatorImage
173177
//- QMUICMI.tableViewCellCheckmarkImage = [UIImage qmui_imageWithShape:QMUIImageShapeCheckmark size:CGSizeMake(15, 12) tintColor:UIColorBlue]; // TableViewCellCheckmarkImage
178+
174179
//- QMUICMI.tableViewSectionHeaderBackgroundColor = UIColorMake(244, 244, 244); // TableViewSectionHeaderBackgroundColor
175180
//- QMUICMI.tableViewSectionFooterBackgroundColor = UIColorMake(244, 244, 244); // TableViewSectionFooterBackgroundColor
176181
//- QMUICMI.tableViewSectionHeaderFont = UIFontBoldMake(12); // TableViewSectionHeaderFont
@@ -180,7 +185,7 @@ + (void)setupConfigurationTemplate {
180185
//- QMUICMI.tableViewSectionHeaderHeight = 20; // TableViewSectionHeaderHeight
181186
//- QMUICMI.tableViewSectionFooterHeight = 0; // TableViewSectionFooterHeight
182187
//- QMUICMI.tableViewSectionHeaderContentInset = UIEdgeInsetsMake(4, 15, 4, 15); // TableViewSectionHeaderContentInset
183-
//- QMUICMI.tableViewSectionFooterContentInset = UIEdgeInsetsMake(4, 15, 4, 15); // TableViewSectionHeaderContentInset
188+
//- QMUICMI.tableViewSectionFooterContentInset = UIEdgeInsetsMake(4, 15, 4, 15); // TableViewSectionFooterContentInset
184189

185190
//- QMUICMI.tableViewGroupedSectionHeaderFont = UIFontMake(12); // TableViewGroupedSectionHeaderFont
186191
//- QMUICMI.tableViewGroupedSectionFooterFont = UIFontMake(12); // TableViewGroupedSectionFooterFont
@@ -191,11 +196,6 @@ + (void)setupConfigurationTemplate {
191196
//- QMUICMI.tableViewGroupedSectionHeaderContentInset = UIEdgeInsetsMake(16, 15, 8, 15); // TableViewGroupedSectionHeaderContentInset
192197
//- QMUICMI.tableViewGroupedSectionFooterContentInset = UIEdgeInsetsMake(8, 15, 2, 15); // TableViewGroupedSectionFooterContentInset
193198

194-
//- QMUICMI.tableViewCellTitleLabelColor = UIColorBlack; // TableViewCellTitleLabelColor
195-
//- QMUICMI.tableViewCellDetailLabelColor = UIColorGray; // TableViewCellDetailLabelColor
196-
//- QMUICMI.tableViewCellContentDefaultPaddingLeft = 15; // TableViewCellContentDefaultPaddingLeft
197-
//- QMUICMI.tableViewCellContentDefaultPaddingRight = 10; // TableViewCellContentDefaultPaddingRight
198-
199199
#pragma mark - UIWindowLevel
200200
//- QMUICMI.windowLevelQMUIAlertView = UIWindowLevelAlert - 4.0; // UIWindowLevelQMUIAlertView
201201
//- QMUICMI.windowLevelQMUIActionSheet = UIWindowLevelAlert - 4.0; // UIWindowLevelQMUIActionSheet

QMUIKit/UIComponents/QMUIModalPresentationViewController.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ - (void)didInitialized {
9292
}
9393

9494
- (void)dealloc {
95-
_containerWindow = nil;
95+
self.containerWindow = nil;
9696
}
9797

9898
- (BOOL)shouldAutomaticallyForwardAppearanceMethods {

QMUIKit/UIComponents/QMUINavigationTitleView.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ - (instancetype)initWithStyle:(QMUINavigationTitleViewStyle)style frame:(CGRect)
107107
self.verticalTitleFont = appearance.verticalTitleFont;
108108
self.verticalSubtitleFont = appearance.verticalSubtitleFont;
109109
self.accessoryViewOffset = appearance.accessoryViewOffset;
110+
self.tintColor = NavBarTitleColor;
110111
}
111112
return self;
112113
}
@@ -557,7 +558,6 @@ + (void)initialize {
557558

558559
+ (void)setDefaultAppearance {
559560
QMUINavigationTitleView *appearance = [QMUINavigationTitleView appearance];
560-
appearance.tintColor = NavBarTitleColor;
561561
appearance.loadingViewSize = CGSizeMake(18, 18);
562562
appearance.loadingViewMarginRight = 3;
563563
appearance.horizontalTitleFont = NavBarTitleFont;

QMUIKit/UIComponents/QMUIPopupContainerView.h

Lines changed: 76 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,95 +15,128 @@ typedef enum {
1515
} QMUIPopupContainerViewLayoutDirection;
1616

1717
/**
18-
* 带箭头的小tips浮层,自带 imageView 和 textLabel,可展示简单的图文信息。<br/>
18+
* 带箭头的小tips浮层,自带 imageView 和 textLabel,可展示简单的图文信息。
19+
* QMUIPopupContainerView 支持以两种方式显示在界面上:
20+
* 1. 添加到某个 UIView 上(适合于 viewController 切换时浮层跟着一起切换的场景),这种场景只能手动隐藏浮层。
21+
* 2. 在 QMUIPopupContainerView 自带的 UIWindow 里显示(适合于用完就消失的场景,不要涉及界面切换),这种场景支持点击空白地方自动隐藏浮层。
1922
*
20-
* 如果默认功能无法满足需求,请继承它重写一个子类。<br/>
21-
* 继承要点:<br/>
22-
* <ol>
23-
* <li>所有subviews请加到contentView上,相对于contentView布局</li>
24-
* <li>通过重写sizeThatFitsInContentView:,在里面返回当前subviews的大小,控件会根据这个大小来布局</li>
25-
* </ol>
26-
* 使用步骤:<br/>
27-
* <ol>
28-
* <li>使用init初始化</li>
29-
* <li>将控件添加到某个View上(一定要先添加,再layout,因为layout里会使用superview的bounds进行计算)</li>
30-
* <li>调用layoutWithReferenceItemRectInSuperview:将需要指向的目标的rect传进去,tipsView就会自动计算宽高和x/y,让箭头对准rect的中心点</li>
31-
* <li>注意传进去的rect必须和tipsView处于同一个坐标系内,必要时记得转换坐标系</li>
32-
* <li>如果需要显示/消失带有动画,则调用<i>showWithAnimated:</i>、<i>hideWithAnimated:</i>,记得show前先setHidden为YES。</li>
33-
* </ol>
23+
* 使用步骤:
24+
* 1. 调用 init 方法初始化。
25+
* 2. 选择一种显示方式:
26+
* 2.1 如果要添加到某个 UIView 上,则先设置浮层 hidden = YES,然后调用 addSubview: 把浮层添加到目标 UIView 上。
27+
* 2.2 如果是轻量的场景用完即走,则 init 完浮层即可,无需设置 hidden,也无需调用 addSubview:。
28+
* 3. 在适当的时机(例如 layoutSubviews: 或 viewDidLayoutSubviews:)调用 layoutWithTargetView: 让浮层参考目标 view 布局,或者调用 layoutWithTargetRectInScreenCoordinate: 让浮层参考基于屏幕坐标系里的一个 rect 来布局。
29+
* 4. 调用 showWithAnimated: 或 showWithAnimated:completion: 显示浮层。
30+
* 5. 调用 hideWithAnimated: 或 hideWithAnimated:completion: 隐藏浮层。
31+
*
32+
* 如果默认功能无法满足需求,可继承它重写一个子类,继承要点:
33+
* 1. 初始化时要做的事情请放在 didInitialized 里。
34+
* 2. 所有 subviews 请加到 contentView 上。
35+
* 3. 通过重写 sizeThatFitsInContentView:,在里面返回当前 subviews 的大小,控件最终会被布局为这个大小。
36+
* 4. 在 layoutSubviews: 里,所有 subviews 请相对于 contentView 布局。
3437
*/
3538

3639
@interface QMUIPopupContainerView : UIControl {
3740
CAShapeLayer *_backgroundLayer;
3841
CGFloat _arrowMinX;
3942
}
4043

41-
@property(nonatomic,assign) BOOL debug;
44+
@property(nonatomic, assign) BOOL debug;
45+
46+
/// 在浮层显示时,点击空白地方是否要自动隐藏浮层,仅在用方法 2 显示时有效。默认为 NO,也即需要代码手动调用才能隐藏。
47+
@property(nonatomic, assign) BOOL automaticallyHidesWhenUserTap;
4248

4349
/// 所有subview都应该添加到contentView上,默认contentView.userInteractionEnabled = NO,需要事件操作时自行打开
44-
@property(nonatomic,strong,readonly) UIView *contentView;
50+
@property(nonatomic, strong, readonly) UIView *contentView;
4551

4652
/// 预提供的UIImageView,默认为nil,调用到的时候才初始化
47-
@property(nonatomic,strong,readonly) UIImageView *imageView;
53+
@property(nonatomic, strong, readonly) UIImageView *imageView;
4854

4955
/// 预提供的UILabel,默认为nil,调用到的时候才初始化。默认支持多行。
50-
@property(nonatomic,strong,readonly) UILabel *textLabel;
56+
@property(nonatomic, strong, readonly) UILabel *textLabel;
5157

5258
/// 圆角矩形气泡内的padding(不包括三角箭头),默认是(8, 8, 8, 8)
53-
@property(nonatomic,assign) UIEdgeInsets contentEdgeInsets UI_APPEARANCE_SELECTOR;
59+
@property(nonatomic, assign) UIEdgeInsets contentEdgeInsets UI_APPEARANCE_SELECTOR;
5460

5561
/// 调整imageView的位置,默认为UIEdgeInsetsZero。top/left正值表示往下/右方偏移,bottom/right仅在对应位置存在下一个子View时生效(例如只有同时存在imageView和textLabel时,imageEdgeInsets.right才会生效)。
56-
@property(nonatomic,assign) UIEdgeInsets imageEdgeInsets UI_APPEARANCE_SELECTOR;
62+
@property(nonatomic, assign) UIEdgeInsets imageEdgeInsets UI_APPEARANCE_SELECTOR;
5763

5864
/// 调整textLabel的位置,默认为UIEdgeInsetsZero。top/left/bottom/right的作用同<i>imageEdgeInsets</i>
59-
@property(nonatomic,assign) UIEdgeInsets textEdgeInsets UI_APPEARANCE_SELECTOR;
65+
@property(nonatomic, assign) UIEdgeInsets textEdgeInsets UI_APPEARANCE_SELECTOR;
6066

61-
/// 三角箭头的大小
62-
@property(nonatomic,assign) CGSize arrowSize UI_APPEARANCE_SELECTOR;
67+
/// 三角箭头的大小,默认为 CGSizeMake(18, 9)
68+
@property(nonatomic, assign) CGSize arrowSize UI_APPEARANCE_SELECTOR;
6369

6470
/// 最大宽度(指整个控件的宽度,而不是contentView部分),默认为CGFLOAT_MAX
65-
@property(nonatomic,assign) CGFloat maximumWidth UI_APPEARANCE_SELECTOR;
71+
@property(nonatomic, assign) CGFloat maximumWidth UI_APPEARANCE_SELECTOR;
6672

6773
/// 最小宽度(指整个控件的宽度,而不是contentView部分),默认为0
68-
@property(nonatomic,assign) CGFloat minimumWidth UI_APPEARANCE_SELECTOR;
74+
@property(nonatomic, assign) CGFloat minimumWidth UI_APPEARANCE_SELECTOR;
6975

7076
/// 最大高度(指整个控件的高度,而不是contentView部分),默认为CGFLOAT_MAX
71-
@property(nonatomic,assign) CGFloat maximumHeight UI_APPEARANCE_SELECTOR;
77+
@property(nonatomic, assign) CGFloat maximumHeight UI_APPEARANCE_SELECTOR;
7278

7379
/// 最小高度(指整个控件的高度,而不是contentView部分),默认为0
74-
@property(nonatomic,assign) CGFloat minimumHeight UI_APPEARANCE_SELECTOR;
80+
@property(nonatomic, assign) CGFloat minimumHeight UI_APPEARANCE_SELECTOR;
7581

7682
/// 计算布局时期望的默认位置,默认为QMUIPopupContainerViewLayoutDirectionAbove,也即在目标的上方
77-
@property(nonatomic,assign) QMUIPopupContainerViewLayoutDirection preferLayoutDirection UI_APPEARANCE_SELECTOR;
83+
@property(nonatomic, assign) QMUIPopupContainerViewLayoutDirection preferLayoutDirection UI_APPEARANCE_SELECTOR;
7884

7985
/// 最终的布局方向(preferLayoutDirection只是期望的方向,但有可能那个方向已经没有剩余空间可摆放控件了,所以会自动变换)
80-
@property(nonatomic,assign,readonly) QMUIPopupContainerViewLayoutDirection currentLayoutDirection;
86+
@property(nonatomic, assign, readonly) QMUIPopupContainerViewLayoutDirection currentLayoutDirection;
8187

8288
/// 最终布局时箭头距离目标边缘的距离,默认为5
83-
@property(nonatomic,assign) CGFloat distanceBetweenTargetRect UI_APPEARANCE_SELECTOR;
89+
@property(nonatomic, assign) CGFloat distanceBetweenTargetRect UI_APPEARANCE_SELECTOR;
8490

8591
/// 最终布局时与父节点的边缘的临界点,默认为(10, 10, 10, 10)
86-
@property(nonatomic,assign) UIEdgeInsets safetyMarginsOfSuperview UI_APPEARANCE_SELECTOR;
92+
@property(nonatomic, assign) UIEdgeInsets safetyMarginsOfSuperview UI_APPEARANCE_SELECTOR;
8793

88-
@property(nonatomic,strong) UIColor *backgroundColor UI_APPEARANCE_SELECTOR;
89-
@property(nonatomic,strong) UIColor *highlightedBackgroundColor UI_APPEARANCE_SELECTOR;
90-
@property(nonatomic,strong) UIColor *shadowColor UI_APPEARANCE_SELECTOR;
91-
@property(nonatomic,strong) UIColor *borderColor UI_APPEARANCE_SELECTOR;
92-
@property(nonatomic,assign) CGFloat borderWidth UI_APPEARANCE_SELECTOR;
93-
@property(nonatomic,assign) CGFloat cornerRadius UI_APPEARANCE_SELECTOR;
94+
@property(nonatomic, strong) UIColor *backgroundColor UI_APPEARANCE_SELECTOR;
95+
@property(nonatomic, strong) UIColor *highlightedBackgroundColor UI_APPEARANCE_SELECTOR;
9496

95-
/// 子类重写,告诉父类subviews的合适大小
96-
- (CGSize)sizeThatFitsInContentView:(CGSize)size;
97+
/// 当使用方法 2 显示时,可修改背景遮罩的颜色,默认为 UIColorClear。
98+
@property(nonatomic, strong) UIColor *maskViewBackgroundColor UI_APPEARANCE_SELECTOR;
99+
@property(nonatomic, strong) UIColor *shadowColor UI_APPEARANCE_SELECTOR;
100+
@property(nonatomic, strong) UIColor *borderColor UI_APPEARANCE_SELECTOR;
101+
@property(nonatomic, assign) CGFloat borderWidth UI_APPEARANCE_SELECTOR;
102+
@property(nonatomic, assign) CGFloat cornerRadius UI_APPEARANCE_SELECTOR;
103+
104+
/**
105+
* 相对于某个 view 布局(布局后箭头不一定会水平居中)
106+
* @param targetView 注意如果这个 targetView 自身的布局发生变化,需要重新调用 layoutWithTargetView:,否则浮层的布局不会自动更新。
107+
*/
108+
- (void)layoutWithTargetView:(UIView *)targetView;
97109

98110
/**
99-
* 利用参考的目标itemRect,计算出tips合适的布局位置(箭头并非绝对居中
100-
* @param itemRect 参考对齐的UIBarButtonItem的rect(rect是相对于toolbar的坐标系而言)
111+
* 相对于给定的 itemRect 布局(布局后箭头不一定会水平居中
112+
* @param targetRect 注意这个 rect 应该是处于屏幕坐标系里的 rect,所以请自行做坐标系转换。
101113
*/
102-
- (void)layoutWithReferenceItemRectInSuperview:(CGRect)itemRect;
114+
- (void)layoutWithTargetRectInScreenCoordinate:(CGRect)targetRect;
103115

104116
- (void)showWithAnimated:(BOOL)animated;
105117
- (void)showWithAnimated:(BOOL)animated completion:(void (^)(BOOL finished))completion;
106118
- (void)hideWithAnimated:(BOOL)animated;
107119
- (void)hideWithAnimated:(BOOL)animated completion:(void (^)(BOOL finished))completion;
108120
- (BOOL)isShowing;
121+
122+
/**
123+
* 即将隐藏时的回调
124+
* @argv hidesByUserTap 用于区分此次隐藏是否因为用户手动点击空白区域导致浮层被隐藏
125+
*/
126+
@property(nonatomic, copy) void (^willHideBlock)(BOOL hidesByUserTap);
127+
128+
/**
129+
* 已经隐藏后的回调
130+
* @argv hidesByUserTap 用于区分此次隐藏是否因为用户手动点击空白区域导致浮层被隐藏
131+
*/
132+
@property(nonatomic, copy) void (^didHideBlock)(BOOL hidesByUserTap);
133+
@end
134+
135+
@interface QMUIPopupContainerView (UISubclassingHooks)
136+
137+
/// 子类重写,在初始化时做一些操作
138+
- (void)didInitialized NS_REQUIRES_SUPER;
139+
140+
/// 子类重写,告诉父类subviews的合适大小
141+
- (CGSize)sizeThatFitsInContentView:(CGSize)size;
109142
@end

0 commit comments

Comments
 (0)