React Native的ScrollView顶部出现白条

刚换工作,接手新公司的一个RN项目,同事向我反映了一个问题,说我们的App的首页,滚动后顶部就出现了一个白条,仅在iOS端出现,Android上运行良好。我一听就猜想是ScrollView兼容出问题了,尝试用iOS 9和iOS 11手机分别运行了一下,在iOS 11的手机上重现了这个问题。于是检查代码,发现是iOS 11上UIScrollView增加了contentInsetAdjustmentBehavior属性。

/* Configure the behavior of adjustedContentInset.
 Default is UIScrollViewContentInsetAdjustmentAutomatic.
 */
@property(nonatomic) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior API_AVAILABLE(ios(11.0),tvos(11.0));


typedef NS_ENUM(NSInteger, UIScrollViewContentInsetAdjustmentBehavior) {
    UIScrollViewContentInsetAdjustmentAutomatic, // Similar to .scrollableAxes, but for backward compatibility will also adjust the top & bottom contentInset when the scroll view is owned by a view controller with automaticallyAdjustsScrollViewInsets = YES inside a navigation controller, regardless of whether the scroll view is scrollable
    UIScrollViewContentInsetAdjustmentScrollableAxes, // Edges for scrollable axes are adjusted (i.e., contentSize.width/height > frame.size.width/height or alwaysBounceHorizontal/Vertical = YES)
    UIScrollViewContentInsetAdjustmentNever, // contentInset is not adjusted
    UIScrollViewContentInsetAdjustmentAlways, // contentInset is always adjusted by the scroll view's safeAreaInsets
} API_AVAILABLE(ios(11.0),tvos(11.0));

contentInsetAdjustmentBehavior默认为automatic时,它会根据屏幕上是否有UINavigationBar,UITabBar,可见状态栏等自动调整ContentInset(并覆盖任何手动设置的ContentInset)

刚好我们的主页上有UITabBar,于是就被自动调整了ContentInset,就出现了顶部的白条。

怎么解决

在新版本的React Native中已经修复了此问题,在ScrollView上新增了contentInsetAdjustmentBehavior属性,且默认为never,所以使用新版本React Native的童鞋一般是不会遇到这个问题的。但是我司App的React Native版本是0.38,因为历史原因也不能直接去升级React Native版本,所以就自己动手修改源码吧。
以下是修改位置和源码:(参考了React Native新版本的代码)

文件RCTScrollView.m
initWithEventDispatcher方法中增加:

#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
      // `contentInsetAdjustmentBehavior` is only available since iOS 11.
      // We set the default behavior to "never" so that iOS
      // doesn't do weird things to UIScrollView insets automatically
      // and keeps it as an opt-in behavior.
      if ([_scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
        _scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
      }
#endif

以下代码可在@implementation RCTScrollView任意位置加入,我是加在sendScrollEventWithName方法前的。

#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
- (void)setContentInsetAdjustmentBehavior:(UIScrollViewContentInsetAdjustmentBehavior)behavior
{
      // `contentInsetAdjustmentBehavior` is available since iOS 11.
      if ([_scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
            CGPoint contentOffset = _scrollView.contentOffset;
            _scrollView.contentInsetAdjustmentBehavior = behavior;
            _scrollView.contentOffset = contentOffset;
      }
}
#endif

文件RCTScrollViewManager.m
可在@implementation RCTScrollViewManager中任意位置加入以下代码,不过为了和其他代码统一,我们在RCT_EXPORT_VIEW_PROPERTY那堆代码后进行增加。

#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
RCT_EXPORT_VIEW_PROPERTY(contentInsetAdjustmentBehavior, UIScrollViewContentInsetAdjustmentBehavior)
#endif

@implementation RCTConvert (UIScrollView)中增加

#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
RCT_ENUM_CONVERTER(UIScrollViewContentInsetAdjustmentBehavior, (@{
                                                                   @"automatic": @(UIScrollViewContentInsetAdjustmentAutomatic),
                                                                   @"scrollableAxes": @(UIScrollViewContentInsetAdjustmentScrollableAxes),
                                                                   @"never": @(UIScrollViewContentInsetAdjustmentNever),
                                                                   @"always": @(UIScrollViewContentInsetAdjustmentAlways),
                                                                }), UIScrollViewContentInsetAdjustmentNever, integerValue)
#endif

文件ScrollView.js
在ScrollView的propTypes中增加contentInsetAdjustmentBehavior属性。

contentInsetAdjustmentBehavior: PropTypes.oneOf([
       'automatic',
       'scrollableAxes',
       'never', // default
       'always',
    ]),

修改完毕,运行后白条消失,不过这只是临时解决方案,接下来还是要想办法把React Native的版本升级一下,以免遇到更多的坑。

参考GitHub: 1954438 #diff-973dcd0e3fbfcc5e35485bb6404a2fd2

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容