You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何为每行添加独立字母?仅首字母显示问题解决

问题修复方案

核心问题分析

  • 布局高度被限制:VStack 设置了固定高度 20,6行内容被严重挤压,仅第一行可见,这是只有首字母显示的直接原因。
  • 数据源长度不足:childTexts 初始长度仅为10,但6行10列需要60个元素,后续行的索引计算会超出数组范围,无法正确渲染按钮。
  • 初始化逻辑冗余:CustomViewModel 的 init 方法中,基于 fretSelected(初始为false)的循环赋值完全可以在数组初始化时直接完成,无需额外循环。
  • 弹框方式不规范:通过 UIApplication.shared.windows.first 弹框的方式在iOS15+版本兼容性差,建议使用SwiftUI原生的 .alert 修饰符。

修复后的完整代码

import SwiftUI

struct CustomParent: View {
    @StateObject var customViewModel = CustomViewModel()
    @State private var showAlert = false
    @State private var currentAlertIndex = 0
    
    let rowTexts = ["E", "A", "D", "G", "B", "E"] // 每行对应的字母
    
    var body: some View {
        VStack(spacing: 10) { // 增加行间距提升可读性
            ForEach(0..<6, id: \.self) { rowIndex in
                HStack(spacing: 10) {
                    Text(rowTexts[rowIndex])
                        .font(.headline)
                    
                    ForEach(0..<10, id: \.self) { columnIndex in
                        let index = rowIndex * 10 + columnIndex
                        CustomChild(index: index, customViewModel: customViewModel) {
                            currentAlertIndex = index
                            showAlert = true
                        }
                    }
                }
            }
        }
        .padding()
        .alert("Enter a number", isPresented: $showAlert) {
            TextField("", value: $customViewModel.inputNumber, formatter: NumberFormatter())
                .keyboardType(.numberPad)
            
            Button("Done") {
                if let number = customViewModel.inputNumber {
                    customViewModel.childTexts[currentAlertIndex] = String(number)
                    customViewModel.inputNumber = nil
                }
            }
            Button("Cancel", role: .cancel) {
                customViewModel.inputNumber = nil
            }
        }
    }
}

struct CustomChild: View {
    let index: Int
    @ObservedObject var customViewModel: CustomViewModel
    let onTap: () -> Void
    
    var body: some View {
        Button(action: onTap) {
            Text(customViewModel.childTexts[index])
                .frame(width: 25, height: 25) // 增大按钮尺寸,方便点击
                .border(.black) // 添加边框明确按钮范围
                .foregroundColor(.black)
        }
    }
}

class CustomViewModel: ObservableObject {
    @Published var childTexts = [String](repeating: "__", count: 60) // 匹配6行10列的元素数量
    @Published var inputNumber: Int? // 绑定弹框输入值
    
    func buttonPushed(at index: Int) {
        // 可添加按钮点击后的额外逻辑
    }
}

struct CustomParent_Previews: PreviewProvider {
    static var previews: some View {
        CustomParent()
    }
}

修复说明

  1. 布局调整:移除VStack的固定高度限制,增加行间距和内边距,确保所有行正常显示。
  2. 数据源修正:将childTexts初始化为60个元素的数组,匹配6行10列的布局需求。
  3. 弹框优化:改用SwiftUI原生.alert修饰符,避免UIKit兼容性问题,通过绑定变量管理输入值。
  4. UI优化:增大按钮尺寸并添加边框,提升交互体验和视觉清晰度。

内容的提问来源于stack exchange,提问作者Swink

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:07:54