I am attempting to create a Swift-based UI programmatically that resembles the layout shown below
Below is my view hierarchy which I created using xib
. Now I'm attempting to achieve the same through programatically.
Below is the code which i'm attempting. Here JTACDayCell
is the child of UICollectionViewCell
FYI: JTACDayCell
belongs to JTAppleCalendar
library
class DateTableCell: JTACDayCell {
static let reuseID = "dateCell"
lazy var parentView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var selectedView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var dateLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
lazy var eventView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var separatorView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .lightGray
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
setUpAutoLayout()
parentView.addSubview(selectedView)
parentView.addSubview(dateLabel)
parentView.addSubview(eventView)
addSubview(parentView)
addSubview(separatorView)
}
required init?(coder: NSCoder) {
fatalError("init?(coder: NSCoder) has not been implemented")
}
private func setUpAutoLayout() {
NSLayoutConstraint.activate([
parentView.leftAnchor.constraint(equalTo: leftAnchor),
parentView.rightAnchor.constraint(equalTo: rightAnchor),
parentView.topAnchor.constraint(equalTo: topAnchor),
parentView.bottomAnchor.constraint(equalTo: separatorView.topAnchor),
selectedView.centerXAnchor.constraint(equalTo: parentView.centerXAnchor),
selectedView.centerYAnchor.constraint(equalTo: parentView.centerYAnchor, constant: -2.5),
selectedView.widthAnchor.constraint(equalToConstant: 35),
selectedView.heightAnchor.constraint(equalToConstant: 35),
dateLabel.centerXAnchor.constraint(equalTo: parentView.centerXAnchor),
dateLabel.centerYAnchor.constraint(equalTo: parentView.centerYAnchor, constant: -2.5),
eventView.centerXAnchor.constraint(equalTo: parentView.centerXAnchor),
eventView.widthAnchor.constraint(equalToConstant: 6),
eventView.heightAnchor.constraint(equalToConstant: 6),
eventView.bottomAnchor.constraint(equalTo: parentView.topAnchor, constant: 5),
separatorView.leftAnchor.constraint(equalTo: leftAnchor),
separatorView.rightAnchor.constraint(equalTo: rightAnchor),
separatorView.heightAnchor.constraint(equalToConstant: 0.5),
separatorView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 1)
])
}
}
Upon executing the provided code, I encounter the following error
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutXAxisAnchor:0x6000034619c0 "UIView:0x7fb1a8a20ce0.left"> and <NSLayoutXAxisAnchor:0x600003460800 "AppName.DateTableCell:0x7fb1a8a28470.left"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.'
What might be the issue here?
Call your setUpAutoLayout() function after added subviews
override init(frame: CGRect) {
super.init(frame: frame)
parentView.addSubview(selectedView)
parentView.addSubview(dateLabel)
parentView.addSubview(eventView)
addSubview(parentView)
addSubview(separatorView)
setUpAutoLayout()
}