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() } }
修复说明
- 布局调整:移除
VStack的固定高度限制,增加行间距和内边距,确保所有行正常显示。 - 数据源修正:将
childTexts初始化为60个元素的数组,匹配6行10列的布局需求。 - 弹框优化:改用SwiftUI原生
.alert修饰符,避免UIKit兼容性问题,通过绑定变量管理输入值。 - UI优化:增大按钮尺寸并添加边框,提升交互体验和视觉清晰度。
内容的提问来源于stack exchange,提问作者Swink
相关产品推荐
相关产品推荐

