业务思路: 客户端调用Java接口把消息id,收藏时间传给后台APIWeb服务器,后端和 IM 服务器通讯,拿到真正收藏的消息StoreBody 进行存储。
收藏:
APIWeb服务器业务收藏成功,返回相关收藏id给客户端。进行存储到表中。
删除:
客户端根据收藏id调用java接口成功后将收藏记录移除。
同步数据:
每次打开个人中心的收藏页面,请求接口进行数据同步,服务器存储时间戳和数条记录,客户端拿到数据后进行循环处理每条记录,根据收藏id,收藏时间,删除标记来决定是否将该记录进行插入到本地收藏表中。
为了使搜索的结果控制器直接重用收藏的控制器。封装了类似EHMyStoreBaseResultsController的result控制器来进行显示。 收藏的基类EHMyStoreBaseController 持有displayController 即为该类型。
同时,该StoreBaseController实现了GYContainerSearchResultsDelegate协议。如下:记录搜索关键字。
1 | - (void)beginStoreSearchByKeyWords:(NSString *)searchStr |
- h 文件
1 | @protocol GYContainerSearchResultsDelegate <NSObject> |
- m文件
1 | @interface EHMyStoreBaseResultsController() |
分割线
EHMyStoreBaseResultsController: GYContainerSearchResultsController
GYSearchController 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72@interface GYSearchController : UISearchController
@end
@interface GYSearchController ()
@end
@implementation GYSearchController
- (void)viewDidLoad {
NSLog(@"viewDidLoad");
[super viewDidLoad];
[self add_imageBg];
}
- (void)viewWillAppear:(BOOL)animated {
NSLog(@"");
[super viewWillAppear:animated];
}
-(void)viewDidLayoutSubviews {
NSLog(@"viewDidLayoutSubviews");
[self setSomeFrame];
[super viewDidLayoutSubviews];
[self setSomeFrame];
}
-(void)viewWillLayoutSubviews {
NSLog(@"viewWillLayoutSubviews");
[self setSomeFrame];
[super viewWillLayoutSubviews];
[self setSomeFrame];
}
- (void) setSomeFrame {
if(kIS_IPHONE_X){
if(1){//searBar内部背景修正
if (@available(iOS 11.0, *)) {
CGRect rect = [[self.searchBar subviews][0] subviews][0].frame;
if(self.isActive){
CGFloat statusHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
rect.origin.y = - statusHeight;
rect.size.height = self.searchBar.bounds.size.height;
[[self.searchBar subviews][0] subviews][0].frame = rect;
}
}
}
}
}
//添加图片的方式
- (void)add_imageBg {
UIImageView *imageBg = ({
UIImageView *iv = (UIImageView*)[self.view viewWithTag:999];
if(!iv){
UIColor *searchBarBgColor = [UIColor colorWithRed:242.0/255.0 green:242.0/255.0 blue:242.0/255.0 alpha:1.0];
CGFloat statusHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
iv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, statusHeight+self.searchBar.frame.size.height-1)];//后面-1是因为iphoneX实际调试为99=44+56-1
iv.backgroundColor = [UIColor redColor];
iv.backgroundColor = searchBarBgColor;
iv.tag = 999;
[self.view addSubview:iv];
}
iv;
});
imageBg.hidden = NO;
}
@endGYContainerSearchResultsController 文件
h文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
///为UISearchController的searchResultsController对象
@interface GYContainerSearchResultsController : UIViewController
@property(nonatomic,readonly) NSString *baseChildControllerName;
- (instancetype)initWithWrapStoreBaseControllerName:(NSString *)baseChildControllerName;
/** 搜索的searchController */
@property(nonatomic, strong) UISearchController *searchController;
/** 是否激活搜索状态中:注意新旧两版不同细节情况;特别旧版在WillEnd开始就为NO了 */
@property(nonatomic, assign) BOOL isActive;
/** 搜索的searchBar */
@property(nonatomic, strong) UISearchBar *searchBar;
/** 搜索的搜索字串 */
@property (nonatomic,strong) NSString *searchStr;
/** 当前Search的上级宿主viewController (一般为self.searchController的nextResponder,只有在搜索框显示出来时才可使用!!!) */
@property(nonatomic, weak) UIViewController *hostViewController;
@property(nonatomic, strong) NSString *defaultTipStr;
@property(nonatomic, copy) void(^willPresentSearchControllerBlock)(GYContainerSearchResultsController *searchResultsController);
@property(nonatomic, copy) void(^didPresentSearchControllerBlock)(GYContainerSearchResultsController *searchResultsController);
@property(nonatomic, copy) void(^willDismissSearchControllerBlock)(GYContainerSearchResultsController *searchResultsController);
@property(nonatomic, copy) void(^didDismissSearchControllerBlock)(GYContainerSearchResultsController *searchResultsController);
/** 上级viewController初始化一些设置 @param viewController 传入待处理的vc */
+ (void)viewController_viewDidLoad_someSetting:(UIViewController*)viewController;
/** 初始化设置searchBar */
- (void)initSearchBar;
-(void)viewController_viewDidLayoutSubviews:(UITableView *)tableView hostViewController:(UIViewController*)hostViewController bottomMargin:(CGFloat)bottomMargin;
@end
@interface GYContainerSearchResultsController(GY_UISearchBarDelegate)
-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar;
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText;
- (void)searchHandle;
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar;
- (void)setSearchResultsTitle:(NSString *)title;
- (void)showSearchTip:(NSString *)title;
@endm文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
@interface GYContainerSearchResultsController ()<UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate
>
@property (nonatomic, strong) UILabel *emptyTipsLabel;
@property (nonatomic, strong) UILabel *defaultTipsLabel;
@end
@implementation GYContainerSearchResultsController
- (UIViewController *)hostViewController {
if (_hostViewController==nil) {
UIResponder *nextResponder = [self.searchController nextResponder];
if ([nextResponder isKindOfClass:[UIViewController class]]) {
_hostViewController = (UIViewController *)nextResponder;
}
}
return _hostViewController;
}
- (BOOL)isActive {
return self.searchController.active;
}
- (instancetype)initWithWrapStoreBaseControllerName:(NSString *)baseChildControllerName
{
if(self = [super init]) {
_baseChildControllerName = baseChildControllerName;
//初始化设置searchBar
[self initSearchBar];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
if(_emptyTipsLabel == nil){
_emptyTipsLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 30, SCREEN_WIDTH, 30)];
_emptyTipsLabel.font = [UIFont systemFontOfSize:20.0f];
_emptyTipsLabel.textColor = [UIColor colorWithRed:202.0/255.0 green:202.0/255.0 blue:202.0/255.0 alpha:1.0];
_emptyTipsLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:_emptyTipsLabel];
}
}
- (UILabel *)defaultTipsLabel{
if (_defaultTipsLabel == nil) {
UILabel *lab = [UILabel new];
lab.textColor = KUIColorFromRGB(0x417FF8);
lab.font = [UIFont systemFontOfSize:17];
_defaultTipsLabel = lab;
_defaultTipsLabel.hidden = YES;
[self.searchController.searchBar addSubview:_defaultTipsLabel];
}
return _defaultTipsLabel;
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSLog(@"updateSearchResultsForSearchController->inputStr==%@",searchController.searchBar.text);
}
- (void)willPresentSearchController:(UISearchController *)searchController {
NSLog(@"willPresentSearchController");
if (self.defaultTipStr.length) {
self.defaultTipsLabel.hidden = NO;
float w = [self.defaultTipStr boundingRectWithSize:CGSizeMake(MAXFLOAT, 30) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:17]} context:nil].size.width + 10;
self.defaultTipsLabel.text = self.defaultTipStr;
self.defaultTipsLabel.frame = CGRectMake(40, 5, w, self.searchBar.bounds.size.height - 10);
self.searchBar.searchTextPositionAdjustment = UIOffsetMake(w, 0);
self.searchBar.placeholder = @"";
}else{
self.defaultTipsLabel.hidden = YES;
self.searchBar.searchTextPositionAdjustment = UIOffsetMake(0, 0);
[self.searchBar changeLeftPlaceholder:[StringUtil getLocalizableString:@"chats_search"]];
}
!self.willPresentSearchControllerBlock?:self.willPresentSearchControllerBlock(self);
}
- (void)didPresentSearchController:(UISearchController *)searchController {
NSLog(@"didPresentSearchController");
!self.didPresentSearchControllerBlock?:self.didPresentSearchControllerBlock(self);
}
- (void)willDismissSearchController:(UISearchController *)searchController {
[self.navigationController setNavigationBarHidden:NO animated:NO];
[self.navigationController.view layoutIfNeeded];
self.defaultTipsLabel.hidden = YES;
self.searchBar.searchTextPositionAdjustment = UIOffsetMake(0, 0);
[self.searchBar changeLeftPlaceholder:[StringUtil getLocalizableString:@"chats_search"]];
!self.willDismissSearchControllerBlock?:self.willDismissSearchControllerBlock(self);
}
- (void)didDismissSearchController:(UISearchController *)searchController {
NSLog(@"didDismissSearchController");
!self.didDismissSearchControllerBlock?:self.didDismissSearchControllerBlock(self);
}
- (void)presentSearchController:(UISearchController *)searchController {
NSLog(@"presentSearchController");
}
-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
NSLog(@"searchBarShouldBeginEditing");
return YES;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(@"%s", __FUNCTION__);
self.searchStr = [StringUtil trimString:searchBar.text];
[self setSearchResultsTitle:nil];
if([self.searchStr length] == 0) {
}
else if ([self.searchStr length] == 1) {
[self setSearchResultsTitle:[StringUtil getLocalizableString:@"search_tip"]];
}
else {
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(searchHandle) object:nil];
[self performSelector:@selector(searchHandle) withObject:nil afterDelay:0.2f];
}
}
- (void)searchHandle {
NSLog(@"开始去搜索。。。。");
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
if ([self.searchStr length] < 1) {
return;
}
//去除焦点收键盘
[searchBar resignFirstResponder];
//搜索提示
[[LCLLoadingView currentIndicator] setCenterMessage:[StringUtil getLocalizableString:@"searching"]];
[[LCLLoadingView currentIndicator] show];
//再搜索
[self searchHandle];
}
//搜索提示文字
- (void)setSearchResultsTitle:(NSString *)title {
if(title==nil){
_emptyTipsLabel.hidden = YES;
}else{
_emptyTipsLabel.hidden = NO;
_emptyTipsLabel.text = [NSString stringWithFormat:@"%@", title];
}
}
//alert
- (void)showSearchTip:(NSString *)title {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:@"" delegate:nil cancelButtonTitle:[StringUtil getLocalizableString:@"confirm"] otherButtonTitles: nil];
[alert show];
}
+ (void)viewController_viewDidLoad_someSetting:(UIViewController*)viewController
{
UIViewController *_self = viewController;
//#warning 如果进入预编辑状态,searchBar消失(UISearchController套到�TabBarController可能会出现这个情况),请添加下边这句话
_self.definesPresentationContext=YES;
if (@available(iOS 11.0, *)) {
} else {
_self.automaticallyAdjustsScrollViewInsets = NO;
}
//适配ios7UIViewController的变化
if ([_self respondsToSelector:@selector(extendedLayoutIncludesOpaqueBars)]) {
_self.extendedLayoutIncludesOpaqueBars = NO;
}
_self.edgesForExtendedLayout = UIRectEdgeAll;
//第三种方式开关
[_self setAutomaticallyAdjustsScrollViewInsets:YES];
[_self setExtendedLayoutIncludesOpaqueBars:YES];
_self.edgesForExtendedLayout = UIRectEdgeNone;
_self.edgesForExtendedLayout = UIRectEdgeBottom | UIRectEdgeLeft | UIRectEdgeRight;
}
- (void)initSearchBar {
// 创建用于展示搜索结果的控制器
GYContainerSearchResultsController *result = self;
self.searchController = ({
UISearchController *_searchController = [[GYSearchController alloc] initWithSearchResultsController:result];
_searchController.delegate = self;
_searchController.searchResultsUpdater = result;
_searchController.dimsBackgroundDuringPresentation = YES;//取消蒙版
_searchController.obscuresBackgroundDuringPresentation = NO;//搜索时,背景变模糊
_searchController.hidesNavigationBarDuringPresentation = YES;//点击搜索的时候,是否隐藏导航栏
_searchController;
});
self.searchBar = self.searchController.searchBar;
[self.searchBar changeLeftPlaceholder:[StringUtil getLocalizableString:@"chats_search"]];
self.searchBar.delegate = self;
[self.searchBar setBackgroundImage:[self imageWithColor:KUIColorFromRGB(0xF5F5F5) size:self.searchBar.bounds.size]];
UIImage *image = [self imageWithColor:KUIColorFromRGB(0xffffff) size:CGSizeMake(self.searchBar.bounds.size.width, self.searchBar.bounds.size.height - 20)];
image = [self rh_bezierPathClip:image cornerRadius:8];
[_searchBar setSearchFieldBackgroundImage:image forState:UIControlStateNormal];
}
- (UIImage *)rh_bezierPathClip:(UIImage *)img
cornerRadius:(CGFloat)cornerRadius {
int w = img.size.width * img.scale;
int h = img.size.height * img.scale;
CGRect rect = (CGRect){CGPointZero, CGSizeMake(w, h)};
UIGraphicsBeginImageContextWithOptions(CGSizeMake(w, h), false, 1.0);
[[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:cornerRadius] addClip];
[img drawInRect:rect];
UIImage *cornerImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return cornerImage;
}
- (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size{
CGRect rect = CGRectMake(0, 0, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
-(void)viewController_viewDidLayoutSubviews:(UITableView *)tableView hostViewController:(UIViewController*)hostViewController bottomMargin:(CGFloat)bottomMargin{
//调节宿主tableView
CGRect tableViewAdjustRect = CGRectZero;
if(self.isActive) {
CGFloat y = [[UIApplication sharedApplication] statusBarFrame].size.height+self.searchBar.frame.size.height;
y = (!kIS_IPHONE_X)?y:(y-1);//iphonex时搜索部分的高度为99=44+56-1;
CGFloat height = SCREEN_HEIGHT-y;
UINavigationController *nav = hostViewController.navigationController;
if(nav && nav.viewControllers[0] == hostViewController
&& [nav nextResponder]
&&([[nav nextResponder] isKindOfClass:[UITabBarController class]]//ios11
||[[[[nav nextResponder] nextResponder] nextResponder] nextResponder]//ios10
)
){//在tabarController里且为其导航根vc时,要减去下面的tabBar下面高度
height = SCREEN_HEIGHT-y-TABBAR_HEIGHT-safeAreaXBottom;
}
tableViewAdjustRect = CGRectMake(0, y, SCREEN_WIDTH, height);
}else {
CGFloat y = self.searchBar.frame.size.height;
CGFloat height = SCREEN_HEIGHT-NAVIGATIONBAR_HEIGHT-STATUSBAR_HEIGHT-y;//-safeAreaXBottom;
UINavigationController *nav = hostViewController.navigationController;
if(nav && nav.viewControllers[0] == hostViewController
&& [nav nextResponder]
&&([[nav nextResponder] isKindOfClass:[UITabBarController class]]//ios11
||[[[[nav nextResponder] nextResponder] nextResponder] nextResponder]//ios10
)
){
height = SCREEN_HEIGHT-NAVIGATIONBAR_HEIGHT-STATUSBAR_HEIGHT-self.searchBar.frame.size.height-TABBAR_HEIGHT-safeAreaXBottom;
}
tableViewAdjustRect = CGRectMake(0, y, SCREEN_WIDTH, height);
}
if (bottomMargin > 0) {
CGRect rect = tableViewAdjustRect;
CGFloat h = rect.size.height - bottomMargin;
if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) && ([UIScreen mainScreen].bounds.size.width >= 375) && ([UIScreen mainScreen].bounds.size.height >= 812)) {
h -= 34;
}
tableView.frame = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width,h);
}else{
tableView.frame = tableViewAdjustRect;
}
}