I'm trying to implement a dynamic view composed UI elements sent by the backend, meaning it is not known beforehand how many and which UI elements will be displayed, the server sends JSON containing the types of fields that need to be rendered.
So for example the sever sends:
- type: paragraph
- type: textfield
Then I instantiate a class I have for each of those elements and add their views as subviews to my main dynamic view:
class DynamicViewController: UIViewController {
// array of subviews, textfield is one element in this array (-> textfield not editable)
var subViews: [UIView] = []
override func viewDidLoad() {
super.viewDidLoad()
getFields(completion: { result in
for (index, element) in result!.form.enumerated() {
let initializedClass = element.getClass()
self.subViews.append(initializedClass.view)
self.addChild(initializedClass)
self.view.addSubview(self.subViews[index])
initializedClass.didMove(toParent: self)
}
})
}
}
The problem I am getting with the "textfield" element, is that the textfield doesn't seem to be editable, tapping on it does nothing.
However, when I change the code to assign the initializedClass.view
to a specific variable, it does work:
class DynamicViewController: UIViewController {
// variable specifically for the textfield's view (-> textfield is editable)
var textfieldView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
getFields(completion: { result in
for (index, element) in result!.form.enumerated() {
if (index == 0) {
let initializedClass = element.getClass()
let initializedView = initializedClass.view
self.textfieldView = initializedClass.view
self.addChild(initializedClass)
self.view.addSubview(initializedView!)
}
}
})
}
}
This second implementation works then (the picker does open), which I got from UIPickerView delegate not called in a subview.
My question is why this is happening and how I can make this work without having to declare static variables for each element, but rather work with an array or some collection that keep references to the elements.
The TextField:
class CustomTextField: UIViewController {
private let labelElement = UILabel(frame: CGRect(x: 20, y: 150, width: 350, height: 20))
private let textfieldElement = UITextField(frame: CGRect(x: 20, y: 200, width: 350, height: 40))
init(label: String) {
self.labelElement.text = label
textfieldElement.borderStyle = UITextField.BorderStyle.roundedRect
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(labelElement)
view.addSubview(textfieldElement)
}
}
question from:
https://stackoverflow.com/questions/65882928/keeping-strong-references-with-dynamic-subviews-in-swift 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…