微信小程序iOS下使用picker选择器与软键盘重叠遮挡问题的解决方案

今天可真是高产呀,哈哈,项目告一段落就有时间review下代码啦,顺便把坑记录一下

项目场景:

一个表单提交页,input、picker都有用到

问题描述:

在这里插入图片描述

如图所示,iOS下如果先点击了input弹出软键盘,再点击picker弹出选择框,但是软键盘却没有收起。

<Picker className='complaintViewTextPicker' value={selectorChecked} mode='multiSelector' range={mulSelector} onChange={this.onChangeComplaintType.bind(this)} onColumnChange={this.onColumnChange.bind(this)} >
                <AtList>
                  <AtListItem
                    title=''
                    extraText={selectorChecked}
                  />
                </AtList>
 </Picker>

原因分析:

首先,既然iOS不收起,那我们在点击picker时强制收起键盘不久行了嘛!
于是监听点击事件,让键盘收起。
但是,经过实践后发现,如果我们点击完input隔一段时间再点击picker,键盘是可以正常收起的,但是如果我们快一点,还是会出现重叠的情况,
观察发现苹果手机picker选择框弹起来的时候有一个自带的动画效果,快速切换点击就是发生在弹起动画过程中了,而动画执行的过程中是屏蔽了我们做的一些操作的。


解决方案:

我当时的话经过查找资料以及结合原因思考是有下面两种还算可行的解决方案的,当然,只是我觉得行,事实上还是有些不完美,但是没办法,iOS系统的原因实在是不会搞啊,除非把上弹动画禁止,但是我不会啊😭

  • 方案一
    利用延时,让收起键盘的操作等动画执行完再做,但是我们不知道它整个动画具体的执行时间是多少,所以我们可以这样
<View className='complaintPickerViewItem' onClick={() => { this.pickerOnClick() }}>
   <Picker className='complaintViewTextPicker' value={selectorChecked} mode='multiSelector' range={mulSelector} onChange={this.onChangeComplaintType.bind(this)} onColumnChange={this.onColumnChange.bind(this)} >
    <AtList>
         <AtListItem
             title=''
             extraText={selectorChecked}
          />
    </AtList>
 </Picker>         
</View>

  pickerOnClick() {
    // 设置了多次,由于不知道具体动画事件,所以写了很多个延时器,希望动画结束最早的执行,同样也要保证百分百触发
    setTimeout(() => {
      Taro.hideKeyboard() //收起键盘
    }, 100)
    setTimeout(() => {
      Taro.hideKeyboard()
    }, 200)
    setTimeout(() => {
      Taro.hideKeyboard()
    }, 300)
    setTimeout(() => {
      Taro.hideKeyboard()
    }, 400)
    setTimeout(() => {
      Taro.hideKeyboard()
    }, 900)
  }

⚠️ 点击事件加载picker上无效哦,因为picker组件文档上并没有说支持点击事件,实践验证后确实是不行,所以我们在外边包一层再加click事件就行啦‘

这种也会有一点不完美,就是会有一个肉眼可见的picker选择器先彻底弹出再收起软键盘的过程,大概零点几秒吧,经测试老大对这个效果不是很满意,让我再想想,于是
👇

  • 方案二
    通过控制picker的显隐避免重叠情况的发生

这里我只分享一下思路吧,就不上代码了,因为这个试过后老大还是觉得效果有点不好,我就改回方案一的做法了

首先进入表单页,设置一个控制picker显示的值为showPickerFlag=true
点击除picker以外的input showPickerFlag=false
再点击picker

setTimeout(() => {
	//伪代码
      showPickerFlag=true
    }, 100)

此时picker只是变为显示了,但是不会触发点击事件,这一次点击不会触发picker,但是相当于input的一个失焦操作,所以键盘肯定会收起
所以我们再点击一次
就会正常弹出picker选择框

这个方案的缺点也显而易见,就是需要点两次picker才会弹出选择框,但实际上我觉得还好,因为第一次点击就相当于收起input键盘的操作嘛,但是给否了,嗯。。。行吧


这个两种方案的效果,我不会传视频上去展示,不知道描述的清不清楚,总的来说肯定方案一好很多了,最近做这个表单啊发现iOS是真的很多坑啊,对比之下咱们安卓太乖了,代码咋写它咋执行,我爱安卓哈哈哈
溜~

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值