首页 > 解决方案 > Swift UIView 内存使用和处理许多子视图

问题描述

我正在制作一个单词搜索应用程序,我在其中显示一个 14x14 的大字母网格。现在,我使用自己的字母来显示每个字母UILabel

for _ in 0..<14 {
  for _ in 0..<14 {
    let letterLabel = UILabel()
    letterLabel.text = randomLetter()
    addSubview(letterLabel)
  }
}

但是,我想知道这样构造我的代码是否会更好:

let lettersLabel = UILabel()
for _ in 0..<14 {
  for _ in 0..<14 {
    letterLabel.text += randomLetter() + " "
  }
  letterLabel.text += "\n"
}
addSubview(letterLabel)

UILabel我的理论是,这将减少我的应用程序的内存占用,尽管我找不到任何关于每个将占用多少内存的文档。

但是,我想知道,后一种方法实际上可以为我节省多少内存?哪种方法是 iOS 开发中的标准/首选方法?或者,有没有我没有想到的第三种方法?

从性能的角度来看,我觉得后一种方法更好,但是在将字母均匀地分布在屏幕上并确定哪个字母被敲击时,会使代码变得非常复杂。

(注意:这个问题极大地简化了我的实际代码以突出问题区域)

标签: iosswift

解决方案


由于您想知道点击了哪个字母,我建议使用集合视图。这是一个示例实现:

private let reuseIdentifier = "Cell"

class CollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    //Here I am generating an array of 14*14 strings since I don't have access to the randomLetter() function
    let elements = (0..<(14 * 14)).map { String($0) }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Register cell classes
        self.collectionView!.register(CollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
    }

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return elements.count
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! CollectionViewCell
        cell.label = UILabel(frame: cell.bounds)
        cell.label.text = elements[indexPath.row] //In your case you would use: cell.label.text = randomLetter()
        cell.label.font = UIFont(name: "helvetica", size: 10)
        cell.label.textAlignment = .center
        cell.addSubview(cell.label)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let size = CGSize(width: self.view.frame.size.width/14, height: self.view.frame.size.width/14)
        return size
    }

    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let cell = collectionView.cellForItem(at: indexPath) as! CollectionViewCell
        print(String(describing: cell.label.text))
    }
}

CollectionViewCell定义UICollectionViewCell定义如下:

class CollectionViewCell: UICollectionViewCell {
    var label: UILabel!
}

推荐阅读