iOS Swift UIKit开发:如何在自定义UIView中复制带数字1234的蓝色盒子
核心问题
你现在代码的问题出在三个地方:
- 你用来展示蓝色框的
stackPipe、展示数字的lblTitleCompo都是全局唯一的实例属性,同一个UIView实例不能被重复添加到父视图上,你在循环里反复执行addSubview操作,只会把这个唯一的视图来回移动父视图,不会生成新的蓝色框,自然看不到多个复制的效果。 products是UIScrollView,你没有给它的内部子视图设置底部约束来撑开contentSize,就算你加了多个视图也会布局混乱、无法滚动。- 你的视图添加逻辑重复:init里执行了一次循环加视图,又调用
listSubviewsOfView再跑了一次循环,后面setupView里又单独加了一次stackPipe,逻辑完全冲突。
修复步骤
第一步:删除全局的stackPipe、lblTitleCompo实例属性,改成在循环里每次创建新实例
第二步:给循环里创建的每个蓝色框设置竖向约束,按顺序排列,最后一个蓝色框的底部约束到products的底部,撑开滚动视图的内容尺寸
第三步:清理重复的视图添加逻辑,只在setupView里执行一次生成多个蓝色框的逻辑
核心修改代码片段
// 首先删除原来的全局 stackPipe、lblTitleCompo 定义,以及init、listSubviewsOfView里的循环加视图逻辑 // 在setupView里添加以下逻辑: // 用来记录上一个蓝色框的底部,方便做竖向约束 var lastViewBottom: CGFloat = 25 let cardHeight: CGFloat = 100 let cardSpacing: CGFloat = 15 for index in 1...5 { // 每次循环创建新的蓝色框stackPipe let stackPipe = UIStackView().usingAutoLayout() stackPipe.axis = .vertical stackPipe.alignment = .fill stackPipe.isLayoutMarginsRelativeArrangement = true stackPipe.layoutMargins = UIEdgeInsets(top: 30, left: 15, bottom: 30, right: 15) stackPipe.roundedCornersAndShadow() stackPipe.backgroundColor = .newBlue // 每次循环创建新的数字label let lblTitleCompo = UILabel().usingAutoLayout() lblTitleCompo.textAlignment = .center lblTitleCompo.numberOfLines = 3 lblTitleCompo.adjustsFontSizeToFitWidth = true // 这里可以改成动态显示不同的数字,比如"\(index)234" lblTitleCompo.attributedText = "\(index)234".localized().book20(.slateGray) stackPipe.addArrangedSubview(lblTitleCompo) products.addSubview(stackPipe) // 给当前蓝色框加约束 constrain(stackPipe, lblTitleCompo) { stackPipe, lblTitleCompo in stackPipe.leading == products.leading + 10 stackPipe.trailing == products.trailing - 10 stackPipe.top == products.top + lastViewBottom stackPipe.height == cardHeight lblTitleCompo.top == stackPipe.top - 10 lblTitleCompo.leading == stackPipe.leading + 10 lblTitleCompo.trailing == stackPipe.trailing - 10 } // 更新lastViewBottom,下一个蓝色框排在当前的下面 lastViewBottom += cardHeight + cardSpacing // 把生成的控件存到全局数组里方便后续使用 buttons.append(lblTitleCompo) } // 最后加约束撑开products的contentSize,要在循环结束后执行 constrain(products) { products in products.bottomAnchor.constraint(equalTo: products.subviews.last!.bottomAnchor, constant: 25).isActive = true }
内容的提问来源于stack exchange,提问作者Zac Mazk
相关产品推荐
相关产品推荐

