Reputation: 339
I'm making my app UI by code.
I usually use a constainer view(just UIView) to make hierarchy.
When I'm using container view, I feel like there is much better way than I using.
Below code is the way I write.
I make all view components as global variable.
And set them on initView()
let conditionContainerView:UIView = {
let view = UIView()
return view
}()
let conditionSubContainerView:UIView = {
let view = UIView()
return view
}()
let firstButton:UIButton = {
let btn = UIButton()
btn.titleLabel?.font = UIFont.systemFont(ofSize:14, weight: .bold)
return btn
}()
let secondButton:UIButton = {
let btn = UIButton()
btn.titleLabel?.font = UIFont.systemFont(ofSize:14, weight: .bold)
return btn
}()
let thirdButton:UIButton = {
let btn = UIButton()
btn.titleLabel?.font = UIFont.systemFont(ofSize:14, weight: .bold)
return btn
}()
func initView() {
view.backgroundColor = .white
view.addSubview(conditionContainerView)
conditionContainerView.addSubview(conditionSubContainerView)
conditionSubContainerView.addSubview(firstButton)
conditionSubContainerView.addSubview(secondButton)
conditionSubContainerView.addSubview(thirdButton)
view.addConstraintsWithFormat(format: "H:|[v0]|", views: conditionContainerView)
view.addConstraintsWithFormat(format: "V:|[v0(35)]", views: conditionContainerView)
conditionSubContainerView.addConstraintsWithFormat(format: "H:[v0(50)]-8-[v1(50)]-8-[v2(50)]", views: firstButton, secondButton, thirdButton)
conditionSubContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: firstButton)
conditionSubContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: secondButton)
conditionSubContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: thirdButton)
firstButton.setTitle("first", for: .normal)
secondButton.setTitle("second", for: .normal)
thirdButton.setTitle("third", for: .normal)
}
override func viewDidLoad() {
super.viewDidLoad()
initView()
}
The reason why I use this way is I can't figure out the way I can access subview of container view.
This is what I want to use.
let conditionContainerView:UIView = {
let view = UIView()
return view
}()
let conditionSubContainerView:UIView = {
let view = UIView()
let firstButton = UIButton()
firstButton.titleLabel?.font = UIFont.systemFont(ofSize:14, weight: .bold)
let secondButton = UIButton()
secondButton.titleLabel?.font = UIFont.systemFont(ofSize:14, weight: .bold)
let thirdButton = UIButton()
thirdButton.titleLabel?.font = UIFont.systemFont(ofSize:14, weight: .bold)
view.addSubview(firstButton)
view.addSubview(secondButton)
view.addSubview(thirdButton)
view.addConstraintsWithFormat(format: "H:[v0(50)]-8-[v1(50)]-8-[v2(50)]", views: firstButton, secondButton, thirdButton)
view.addConstraintsWithFormat(format: "V:|[v0]|", views: firstButton)
view.addConstraintsWithFormat(format: "V:|[v0]|", views: secondButton)
view.addConstraintsWithFormat(format: "V:|[v0]|", views: thirdButton)
return view
}()
func initView() {
view.backgroundColor = .white
view.addSubview(mapView)
view.addSubview(conditionContainerView)
conditionContainerView.addSubview(conditionSubContainerView)
view.addConstraintsWithFormat(format: "H:|[v0]|", views: conditionContainerView)
view.addConstraintsWithFormat(format: "V:|[v0(35)]", views: conditionContainerView)
conditionSubContainerView.firstButton.setTitle("first", for: .normal)
conditionSubContainerView.secondButton.setTitle("second", for: .normal)
conditionSubContainerView.thirdButton.setTitle("third", for: .normal)
}
override func viewDidLoad() {
super.viewDidLoad()
initView()
}
But I can't use the code
conditionSubContainerView.firstButton.setTitle("first", for: .normal)
This maybe SO easy question to someone. Maybe it's nothing. But I really want to know the better way to make the code clean and shorter.
Thank you for your advice.
Upvotes: 0
Views: 1001
Reputation: 507
You need to subclass from UIView
final class SomeView: UIView {
lazy var button: UIButton = {
return UIButton()
}()
}
Then in view controller:
class ViewController: UIViewController {
let containerView = SomeView()
override func loadView() {
view = containerView
}
}
and use containerView
instead of self.view
func videDidLoad() {
super.viewDidLoad()
containerView.button.setTitle("Test", for: .normal)
}
Upvotes: 1
Reputation: 1593
Solving this is totally based on your use-case:-
If you are planning to access these buttons from the view a lot, and you have a lot of buttons/elements to share, I'd recommend creating a custom UIView
and making these elements accessible to public
Else if this is a one-time process, just assign the titles for the buttons as soon as you instantiate them
Finally, just to answer your question, here's a not-so-efficient way to solve this (especially when you are dealing with a lot of subviews). Three buttons in your case is not that big of a deal. Assign tags to those buttons and filter them if you ultimately feel the need for it:-
let conditionSubContainerView:UIView = {
let view = UIView()
let firstButton = UIButton()
firstButton.tag = 1 // <- assign tags this way
firstButton.titleLabel?.font = UIFont.systemFont(ofSize:14, weight: .bold)
let secondButton = UIButton()
secondButton.tag = 2
secondButton.titleLabel?.font = UIFont.systemFont(ofSize:14, weight: .bold)
let thirdButton = UIButton()
thirdButton.tag = 3
thirdButton.titleLabel?.font = UIFont.systemFont(ofSize:14, weight: .bold)
view.addSubview(firstButton)
view.addSubview(secondButton)
view.addSubview(thirdButton)
return view
}()
and filter them using their tags that you assigned:-
if let yourButton = conditionSubContainerView.subviews.filter({$0.tag == 1}).first as? UIButton{
print("This works and you'll get your firstButton but have this as your last option")
}
Upvotes: 1