Swift:如何基于对象数组复用已有UIView动态添加至UIStackView?
解决方法:基于模板视图生成多份实例并填充数据
问题原因
你当前的代码存在两个核心问题:
- 同一个
companyShow视图实例不能被多次添加到栈视图中,UIKit规则是一个视图只能属于一个父视图,重复添加只会保留最后一次的操作结果。 - 你修改的是同一个
companyName标签的文本,循环结束后自然只会显示最后一个公司的名称。
解决方案1:视图拷贝+Tag查找标签
将Storyboard中的companyShow作为模板,通过拷贝生成新视图,再通过Tag定位标签填充数据:
- 先给UIView添加拷贝扩展:
extension UIView { func copyView() -> UIView? { guard let archivedData = try? NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false), let copiedView = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(archivedData) as? UIView else { return nil } copiedView.frame = self.frame return copiedView } }
- 修改控制器
viewDidLoad代码:
override func viewDidLoad() { super.viewDidLoad() let companies = [ Company(owner: "jan"), Company(owner: "henk"), ] // 移除模板视图,避免显示原控件 companyShow.removeFromSuperview() for company in companies { // 拷贝模板视图 guard let companyViewCopy = companyShow.copyView() else { continue } // 通过Tag获取副本内的标签(需提前在Storyboard给companyName设置Tag,比如100) if let nameLabel = companyViewCopy.viewWithTag(100) as? UILabel { nameLabel.text = company.owner } // 添加到栈视图 allCompaniesShow.addArrangedSubview(companyViewCopy) } }
注意:需要在Storyboard中选中
companyName标签,在Attributes Inspector里设置Tag值为100(或其他自定义数值)。
解决方案2:自定义UIView子类(推荐)
这种方式更规范,避免Tag冲突问题,也更易维护:
- 创建自定义视图类
CompanyView.swift:
import UIKit class CompanyView: UIView { @IBOutlet weak var companyName: UILabel! // 加载自定义视图的类方法 static func instantiate() -> CompanyView { let nib = UINib(nibName: "CompanyView", bundle: nil) return nib.instantiate(withOwner: nil, options: nil).first as! CompanyView } }
- 在Storyboard中配置模板视图:
- 选中
companyShow视图,在Identity Inspector中将Class改为CompanyView。 - 确保
companyName标签已经和CompanyView中的IBOutlet关联。
- 修改控制器
viewDidLoad代码:
override func viewDidLoad() { super.viewDidLoad() let companies = [ Company(owner: "jan"), Company(owner: "henk"), ] // 隐藏原模板视图 companyShow.isHidden = true for company in companies { let companyView = CompanyView.instantiate() companyView.companyName.text = company.owner allCompaniesShow.addArrangedSubview(companyView) } }
内容的提问来源于stack exchange,提问作者Moemen Hussein
相关产品推荐
相关产品推荐

