首页 > 解决方案 > 有没有办法在不重复代码的情况下在 for 循环中显示字符?

问题描述

我对学习 Swift 还是很陌生,并且有一个框架可以均匀地显示字母表。

我有 3 个 for 循环,其中字母 AX 显示在 4 行 6 列中,而 Y 和 Z 位于第 2-3 列的第 5 行(因此它居中)。然而,为了实现这一点,我不得不复制我的代码。有没有更好的方法来解决这个问题,所以我不必复制代码?

let allLetters = (65...90).map { Character(Unicode.Scalar($0)) }
    let width = 80
    let height = 80

    for row in 0..<4 {
        for col in 0..<6 {
            let letterButton = UIButton(type: .system)
                letterButton.titleLabel?.font = UIFont.systemFont(ofSize: 36)
                letterButton.addTarget(self, action: #selector(letterTapped), for: .touchUpInside)
            
            let frame = CGRect(x: col * width, y: row * height, width: width, height: height)
            letterButton.frame = frame
            
            buttonsView.addSubview(letterButton)
            letterButtons.append(letterButton)
        }
    }
   
        for col in 2..<4 {
            let letterButton = UIButton(type: .system)
                letterButton.titleLabel?.font = UIFont.systemFont(ofSize: 36)
                letterButton.addTarget(self, action: #selector(letterTapped), for: .touchUpInside)
           
            let frame = CGRect(x: col * width, y: 4 * height, width: width, height: height)
            letterButton.frame = frame
        
            buttonsView.addSubview(letterButton)
            letterButtons.append(letterButton)
    }
            
    for (index, button) in letterButtons.enumerated() {
        button.setTitle(String(allLetters[index]), for: .normal)
    }
}

标签: swift

解决方案


您可以简化和提高性能,删除两个这样的 for 循环:

let allLetters = (65...90).map { Character(Unicode.Scalar($0)) }
let width = 80
let height = 80

var letterIndex = 0
let lastRowIndex = 4
let defaultRowColumnRange = 0..<6
let lastRowColumnRange = 2..<4

for row in 0...lastRowIndex {
    let rangeForRow = row == lastRowIndex ? lastRowColumnRange : defaultRowColumnRange
    for col in rangeForRow {
        let letterButton = UIButton(type: .system)
        letterButton.titleLabel?.font = UIFont.systemFont(ofSize: 36)
        letterButton.addTarget(self, action: #selector(letterTapped), for: .touchUpInside)

        if allLetters.count > letterIndex {
            letterButton.setTitle(String(allLetters[letterIndex]), for: .normal)
            letterIndex += 1
        }
        
        let frame = CGRect(x: col * width, y: row * height, width: width, height: height)
        letterButton.frame = frame
        
        view.addSubview(letterButton)
        letterButtons.append(letterButton) // Might not be necessary anymore
    }
}

推荐阅读