I have several views that I need to have collaborate with a custom sub-class of NSScrollView I am making. One type of view needs to be fixed completely relative to the scrolling in the NSScrollView and another type needs to have its outer shell fixed in position relative to the scrolling but allow inner contents to scroll as the scrollview changes (like the column headers in a spreadsheet for example).
The following are the options for placement of these views within the view hierarchy AFAIK:
*** +[NSLayoutConstraint constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:]: A multiplier of 0 or a nil second item together with a location for the first attribute creates an illegal constraint of a location equal to a constant. Location attributes must be specified in pairs)
===
I have also read in more than one place online that I won't be able to use the Visual Format Language
approach to setting up my constraints because floating constraints aren't set relative to the immediate superview. This is the clue that I am doing something wrong above because the 2nd approach could use VCL whereas the first would need to create NSLayoutConstraint manually.
===
The following is the Swift code that I have added to the initialiser of my NSScrollView subclass:
topCorner = NSButton()
topCorner.translatesAutoresizingMaskIntoConstraints = false
topCorner.bezelStyle = NSBezelStyle.CircularBezelStyle //.RecessedBezelStyle
topCorner.setButtonType(NSButtonType.PushOnPushOffButton)
topCorner.identifier = "topCorner"
topCorner.title = "TC"
self.addSubview(topCorner)
thc = NSLayoutConstraint(item: self.topCorner, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.superview, attribute: NSLayoutAttribute.Left, multiplier: 1.0, constant: 0.0)
self.addConstraint(thc)
thc1 = NSLayoutConstraint(item: self.topCorner, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 36.0)
self.addConstraint(thc1)
thc2 = NSLayoutConstraint(item: self.topCorner, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.superview, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 0.0)
self.addConstraint(thc2)
thc3 = NSLayoutConstraint(item: self.topCorner, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 24.0)
self.addConstraint(thc3)
Just to confuse things further, the error message that I get is only when I have the constraints thc and thc2 around in the code. (Experimented with commenting out different constraints to see which was causing the horrible error text.)
The error message was caused by the fact that the relationship of self.superview
had not been created at the time of adding the constraint.
A further error ensues because the two constraints thc & thc2 can't be added to the NSScrollView, they need to be added to its superview.
While the above still does not yield my desired result it gets rid of two errors that have arisen at runtime.
This will happen if you try to add constraints to views that are not within the view hierachy. An auto layout restriction.
To debug this, I worked out the programmatically created constraint that was causing the issue. Then I debugged to this point and checked neither of the 2 views within the constraint were null when the constraint was added. One of them was. I fixed this and the error went.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With