uni-app iOS 18.x nvue开发页面 键盘唤起后收起页面未恢复
uni-app iOS 18.x nvue开发页面 键盘唤起后收起页面未恢复
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
Mac | 15.1.1 | HBuilderX |
bug描述:
nvue开发的页面 键盘收起页面没有恢复 ,使用开发工具 调试运行正常,打包离线使用页面没有恢复
示例代码:
<template>
<view class="container">
<!-- 触发按钮 -->
<button @click="showPopup" type="primary">显示输入弹窗</button>
<!-- 弹出层 -->
<uni-popup
ref="popup"
type="bottom"
:safe-area="true"
:mask-click="true"
@change="onPopupChange"
>
<view class="popup-content">
<text class="popup-title">请输入内容</text>
<input
class="input-box"
v-model="inputValue"
placeholder="请输入内容"
@confirm="handleConfirm"
:adjust-position="true"
@focus="onFocus"
@blur="onBlur"
:cursor-spacing="100"
:fixed="true"
/>
<view class="btn-group">
<button class="btn cancel" @click="handleClose">取消</button>
<button class="btn confirm" @click="handleConfirm">确定</button>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
export default {
pageStyle: {
androidSoftInputMode: 'adjustResize'
},
data() {
return {
inputValue: '',
isKeyboardShow: false
}
},
methods: {
showPopup() {
// 显示弹窗
this.$refs.popup.open('bottom')
},
handleClose() {
// 关闭弹窗
this.$refs.popup.close()
this.inputValue = ''
},
handleConfirm() {
// 处理确认事件
if (!this.inputValue.trim()) {
uni.showToast({
title: '请输入内容',
icon: 'none'
})
return
}
// TODO: 处理输入内容
console.log('输入内容:', this.inputValue)
this.handleClose()
},
onFocus() {
this.isKeyboardShow = true
},
onBlur() {
this.isKeyboardShow = false
},
onPopupChange(e) {
if (!e.show) {
// 弹窗关闭时清空输入
this.inputValue = ''
// 如果键盘还在显示,让输入框失去焦点
if (this.isKeyboardShow) {
uni.hideKeyboard()
}
}
}
},
onLoad() {
// 设置页面背景色,避免透明问题
// uni.setBackgroundColor({
// backgroundColor: '#ffffff'
// })
}
}
</script>
<style>
.container {
flex: 1;
position: relative;
align-items: center;
justify-content: center;
}
.popup-content {
background-color: #fff;
padding: 20px;
width: 750rpx;
border-radius: 16px 16px 0 0;
position: relative;
bottom: 0;
z-index: 999;
}
.popup-title {
font-size: 16px;
text-align: center;
margin-bottom: 20px;
}
.input-box {
border: 1px solid #eee;
height: 40px;
padding: 0 10px;
margin: 20px 0;
background-color: #fff;
position: relative;
border-radius: 4px;
}
.btn-group {
flex-direction: row;
justify-content: space-between;
margin-top: 20px;
}
.btn {
width: 240rpx;
height: 40px;
line-height: 40px;
text-align: center;
border-radius: 3px;
}
.cancel {
background-color: #f1f1f1;
color: #666;
}
.confirm {
background-color: #007AFF;
color: #fff;
}
</style>
操作步骤:
<template>
<view class="container">
<!-- 触发按钮 -->
<button @click="showPopup" type="primary">显示输入弹窗</button>
<!-- 弹出层 -->
<uni-popup
ref="popup"
type="bottom"
:safe-area="true"
:mask-click="true"
@change="onPopupChange"
>
<view class="popup-content">
<text class="popup-title">请输入内容</text>
<input
class="input-box"
v-model="inputValue"
placeholder="请输入内容"
@confirm="handleConfirm"
:adjust-position="true"
@focus="onFocus"
@blur="onBlur"
:cursor-spacing="100"
:fixed="true"
/>
<view class="btn-group">
<button class="btn cancel" @click="handleClose">取消</button>
<button class="btn confirm" @click="handleConfirm">确定</button>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
export default {
pageStyle: {
androidSoftInputMode: 'adjustResize'
},
data() {
return {
inputValue: '',
isKeyboardShow: false
}
},
methods: {
showPopup() {
// 显示弹窗
this.$refs.popup.open('bottom')
},
handleClose() {
// 关闭弹窗
this.$refs.popup.close()
this.inputValue = ''
},
handleConfirm() {
// 处理确认事件
if (!this.inputValue.trim()) {
uni.showToast({
title: '请输入内容',
icon: 'none'
})
return
}
// TODO: 处理输入内容
console.log('输入内容:', this.inputValue)
this.handleClose()
},
onFocus() {
this.isKeyboardShow = true
},
onBlur() {
this.isKeyboardShow = false
},
onPopupChange(e) {
if (!e.show) {
// 弹窗关闭时清空输入
this.inputValue = ''
// 如果键盘还在显示,让输入框失去焦点
if (this.isKeyboardShow) {
uni.hideKeyboard()
}
}
}
},
onLoad() {
// 设置页面背景色,避免透明问题
// uni.setBackgroundColor({
// backgroundColor: '#ffffff'
// })
}
}
</script>
<style>
.container {
flex: 1;
position: relative;
align-items: center;
justify-content: center;
}
.popup-content {
background-color: #fff;
padding: 20px;
width: 750rpx;
border-radius: 16px 16px 0 0;
position: relative;
bottom: 0;
z-index: 999;
}
.popup-title {
font-size: 16px;
text-align: center;
margin-bottom: 20px;
}
.input-box {
border: 1px solid #eee;
height: 40px;
padding: 0 10px;
margin: 20px 0;
background-color: #fff;
position: relative;
border-radius: 4px;
}
.btn-group {
flex-direction: row;
justify-content: space-between;
margin-top: 20px;
}
.btn {
width: 240rpx;
height: 40px;
line-height: 40px;
text-align: center;
border-radius: 3px;
}
.cancel {
background-color: #f1f1f1;
color: #666;
}
.confirm {
background-color: #007AFF;
color: #fff;
}
</style>
预期结果:
无
实际结果:
<template>
<view class="container">
<!-- 触发按钮 -->
<button @click="showPopup" type="primary">显示输入弹窗</button>
<!-- 弹出层 -->
<uni-popup
ref="popup"
type="bottom"
:safe-area="true"
:mask-click="true"
@change="onPopupChange"
>
<view class="popup-content">
<text class="popup-title">请输入内容</text>
<input
class="input-box"
v-model="inputValue"
placeholder="请输入内容"
@confirm="handleConfirm"
:adjust-position="true"
@focus="onFocus"
@blur="onBlur"
:cursor-spacing="100"
:fixed="true"
/>
<view class="btn-group">
<button class="btn cancel" @click="handleClose">取消</button>
<button class="btn confirm" @click="handleConfirm">确定</button>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
export default {
pageStyle: {
androidSoftInputMode: 'adjustResize'
},
data() {
return {
inputValue: '',
isKeyboardShow: false
}
},
methods: {
showPopup() {
// 显示弹窗
this.$refs.popup.open('bottom')
},
handleClose() {
// 关闭弹窗
this.$refs.popup.close()
this.inputValue = ''
},
handleConfirm() {
// 处理确认事件
if (!this.inputValue.trim()) {
uni.showToast({
title: '请输入内容',
icon: 'none'
})
return
}
// TODO: 处理输入内容
console.log('输入内容:', this.inputValue)
this.handleClose()
},
onFocus() {
this.isKeyboardShow = true
},
onBlur() {
this.isKeyboardShow = false
},
onPopupChange(e) {
if (!e.show) {
// 弹窗关闭时清空输入
this.inputValue = ''
// 如果键盘还在显示,让输入框失去焦点
if (this.isKeyboardShow) {
uni.hideKeyboard()
}
}
}
},
onLoad() {
// 设置页面背景色,避免透明问题
// uni.setBackgroundColor({
// backgroundColor: '#ffffff'
// })
}
}
</script>
<style>
.container {
flex: 1;
position: relative;
align-items: center;
justify-content: center;
}
.popup-content {
background-color: #fff;
padding: 20px;
width: 750rpx;
border-radius: 16px 16px 0 0;
position: relative;
bottom: 0;
z-index: 999;
}
.popup-title {
font-size: 16px;
text-align: center;
margin-bottom: 20px;
}
.input-box {
border: 1px solid #eee;
height: 40px;
padding: 0 10px;
margin: 20px 0;
background-color: #fff;
position: relative;
border-radius: 4px;
}
.btn-group {
flex-direction: row;
justify-content: space-between;
margin-top: 20px;
}
.btn {
width: 240rpx;
height: 40px;
line-height: 40px;
text-align: center;
border-radius: 3px;
}
.cancel {
background-color: #f1f1f1;
color: #666;
}
.confirm {
background-color: #007AFF;
color: #fff;
}
</style>
3 回复
nvue、weex已经不再维护。推荐使用uni-app x 的uvue,体验更好,或者改用vue的webview。
当然如果一定要修改nvue的问题,有一种办法是点论坛右上角的付费技术支持
已经使用其他办法解决了
在uni-app中使用nvue开发iOS 18.x版本的页面时,遇到键盘唤起后页面未能恢复原位的问题,通常是由于页面布局或键盘事件处理不当导致的。以下是一个可能的解决方案,通过监听键盘的弹出和收回事件,手动调整页面布局来确保页面能够恢复到正确的位置。
首先,确保你的nvue页面中已经正确设置了键盘相关的事件监听。在nvue中,你可以使用onKeyboardHeightChange
事件来监听键盘高度的变化,从而判断键盘是弹出还是收回。
以下是一个示例代码,展示了如何在nvue页面中处理键盘事件,以确保页面在键盘唤起和收回后能够正确恢复:
<template>
<div class="container">
<input type="text" placeholder="点击输入" @focus="onInputFocus" @blur="onInputBlur" />
<!-- 其他页面内容 -->
</div>
</template>
<script>
export default {
data() {
return {
keyboardHeight: 0, // 键盘高度
originalPaddingBottom: 0, // 原始页面底部内边距
};
},
methods: {
// 键盘高度变化时触发
onKeyboardHeightChange(e) {
this.keyboardHeight = e.detail.height;
this.adjustPageLayout();
},
// 输入框聚焦时触发
onInputFocus() {
// 保存原始页面底部内边距
this.originalPaddingBottom = parseInt(window.getComputedStyle(document.querySelector('.container')).paddingBottom, 10);
// 监听键盘高度变化
uni.onKeyboardHeightChange(this.onKeyboardHeightChange);
},
// 输入框失焦时触发
onInputBlur() {
// 恢复页面底部内边距
this.adjustPageLayout(true);
// 取消监听键盘高度变化
uni.offKeyboardHeightChange(this.onKeyboardHeightChange);
},
// 调整页面布局
adjustPageLayout(restore = false) {
const container = document.querySelector('.container');
if (restore) {
// 恢复原始布局
container.style.paddingBottom = `${this.originalPaddingBottom}px`;
} else {
// 根据键盘高度调整布局
container.style.paddingBottom = `${this.keyboardHeight + this.originalPaddingBottom}px`;
}
},
},
};
</script>
<style scoped>
.container {
padding: 20px;
box-sizing: border-box;
}
</style>
在这个示例中,我们使用了onKeyboardHeightChange
方法来监听键盘高度的变化,并在输入框聚焦和失焦时分别调整页面的底部内边距。当键盘弹出时,我们增加页面的底部内边距以留出空间;当键盘收回时,我们恢复原始的底部内边距。
请注意,这个解决方案是基于nvue的特定环境,并且可能需要根据你的具体页面布局和样式进行调整。