Skip to content

Commit 60d384b

Browse files
committed
fix bug
1 parent 5bb90d1 commit 60d384b

7 files changed

Lines changed: 38 additions & 20 deletions

ZHIntersectionObserver.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Pod::Spec.new do |spec|
1616
#
1717

1818
spec.name = "ZHIntersectionObserver"
19-
spec.version = "0.0.3"
19+
spec.version = "0.0.4"
2020
spec.summary = "Intersection Observer for iOS."
2121

2222
# This description is used to generate tags and improve search results.

ZHIntersectionObserver/Example/Pages/ZHExample2ViewController.m

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,9 @@ - (void)viewDidLoad {
3434
self.view.backgroundColor = [UIColor whiteColor];
3535
self.tableView.rowHeight = 100;
3636

37-
/*
3837
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
3938
[self.tableView reloadData];
4039
});
41-
*/
4240
}
4341

4442
- (void)updateNavigationItem {

ZHIntersectionObserver/Example/ZHExampleTableViewController.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ @implementation ZHExampleTableViewController
1919
- (void)viewDidLoad {
2020
[super viewDidLoad];
2121
self.view.backgroundColor = [UIColor whiteColor];
22-
self.tableView.rowHeight = 80;
22+
self.tableView.rowHeight = 96;
2323
self.title = @"ZHIntersectionObsever";
2424
}
2525

@@ -42,7 +42,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
4242
cell.detailTextLabel.numberOfLines = 0;
4343

4444
if (indexPath.row == 0) {
45-
cell.textLabel.text = @"基础功能体验";
45+
cell.textLabel.text = @"基础功能体验 - 1";
4646
cell.detailTextLabel.text = @"设置和更新容器大小,设置曝光临界点,动态检测曝光";
4747
}
4848

ZHIntersectionObserver/Source/IntersectionObserver.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ - (BOOL)addTargetOptions:(UIView *)target options:(IntersectionObserverTargetOpt
4040
return YES;
4141
}
4242
} else {
43-
// view 不复用,但是 dataKey 一样,这个时候需要移除旧的 options
43+
// view 不复用,但是 dataKey 一样,这个时候需要移除旧的 options,并且同步旧 options 的 preXXX 属性到新 options 上
4444
UIView *existTarget = [self isTargetDataKeyExisted:options.dataKey];
45+
IntersectionObserverTargetOptions *oldOptions = [self.targetOptions objectForKey:existTarget];
4546
if (existTarget && target != existTarget) {
47+
[IntersectionObserverMeasure updateOptionsPreProperties:options fromOldOptions:oldOptions];
4648
[self.targetOptions removeObjectForKey:existTarget];
4749
}
4850
[self.targetOptions setObject:options forKey:target];

ZHIntersectionObserver/Source/IntersectionObserverMeasure.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ NS_ASSUME_NONNULL_BEGIN
2727
+ (BOOL)isTargetOptions:(IntersectionObserverTargetOptions *)options1
2828
sameWithOptions:(IntersectionObserverTargetOptions *)options2;
2929

30+
/// 更新 view 不复用但是 dataKey 相同的场景下的 options,对齐其 preXXX 属性,避免判断错误
31+
+ (void)updateOptionsPreProperties:(IntersectionObserverTargetOptions *)options
32+
fromOldOptions:(IntersectionObserverTargetOptions *)oldOptions;
33+
3034
@end
3135

3236

ZHIntersectionObserver/Source/IntersectionObserverMeasure.m

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -324,31 +324,32 @@ + (BOOL)canReportWithRatio:(CGFloat)ratio
324324
BOOL isDataKeyVisible = targetOptions.dataKey ? [[IntersectionObserverReuseManager shareInstance] isDataKeyVisible:targetOptions.dataKey inScope:containerOptions.scope] : NO;
325325

326326
// 生命周期发生变化
327-
if (containerOptions.measureWhenAppStateChanged) {
327+
if (containerOptions.measureWhenAppStateChanged && targetOptions.dataKey) {
328328
UIApplicationState prevApplicationState = [IntersectionObserverManager shareInstance].previousApplicationState;
329329
if (prevApplicationState != UIApplicationStateActive &&
330330
UIApplication.sharedApplication.applicationState == UIApplicationStateActive) {
331-
// TODO: 先直接返回 YES,这样导致那些那些一开始没曝光的 item 会发送多 isInsecting = NO 的通知
332-
// TODO: 如果改为 isInsecting != targetOptions.preInsecting 会导致 cell 不复用的情况切换前后台无法触发事件
333-
return YES; // isInsecting != targetOptions.preInsecting;
331+
// 重新计算,只要是 isInsecting 即可发送事件。如果没有设置 dataKey,回到前台会多发送一次曝光事件,所以屏蔽一下。
332+
if (targetOptions.dataKey) {
333+
return isInsecting;
334+
}
335+
return NO;
334336
}
335337
if (prevApplicationState != UIApplicationStateBackground &&
336338
UIApplication.sharedApplication.applicationState == UIApplicationStateBackground) {
337-
// TODO: 先直接返回 YES,这样导致那些那些一开始没曝光的 item 会发送多 isInsecting = NO 的通知
338-
// TODO: 如果改为 isInsecting != targetOptions.preInsecting 会导致 cell 不复用的情况切换前后台无法触发事件
339-
return YES; // isInsecting != targetOptions.preInsecting;
339+
// 直接返回 YES 会导致那些那些一开始没曝光的 item 会发送多 isInsecting = NO 的通知
340+
// 如果改为 isInsecting != targetOptions.preInsecting 会导致 cell 不复用的情况切换前后台无法触发事件,所以需要通过 updateOptionsPreProperties:fromOldOptions 同步一下 options,但是还是会存在之前非曝光过的被复用到曝光的时候,isInsecting != targetOptions.preInsecting 为 NO(isInsecting 必定为 NO,没曝光的 item 的 targetOptions.preInsecting 也是 NO),导致当前没有发送 isInsecting = NO 事件,所以最后改成 isDataKeyVisible,但是要求设置 dataKey 才能生效。
341+
return [[IntersectionObserverReuseManager shareInstance] isDataKeyVisible:targetOptions.dataKey inScope:containerOptions.scope];
340342
}
341343
}
342344

343-
// TODO: 可视状态发生变化
344-
/*
345-
if (containerOptions.measureWhenVisibilityChanged) {
345+
// 可视状态发生变化
346+
if (containerOptions.measureWhenVisibilityChanged && targetOptions.dataKey) {
346347
BOOL targetViewVisible = [self isTargetViewVisible:targetOptions.targetView inContainerView:containerOptions.containerView];
347348
BOOL containerViewVisible = [self isContainerViewVisible:containerOptions.containerView];
348349
if (targetViewVisible != targetOptions.preVisible || containerViewVisible != containerOptions.preVisible) {
349-
return isInsecting != targetOptions.preInsecting;
350+
return isInsecting != targetOptions.preInsecting && ![[IntersectionObserverReuseManager shareInstance] isDataKeyVisible:targetOptions.dataKey inScope:containerOptions.scope];
350351
}
351-
}*/
352+
}
352353

353354
// 数据发生变化(或者复用)
354355
if (targetOptions.dataKey && targetOptions.dataKey.length > 0 && ![targetOptions.dataKey isEqualToString:targetOptions.preDataKey]) {
@@ -460,6 +461,19 @@ + (BOOL)isCGRectValidated:(CGRect)rect {
460461
return !CGRectIsNull(rect) && !CGRectIsInfinite(rect) && !isCGRectNaN && !isCGRectInf;
461462
}
462463

464+
+ (void)updateOptionsPreProperties:(IntersectionObserverTargetOptions *)options
465+
fromOldOptions:(IntersectionObserverTargetOptions *)oldOptions {
466+
if (options && oldOptions) {
467+
options.preRatio = oldOptions.preRatio;
468+
options.preInsecting = oldOptions.preInsecting;
469+
options.preVisible = oldOptions.preVisible;
470+
options.preDataKey = oldOptions.preDataKey;
471+
options.preData = oldOptions.preData;
472+
options.preDataKey = oldOptions.preDataKey;
473+
options.preReuseInsecting = oldOptions.preReuseInsecting;
474+
}
475+
}
476+
463477
@end
464478

465479

ZHIntersectionObserver/Source/IntersectionObserverOptions.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ NS_ASSUME_NONNULL_BEGIN
2626
/// 节流参数,频率限制,默认 100 ms。需要搭配 intersectionDuration 一起使用,不宜设置太大,否则 intersectionDuration 效果会不明显。
2727
@property(nonatomic, assign, readonly) NSTimeInterval throttle;
2828

29-
/// measure when appState changed, default YES.
29+
/// appState 发生变化是否重新检测曝光,默认 YES。这个属性只有当设置了 dataKey 才会生效。
3030
@property(nonatomic, assign, readonly) BOOL measureWhenAppStateChanged;
3131

32-
/// measure when containerView visibility changed, default YES.
32+
/// 可视状态发生变化是否重新检测曝光, 默认 YES。这个属性只有当设置了 dataKey 才会生效。
3333
@property(nonatomic, assign, readonly) BOOL measureWhenVisibilityChanged;
3434

3535
/// 触发 intersection 事件之后经过 duration 时长再检查一次如果两次结果一样,才会 callback 给业务。可以理解为曝光时长,用于解决快速滚动或者本地数据被网络数据覆盖的场景,默认为 600 ms

0 commit comments

Comments
 (0)