如何解决有没有办法在不删除视图并重新添加它的情况下更新 StackView 中的视图?
我有使用自动布局的视图。我知道我希望每个视图的确切宽度(每个宽度都不同)。 StackView 嵌套在集合视图中。堆栈视图中的视图是从主视图控制器动态加载的。我想在集合视图重新加载时更新堆栈视图视图而不删除视图并再次添加它们。我无法删除视图并重新添加它们,因为某些视图具有文本字段,如果重新加载会关闭键盘。我已经解释了下面的代码
感谢您的帮助。
编辑
这是我要找的布局。
我使用 Carbon 将视图渲染到集合视图中:
private func render() {
renderer.render {
Section(
id: "testing row collection",cells: {
Row(id: "row id",data: [
Input(
id: 6,props: InputContent.State(
text: self.state.inputText,placeholder: "Search",size: .medium
),onChange: { [weak self] text in
print("text is:",text)
self?.state.inputText = text
}
)
])
}
)
}
}
注意:图像和代码与实现不匹配。图片显示了3个视图,代码只显示了1个。
类 Row
是呈现包含 UIStackView 的视图的类。在里面我有一个视图列表,目前只有 1 个视图。它将 text
设置为 self.state.inputText
,这是视图控制器中的一个变量。然后在文本字段中发生任何变化时,我将 self.state.inputText
设置为该文本。设置变量 state
后,运行 render()
。
Row
类:
这个类渲染实际的 UIView,它被称为 RowContent
。它调用 updateState(state:)
类中显示的 RowContent
方法。这在集合视图呈现时调用
RowContent
类:
class RowContent: UIView {
var stack: UIStackView
var state: State
struct State {
var views: [UIView] = [UIView]()
}
public func updateState(_ state: State? = nil) {
self.state = state ?? self.state
//updateView()
}
required init(state: State) {
self.state = state
self.stack = UIStackView(arrangedSubviews: state.views)
super.init(frame: .zero)
self.setupStackView()
}
...
}
堆栈视图在初始化程序中填充了视图,然后我在 setupStackview()
目前,当集合视图重新呈现时,视图永远不会更新,这意味着 Input 中的文本属性永远不会更新。我想在集合视图重新呈现时更新视图。这将在被注释掉的 updateView()
方法中。我不知道如何在不删除视图并重新添加它们的情况下更新 collectionView 中的视图。
谢谢。
我在这里添加了一个示例:https://github.com/4ndrewHarri5/ExampleRow
解决方法
试试这个...
我们从一个标签“基础”视图类开始——它将为标签视图设置背景颜色和圆角:
// background and rounded corners
class TagBaseView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
layer.cornerRadius = 12
layer.masksToBounds = true
backgroundColor = UIColor(red: 0.96,green: 0.95,blue: 0.97,alpha: 1.0)
}
}
子类 TagBaseView
,添加一个 UILabel
:
class TagLabelView: TagBaseView {
let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
override func commonInit() -> Void {
super.commonInit()
label.font = .boldSystemFont(ofSize: 18.0)
label.numberOfLines = 0
addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
label.topAnchor.constraint(equalTo: topAnchor,constant: 8.0),label.leadingAnchor.constraint(equalTo: leadingAnchor,label.trailingAnchor.constraint(equalTo: trailingAnchor,constant: -8.0),label.bottomAnchor.constraint(equalTo: bottomAnchor,])
}
}
子类 TagBaseView
,添加一个 UITextField
:
class TagFieldView: TagBaseView {
let field = UITextField()
var textChangeCallback: ((String)->())?
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
override func commonInit() -> Void {
super.commonInit()
field.font = .boldSystemFont(ofSize: 18.0)
addSubview(field)
field.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
// constrain text field Leading / Trailing
field.leadingAnchor.constraint(equalTo: leadingAnchor,field.trailingAnchor.constraint(equalTo: trailingAnchor,// center it vertically
field.centerYAnchor.constraint(equalTo: centerYAnchor),// require at least 8-pts Top and Bottom
field.topAnchor.constraint(greaterThanOrEqualTo: topAnchor,field.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor,])
field.addTarget(self,action: #selector(self.textDidChange(_:)),for: .editingChanged)
}
@objc func textDidChange(_ textField: UITextField) -> Void {
guard let s = textField.text else {
return
}
// tell the controller the text changed
textChangeCallback?(s)
}
}
视图控制器类 - 创建一个水平堆栈视图,具有 TagLabelView
“左”视图、TagLabelView
“中心”视图和 TagFieldView
“右”视图。>
当我们在“右”视图中编辑文本字段时,它将使用一个闭包“回调”到我们处理文本更改并更新左视图和中心视图的控制器:
class EditStackViewController: UIViewController {
let stack: UIStackView = {
let v = UIStackView()
v.spacing = 8
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
let leftView = TagLabelView()
let centerView = TagLabelView()
let rightView = TagFieldView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(stack)
stack.addArrangedSubview(leftView)
stack.addArrangedSubview(centerView)
stack.addArrangedSubview(rightView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// constrain stack view Top / Leading / Trailing
// (no Bottom or Height)
stack.topAnchor.constraint(equalTo: g.topAnchor,constant: 20.0),stack.leadingAnchor.constraint(equalTo: g.leadingAnchor,stack.trailingAnchor.constraint(equalTo: g.trailingAnchor,// make "center" view 45% of the width
centerView.widthAnchor.constraint(equalTo: stack.widthAnchor,multiplier: 0.45),// make "right" view equal width to "left" view
rightView.widthAnchor.constraint(equalTo: leftView.widthAnchor),])
rightView.field.placeholder = "Search"
// TagSearchView tells us when the field is being edited
rightView.textChangeCallback = { [weak self] str in
guard let self = self else {
return
}
self.leftView.label.text = str
self.centerView.label.text = str
}
}
}
结果:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。