iOS应用多输入框短信验证码自动填充问题求助
我们的应用基于Angular、Ionic、Cordova开发,验证码输入采用4个独立输入框实现。在Safari浏览器中打开时,iOS能从短信提取验证码,通过键盘的「来自信息」按钮可正确填充全部4个输入框。但打包成iOS应用后,键盘自动填充时,整段验证码只会填入第一个maxlength为1的输入框,仅首字符生效,其余为空。手动复制粘贴验证码到第一个输入框时,所有输入框能正常填充。推测打包后的应用与Safari触发的自动填充事件不同。测试单输入框验证码时,系统自动填充功能正常,请问如何解决iOS应用中多输入框验证码的键盘自动填充问题?
代码示例
<ng-container *ngFor="let code of form.controls | keyvalue; index as i"> <app-input [formControlName]="code.key" #codes color="dark" class="code-input" size="medium" [mask]="'9'" state="error" [showErrorElement]="false" [state]="isError ? 'error' : null" [inputForCode]="true" [enterkeyhint]="'go'" [inputmode]="'numeric'" [addClass]="'input-text'" [maxlength]="1" [dontShowDisabled]="true" autocomplete="one-time-code" (keyupEvent)="nextCode($event, i)" (clickEvent)="select(i)" (paste)="paste($event)" (input)="paste($event)" ></app-input> </ng-container>
针对iOS应用多输入框验证码自动填充的问题,可以从以下几个方向处理:
监听输入事件手动分发验证码字符
iOS打包应用的自动填充只会向第一个带autocomplete="one-time-code"的输入框注入完整验证码,但不会触发粘贴类的事件分发。可以在第一个输入框的input事件中捕获完整验证码,将每个字符分别赋值给对应输入框:// 假设form是包含code0-code3四个控件的FormGroup handleAutoFill(event: Event) { const inputElement = event.target as HTMLInputElement; const fullCode = inputElement.value; if (fullCode.length === 4) { this.form.get('code0')?.setValue(fullCode[0]); this.form.get('code1')?.setValue(fullCode[1]); this.form.get('code2')?.setValue(fullCode[2]); this.form.get('code3')?.setValue(fullCode[3]); // 自动聚焦到最后一个输入框 document.querySelectorAll('.code-input input')[3]?.focus(); } }模板中给第一个输入框绑定该事件:
<!-- 为第一个输入框添加自动填充处理事件 --> <app-input ... (input)="handleAutoFill($event)" ...></app-input>调整autocomplete属性范围
仅给第一个输入框设置autocomplete="one-time-code",其余输入框移除该属性,避免系统尝试填充多个输入框导致逻辑混乱。同时保留所有输入框的inputmode="numeric"和maxlength="1"配置。使用Cordova插件直接读取短信验证码
借助cordova-plugin-sms-retriever这类插件,直接监听短信内容并提取验证码,再自动填充到输入框。这种方式不受系统自动填充的限制,兼容性更稳定:// 初始化短信监听 SMSRetriever.startWatch().then(() => { document.addEventListener('onSMSArrive', (e: any) => { const smsBody = e.data.body; // 正则提取4位数字验证码 const codeMatch = smsBody.match(/\d{4}/); if (codeMatch) { const code = codeMatch[0]; this.form.get('code0')?.setValue(code[0]); this.form.get('code1')?.setValue(code[1]); this.form.get('code2')?.setValue(code[2]); this.form.get('code3')?.setValue(code[3]); } }); });优化焦点切换逻辑
自动填充完成后,确保焦点能正确移动到对应输入框,同时处理好输入框的选中状态,避免系统填充时出现焦点冲突问题。
内容的提问来源于stack exchange,提问作者Bessonniy

