From cd2401242c69039b3bc2b6796818c4e40c91657e Mon Sep 17 00:00:00 2001 From: laoyang Date: Fri, 9 Oct 2026 22:41:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E9=A1=B5=E6=8C=82=E4=BA=86=E4=B8=A4=E4=B8=AA=20bindSheet=20?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E6=97=B6=E9=97=B4=E9=80=89=E6=8B=A9=E6=A1=86?= =?UTF-8?q?=E5=BC=B9=E4=B8=8D=E5=87=BA=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 症状(用户反馈,本轮改动引入的回归):编辑/新建日程时点开始或结束时间, 白框一闪而过、日期时间选择器不出现。 根因:ArkUI 同一组件**只支持一个 bindSheet**,后挂的会覆盖先挂的。 上一轮新增"重复日程范围选择"弹层时,在同一根容器上挂了第二个 bindSheet, 于是它把原有的"时间选择"弹层顶掉了 —— 表现正是白框一闪即消失。 修法:合并为**唯一**一个 bindSheet,用 sheetMode 区分内容: - sheetMode='picker' → 日期/时间选择(高度 380) - sheetMode='scope' → 重复日程范围选择(高度 320) 新增 bottomSheet() builder 按模式分发;原 pickerShow/scopeConfirmShow 两个状态合并为 sheetShow + sheetMode。 --- entry/src/main/ets/pages/EventEditPage.ets | 50 +++++++++++++++------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/entry/src/main/ets/pages/EventEditPage.ets b/entry/src/main/ets/pages/EventEditPage.ets index b0a68bb..86fce83 100644 --- a/entry/src/main/ets/pages/EventEditPage.ets +++ b/entry/src/main/ets/pages/EventEditPage.ets @@ -45,14 +45,22 @@ struct EventEditPage { @State isExisting: boolean = false; @State repeatMode: string = 'none'; // none|daily|workday|weekly|monthly|yearly|custom @State reminderList: number[] = []; // 提前提醒分钟数(多选),空 = 不提醒 - @State pickerShow: boolean = false; // 开始/结束时间选择底部弹层(日期+时间一次选完) + /** + * ⭐ 底部弹层:**整个页面只能挂一个 `bindSheet`**。 + * ArkUI 里同一组件挂多个 bindSheet 时,后一个会覆盖前一个 —— 实测表现就是 + * "时间选择框白框一闪而过、什么都没出来"(范围弹层把时间弹层顶掉了)。 + * 因此这里用一个状态 + 一个模式来复用同一个弹层: + * sheetMode = 'picker' → 日期/时间选择 + * sheetMode = 'scope' → 重复日程范围选择 + */ + @State sheetShow: boolean = false; + @State sheetMode: string = 'picker'; @State pickerIsEnd: boolean = false; @State pickDate: Date = new Date(); @State pickHour: number = 9; @State pickMin: number = 0; /** ⭐ 重复日程编辑范围:'one' 仅此次 / 'future' 此次及以后 / 'all' 全部 */ @State scope: string = 'all'; - @State scopeConfirmShow: boolean = false; // 保存重复日程时的范围选择弹层 private pendingDelete: boolean = false; // 该弹层是"保存"还是"删除"流程 /** * ⭐ 载入时的**原始行快照**(不可变)。 @@ -254,7 +262,8 @@ struct EventEditPage { this.pickDate = new Date(base.getFullYear(), base.getMonth(), base.getDate()); this.pickHour = base.getHours(); this.pickMin = base.getMinutes(); - this.pickerShow = true; + this.sheetMode = 'picker'; + this.sheetShow = true; } private applyPicker(): void { @@ -499,7 +508,8 @@ struct EventEditPage { // 永远等不到范围选择弹层(表现为"编辑重复日程没有那三个选项")。 if (this.isSeriesOccurrence()) { this.pendingDelete = false; - this.scopeConfirmShow = true; + this.sheetMode = 'scope'; + this.sheetShow = true; LogUtil.write('保存判定:重复系列 → 弹出范围选择'); return; } @@ -641,7 +651,8 @@ struct EventEditPage { // ⭐ 重复日程:先让用户选择"删这一次 / 此次及以后 / 全部" if (this.isSeriesOccurrence()) { this.pendingDelete = true; - this.scopeConfirmShow = true; + this.sheetMode = 'scope'; + this.sheetShow = true; return; } const label: string = this.title.trim() === '' ? '该日程' : `「${this.title.trim()}」`; @@ -987,20 +998,27 @@ struct EventEditPage { .backgroundColor($r('app.color.page_bg')) // 沉浸式:背景延伸到状态栏/导航条区域(只扩绘制、不移动子组件) .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) - .bindSheet($$this.pickerShow, this.dateTimePickerSheet(), { - height: 380, - showClose: false, - dragBar: true, - backgroundColor: $r('app.color.card_bg') - }) - .bindSheet($$this.scopeConfirmShow, this.scopeSheet(), { - height: 300, + // ⚠️ 整个页面**只允许一个 bindSheet**:挂两个时后者会覆盖前者, + // 表现为"时间选择框白框一闪而过"(范围弹层顶掉了它)。 + // 这里用 sheetMode 在同一个弹层里切换内容。 + .bindSheet($$this.sheetShow, this.bottomSheet(), { + height: this.sheetMode === 'scope' ? 320 : 380, showClose: false, dragBar: true, backgroundColor: $r('app.color.card_bg') }) } + /** ⭐ 唯一的底部弹层:按 sheetMode 切换显示"时间选择"或"重复范围选择" */ + @Builder + bottomSheet() { + if (this.sheetMode === 'scope') { + this.scopeSheet() + } else { + this.dateTimePickerSheet() + } + } + /** ⭐ 重复日程"作用范围"选择弹层:保存/删除前让用户明确改哪几次 */ @Builder scopeSheet() { @@ -1031,7 +1049,7 @@ struct EventEditPage { .textAlign(TextAlign.Center) .padding({ top: 12, bottom: 16 }) .onClick(() => { - this.scopeConfirmShow = false; + this.sheetShow = false; }) } .width('100%') @@ -1058,7 +1076,7 @@ struct EventEditPage { .borderRadius(12) .backgroundColor($r('app.color.chip_off_bg')) .onClick(() => { - this.scopeConfirmShow = false; + this.sheetShow = false; if (this.pendingDelete) { this.removeEvent(mode); } else { @@ -1216,7 +1234,7 @@ struct EventEditPage { .backgroundColor($r('app.color.brand')) .onClick(() => { this.applyPicker(); - this.pickerShow = false; + this.sheetShow = false; }) } .width('100%')