如何在Swift中向单独的行添加字母

huangapple go评论72阅读模式
英文:

How to add letters to an individual row in Swift

问题

I've translated the code portion as requested. Here it is:

struct CustomParent: View {
    @StateObject var customViewModel = CustomViewModel()
    
    let columnTexts = ["E", "A", "D", "G", "B", "E"] // << array
    var body: some View {
        VStack {
           
            ForEach(0..<6, id: \.self) { rowIndex in
           
                HStack(spacing: 10) {
                    Text(columnTexts[rowIndex])
                    ForEach(0..<10, id: \.self) { columnIndex in
                        let index = rowIndex * 10 + columnIndex
                        
                        if index < customViewModel.childTexts.count {
                            CustomChild(index: index, customViewModel: customViewModel)
                        } else {
                            Spacer()
                               
                        }
                    }
                }
            }
        }
        .frame(height: 20)
    }
}

struct CustomChild: View {
    let index: Int
    @ObservedObject var customViewModel: CustomViewModel
    
    var body: some View {
        Button(action: {
            customViewModel.showNumberInputAlert(for: index)
            
            customViewModel.buttonPushed(at: index)
        }) {
           
            Text(customViewModel.childTexts[index])
                .frame(width: 20, height: 2)
                .foregroundColor(.black)
        }
    }
}

class CustomViewModel: ObservableObject {
    
    @Published var childTexts = [String](repeating: "", count: 10)
    @Published var fretSelected = false
    
    func showNumberInputAlert(for rowIndex: Int) {
        let alert = UIAlertController(title: "Enter a number", message: nil, preferredStyle: .alert)
        alert.addTextField { textField in
            textField.keyboardType = .numberPad
        }
        
        let doneAction = UIAlertAction(title: "Done", style: .default) { _ in
            if let text = alert.textFields?.first?.text, let number = Int(text) {
               // Make changes here to text
                self.fretSelected = true
                self.childTexts[rowIndex] = String(number)
            }
        }
        alert.addAction(doneAction)
        
        UIApplication.shared.windows.first?.rootViewController?.present(alert, animated: true, completion: nil)
    }
    
    
    init() {
        for i in 0..<childTexts.count {
            if fretSelected {
                childTexts[i]
            }
            else{
                childTexts[i] = "__"
            }
           
        }
    }
}

Please note that I've replaced the HTML-encoded characters (e.g., &quot;) with their actual representations in the code.

英文:

I'm attempting to create 6 rows of 10 columns, with a individual letter attached to each row. In my particular case I want the first letter for the array to display, then the next and so on. As of now, only the first letter displays.

I'm not sure how to increment the column texts in the view itself to display a new letter for each row.

I attached an image below of the issue of what currently is happening.

