解决按钮问题与键盘弹出问题

This commit is contained in:
筱野
2026-02-07 23:37:28 +08:00
parent bfc6a149f0
commit e07f2ad2d1
4 changed files with 50 additions and 13 deletions

View File

@@ -1,7 +1,8 @@
import React, { useRef, useState } from 'react' import React, { useRef, useState, useEffect } from 'react'
import type { CSSProperties, ReactNode } from 'react' import type { CSSProperties, ReactNode } from 'react'
import { View, Text } from '@tarojs/components' import { View, Text } from '@tarojs/components'
import { Button } from '@nutui/nutui-react-taro' import { Button } from '@nutui/nutui-react-taro'
import { useKeyboardHeight } from '@/store/keyboardStore'
import styles from './index.module.scss' import styles from './index.module.scss'
export interface CustomPopupProps { export interface CustomPopupProps {
@@ -46,6 +47,24 @@ const CustomPopup: React.FC<CustomPopupProps> = ({
const [isDragging, setIsDragging] = useState(false) const [isDragging, setIsDragging] = useState(false)
const touchStartY = useRef(0) const touchStartY = useRef(0)
// 使用全局键盘状态
const { keyboardHeight, isKeyboardVisible, addListener, initializeKeyboardListener } = useKeyboardHeight()
// 使用全局键盘状态监听
useEffect(() => {
// 初始化全局键盘监听器
initializeKeyboardListener()
// 添加本地监听器
const removeListener = addListener((height, visible) => {
console.log('CustomPopup 收到键盘变化:', height, visible)
})
return () => {
removeListener()
}
}, [initializeKeyboardListener, addListener])
if (!visible) { if (!visible) {
return null return null
} }
@@ -99,6 +118,13 @@ const CustomPopup: React.FC<CustomPopupProps> = ({
onClose() onClose()
} }
// 阻止弹窗内的触摸事件冒泡
const handleTouchMoveInPopup = (e: any) => {
if (!isKeyboardVisible) {
e.stopPropagation()
}
}
return ( return (
<View <View
@@ -106,11 +132,12 @@ const CustomPopup: React.FC<CustomPopupProps> = ({
style={{ zIndex: zIndex ?? undefined, alignItems: overlayAlignItems }} style={{ zIndex: zIndex ?? undefined, alignItems: overlayAlignItems }}
onClick={handleOverlayClick} onClick={handleOverlayClick}
> >
<View className={styles['custom-popup-move']} catchMove></View> <View className={styles['custom-popup-move']} onTouchMove={handleTouchMoveInPopup} catchMove></View>
<View <View
className={`${styles['custom-popup']} ${className ? className : ''}`} className={`${styles['custom-popup']} ${className ? className : ''}`}
style={{ style={{
...style, ...style,
paddingBottom: isKeyboardVisible ? `${keyboardHeight}px` : undefined,
}} }}
onClick={(e) => { onClick={(e) => {
e.stopPropagation() e.stopPropagation()
@@ -152,7 +179,7 @@ const CustomPopup: React.FC<CustomPopupProps> = ({
<View className={styles['custom-popup__body']}>{children}</View> <View className={styles['custom-popup__body']}>{children}</View>
{!hideFooter && ( {!hideFooter && !isKeyboardVisible && (
<View className={styles['custom-popup__footer']}> <View className={styles['custom-popup__footer']}>
<Button <Button
className={`${styles['custom-popup__btn']} ${styles['custom-popup__btn-cancel']}`} className={`${styles['custom-popup__btn']} ${styles['custom-popup__btn-cancel']}`}

View File

@@ -7,7 +7,7 @@
right: 0; right: 0;
bottom: 0; bottom: 0;
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
z-index: 9999; z-index: 999;
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
justify-content: center; justify-content: center;
@@ -18,20 +18,20 @@
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
z-index: 9998; z-index: 998;
} }
.custom-popup { .custom-popup {
position: relative; position: relative;
z-index: 9999; z-index: 999;
width: 100%; width: 100%;
padding: 0; padding: 0;
box-sizing: border-box; box-sizing: border-box;
max-height: 80vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background-color: theme.$page-background-color; background-color: theme.$page-background-color;
border-radius: 20px 20px 0 0; border-radius: 20px 20px 0 0;
overflow: hidden; overflow: hidden;
transition: padding-bottom 0.3s ease;
.custom-popup__drag-handle-container { .custom-popup__drag-handle-container {
position: relative; position: relative;
height: 0; height: 0;
@@ -109,6 +109,8 @@
.custom-popup__body { .custom-popup__body {
flex: 1 1 auto; flex: 1 1 auto;
max-height: 80vh;
overflow-y: auto;
} }
.custom-popup__footer { .custom-popup__footer {

View File

@@ -79,6 +79,7 @@ const TextareaTag: React.FC<TextareaTagProps> = ({
autoHeight={true} autoHeight={true}
onFocus={onFocus} onFocus={onFocus}
onBlur={onBlur} onBlur={onBlur}
adjustPosition={false}
/> />
<View className={`char-count${isOverflow ? ' char-count--error' : ''}`}> <View className={`char-count${isOverflow ? ' char-count--error' : ''}`}>
{value.description.length}/{maxLength} {value.description.length}/{maxLength}

View File

@@ -70,7 +70,7 @@ const StadiumDetail = forwardRef<StadiumDetailRef, StadiumDetailProps>(({
stadium, stadium,
onAnyInput onAnyInput
}, ref) => { }, ref) => {
const [openPicker, setOpenPicker] = useState(false); const [openPicker, setOpenPicker] = useState(false); //为了解决上传图片时按钮样式问题
const [scrollTop, setScrollTop] = useState(0); const [scrollTop, setScrollTop] = useState(0);
const { getDictionaryValue } = useDictionaryActions() const { getDictionaryValue } = useDictionaryActions()
const court_type = getDictionaryValue('court_type') || [] const court_type = getDictionaryValue('court_type') || []
@@ -194,7 +194,7 @@ const StadiumDetail = forwardRef<StadiumDetailRef, StadiumDetailProps>(({
const changeTextarea = (value: boolean) => { const changeTextarea = (value: boolean) => {
if (value) { if (value) {
// 先滚动到底部 // 先滚动到底部
setScrollTop(scrollTop ? scrollTop + 15 : 9999); setScrollTop(140);
// 使用 setTimeout 确保滚动后再更新 openPicker // 使用 setTimeout 确保滚动后再更新 openPicker
} }
} }
@@ -206,18 +206,25 @@ const StadiumDetail = forwardRef<StadiumDetailRef, StadiumDetailProps>(({
} }
}, [isKeyboardVisible]) }, [isKeyboardVisible])
const changePicker = (value) => { const changePicker = (value:boolean) => {
setOpenPicker(value); setOpenPicker(value);
} }
console.log(stadium,'stadiumstadium'); console.log(stadium,'stadiumstadium');
// 计算滚动区域的最大高度
const scrollMaxHeight = isKeyboardVisible
? `calc(100vh - ${keyboardHeight+40}px)`
: '60vh'
return ( return (
<View className='stadium-detail'> <View className='stadium-detail'>
<ScrollView <ScrollView
className='stadium-detail-scroll' className='stadium-detail-scroll'
refresherBackground="#FAFAFA" refresherBackground="#FAFAFA"
scrollY scrollY={!openPicker}
scrollTop={scrollTop} scrollTop={scrollTop}
style={{ maxHeight: scrollMaxHeight }}
> >
{/* 已选球场 */} {/* 已选球场 */}
<View <View
@@ -262,11 +269,11 @@ const StadiumDetail = forwardRef<StadiumDetailRef, StadiumDetailProps>(({
<TextareaTag <TextareaTag
value={formData[item.prop]} value={formData[item.prop]}
onChange={(value) => { onChange={(value) => {
changeTextarea(true) //changeTextarea(true)
updateFormData(item.prop, value) updateFormData(item.prop, value)
}} }}
// onBlur={() => changeTextarea(false)} // onBlur={() => changeTextarea(false)}
//onFocus={() => changeTextarea(true)} onFocus={() => changeTextarea(true)}
placeholder='有其他场地信息可备注' placeholder='有其他场地信息可备注'
options={(item.options || []).map((o) => ({ label: o, value: o }))} options={(item.options || []).map((o) => ({ label: o, value: o }))}
/> />