struct CustomParent: View {
@StateObject var customViewModel = CustomViewModel()
let columnTexts = [&quot;E&quot;, &quot;A&quot;, &quot;D&quot;, &quot;G&quot;, &quot;B&quot;, &quot;E&quot;] // &lt;&lt; array
var body: some View {
VStack {
ForEach(0..&lt;6, id: \.self) { rowIndex in
HStack(spacing: 10) {
Text(columnTexts[rowIndex])
ForEach(0..&lt;10, id: \.self) { columnIndex in
let index = rowIndex * 10 + columnIndex
if index &lt; customViewModel.childTexts.count {
CustomChild(index: index, customViewModel: customViewModel)
} else {
Spacer()
}
}
}
}
}
.frame(height: 20)
}
}
struct CustomChild: View {
let index: Int
@ObservedObject var customViewModel: CustomViewModel
var body: some View {
Button(action: {
customViewModel.showNumberInputAlert(for: index)
customViewModel.buttonPushed(at: index)
}) {
Text(customViewModel.childTexts[index])
.frame(width: 20, height: 2)
.foregroundColor(.black)
// .border(.black)
}
}
}
class CustomViewModel: ObservableObject {
@Published var childTexts = [String](repeating: &quot;&quot;, count: 10)
@Published var fretSelected = false
func showNumberInputAlert(for rowIndex: Int) {
let alert = UIAlertController(title: &quot;Enter a number&quot;, message: nil, preferredStyle: .alert)
alert.addTextField { textField in
textField.keyboardType = .numberPad
}
let doneAction = UIAlertAction(title: &quot;Done&quot;, style: .default) { _ in
if let text = alert.textFields?.first?.text, let number = Int(text) {
// Make changes here to text
self.fretSelected = true
self.childTexts[rowIndex] = String(number)
}
}
alert.addAction(doneAction)
UIApplication.shared.windows.first?.rootViewController?.present(alert, animated: true, completion: nil)
}
init() {
for i in 0..&lt;childTexts.count {
if fretSelected {
childTexts[i]
}
else{
childTexts[i] = &quot;__&quot;
}
}
}

如何在Swift中向单独的行添加字母

答案1

得分: 1

Here is the translated code:

一件事情:
let index = rowIndex * 10 + columnIndex
if index < customViewModel.childTexts.count {
    CustomChild(index: index, customViewModel: customViewModel)
} else {
    Spacer()
}

如果我理解代码正确,我们将无法显示第二行的自定义子项,因为索引将高于childTexts.count,您确定您发布的代码与屏幕一致吗?

第二件事,它会崩溃,因为您将“index”传递给childView,但在childView中引用了一个包含10个元素的数组

//在CustomChild中:
Text(customViewModel.childTexts[index]) //第二行将给出索引20,导致越界

使用一个函数来保留“index”的最后一个数字将非常有用,以避免越界并在childView中保留真正的索引 https://stackoverflow.com/questions/30415937/how-to-split-an-int-to-its-individual-digits

第三,在您发布的代码上进行了微小的修复后,我得到了您正在寻找的显示效果。

//请用以下内容替换
if index < customViewModel.childTexts.count {
//与
if columnIndex < customViewModel.childTexts.count {

//在CustomChild中
Text(customViewModel.childTexts[index])
//与
Text(customViewModel.childTexts[index.lastDigit]) //lastDigit将是我上面链接的StackOverflow资源中的一个函数

对于lastDigit函数,像这样的东西应该可以胜任:
```swift
extension Int {
    var lastDigit: Int {
        String(self).last!.wholeNumberValue!
    }
}

用法:

let index = 156
print(index.lastDigit) //应该打印6
print(-4577.lastDigit) //应该打印-7
print(abs(-88).lastDigit) //应该打印8

注意:我强制解包,因为函数lastwholeNumberValue在非可选Int上不能失败(如果您想使用可选Int进行操作,我会让您添加一些nil检查)。


<details>
<summary>英文:</summary>
one thing : 

let index = rowIndex * 10 + columnIndex
if index < customViewModel.childTexts.count {
CustomChild(index: index, customViewModel: customViewModel)
} else {
Spacer()

If I understand the code well we would not be able to display the customs childs of the second row as the index would be higher that the childTexts.count, are you sure the code you posted is accurate with the screen you posted?
Second thing, it would crash as you are giving &quot;index&quot; to childView but in the childView you are referencing an array of 10 elements 

//In CustomChild:
Text(customViewModel.childTexts[index]) //second row would give index 20 that cause outOfRange

Using a function to keep only the last digit of the &quot;index&quot; would be useful to avoid outOfRange and keep the real index in your childView https://stackoverflow.com/questions/30415937/how-to-split-an-int-to-its-individual-digits
Third, after a minor fix on the code you posted I have the display you&#39;re seeking for.

// Please replace
if index < customViewModel.childTexts.count {
//with
if columnIndex < customViewModel.childTexts.count {

//In CustomChild
Text(customViewModel.childTexts[index])
//with
Text(customViewModel.childTexts[index.lastDigit]) //lastDigit would be a function from the StackOverlow resource I linked above

The edits I stated above are the only one I made to your code for it to obtain the result I&#39;ll post under:
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/IpXNv.png
EDIT: Something like this should do the job for the lastDigit function

extension Int {
var lastDigit: Int {
String(self).last!.wholeNumberValue!
}
}

usage: 

let index = 156
print(index.lastDigit) // should print 6
print(-4577.lastDigit) // should print -7
print(abs(-88).lastDigit) // should print 8

Note: I force unwrap as the functions `last` and `wholeNumberValue` cannot fail on a non-optionnal Int (if you want to work with optional Int I let you add some nil checking.)
</details>

huangapple
  • 本文由 发表于 2023年6月30日 03:28:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76584099.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定