Why is this autolayout specification not sufficient? - iphone

I am trying to get rid of those annoying warnings in Interface Builder, but I do not understand what it is complaining about (all Interface Builder, no code):
I have specified a fixed with, fixed height and fixed distances to right and top.
Yet the warning tells me
Needs Constraints for: Y position, height
Needs Constraints for: X position, width
Can someone please explain how these are constraints are not sufficient?
Edit
Also, when using the "automatic" add constraints commands, it does nothing and the errors remain.

I would suspect the superview is not pinned to a size in interface builder. Autolayout constraints seem to solve everything simultaneously and an error message that looks like it relates to one view can just as easily relate to the other view in the relationship.
What is - (NSArray *)constraintsAffectingLayoutForAxis:(UILayoutConstraintAxis)axis telling you?

Related

Swift : how to check which view is causing constraints error

I am getting the following error when trying to load a VC:
Thread 1: Exception: "Unable to activate constraint with anchors
<NSLayoutXAxisAnchor:0x280fea300 \"i6.I6FuelSheetTextField:0x1030fe400.centerX\"> and
<NSLayoutXAxisAnchor:0x280fea440
\"UILayoutGuide:0x282327800'UIViewSafeAreaLayoutGuide'.centerX\"> because they have no common
ancestor. Does the constraint or its anchors reference items in different view hierarchies?
That's illegal."
How can I identify which views these addresses are referring to?
This is occurring because you are trying to constraint two views that are unrelated to each other. You are lucky enough to get enough information from the error. You are using a component that an instance of I6FuelSheetTextField and you trying to constraint it's centerX attribute. So, I think the error itself is pretty explanatory.
Note: It could also be the case when you forget to add a view to another view's subview.

Is it possible to reference constants in code from storyboard in Swift?

I have constants in my code, for example:
let cellHeight = 44
I don't know how to reference those constants from code in the storyboard. For example, in the storyboard, there are multiple section headers of a tableview:
I would like to control all of their heights with a constant, so if I decide to change the height, I don't have to change every storyboard value. I would like to replace those numbers with constant names.
I did some research, and couldn't find anything. I don't know if this is possible, but is it?
P.S. I know that I can just connect the UI to the code, and set the height in viewDidLoad(), but I want to use this way.
There is no simple way, because a storyboard is not code — there is nothing there that can "see" your variable cellHeight.
However, what you are asking to do is something you should not want to do. If you have sizes that need to be adjusted depending on the screen size, or views that need to be adjusted when some other view changes, that is what auto layout is for.
Otherwise, you will just have to write code that changes all the things you want changed when you want them changed.

Snapkit: Constrain multiple to margins

I'm using Snapkit to simplify my autolayout code, however one scenario seems to popup very regularly, which i'm wondering if there's a way which involves less code.
So let's say that I need to pin the edges of a UIView to it's superview margins, we might do something like this:
subView.snp.makeConstraints { make in
make.top.equalTo(parentView.snp.topMargin)
make.bottom.equalTo(parentView.snp.bottomMargin)
make.left.equalTo(parentView.snp.leftMargin)
make.right.equalTo(parentView.snp.rightMargin)
}
This essentially results in the subview filling the parent view, except for a small amount of padding as defined by the parent views layout margins.I'm sure some variation of this is pretty common.
This seems overly verbose for this library. It has some really nice helper methods such as these
make.edges.equalToSuperview()
make.top.left.right.equalToSuperview()
What I haven't managed to find in their documentation however is how to do the two above helper methods, in relation to the margins.
What i'm looking for (if it exists) is something akin to:
make.edges.equalToSuperview().withMargins()
make.top.left.right.equalToSuperview().withMargins()
make.top.left.right.equalTo(someview).withMargins()
So, is there a way of doing this other than the very verbose way? Am I missing something in the documentation or maybe this could be added by extension?
did you try something like this?
subView.snp.makeConstraints { make in
make.edges.equalTo(view.snp.margins)
}
Edit after comment:
When you only want to constrain certain edges to the superview margin, you can do something like this.
subView.snp.makeConstraints { make in
make.top.leading.equalTo(view).inset(view.layoutMargins)
}
or
subView.snp.makeConstraints { make in
make.top.leading.equalTo(view.layoutMarginsGuide)
or
subView.snp.makeConstraints { make in
make.top.leading.equalTo(view.safeAreaLayoutGuide)
One nice way to do this is to use UIView.layoutMarginsGuide:
childView.snp.makeConstraints { make in
make.top.leading.bottom.equalTo(parentView.layoutMarginsGuide)
make.trailing.equalTo(otherView.snp.leading).offset(-8.0)
}

UITableViewDelegate Protocol Reference [ iOS 4.2 Library ]

iwas reading about the tableView protocol in the iOs 4.2 documentation, and i found this sentence, which refers to the "tableView:viewForHeaderInSection:" paragraph:
Discussion The returned object, for
example, can be a UILabel or
UIImageView object. The table view
automatically adjusts the height of
the section header to accommodate the
returned view object. This method only
works correctly when
tableView:heightForHeaderInSection: is
also implemented.
It doesn't seem to you a little bit misunderstanding?
Yes, it sounds a bit misleading.
In fact they say 2 things:
1) We make the header the height of the object you returned for tableView:viewForHeaderInSection:
2) We make the header height you returned in the method tableView:heightForHeaderInSection:.
These are two quite different.
But the correct conclusion is:
1) You have to implement heightForHeaderInSection.
2) Your height for each section will be adjusted for the object you return if it is not accommodate to the size you defined in heightForHeaderInSection:.

how to compare the hierarchical order of two subviews?

I want to find a way how I can compare the actual hierarchical order of two subviews.
As i didn't find a method who turns out to give me this kind of result, I want to ask you. Im sure there must be a way to do this.
Is it possible, that the [view subviews] array is ordered with the same hierarchy?
Thanks,
Makrus
Although I have not find any reference about that in docs I'm pretty sure that the order of elements in subviews array corresponds to their z-order. You can try to change order of subviews in IB and log subviews to console - you will see that output supports that.
One more hint that it is really so are insertSubview:atIndex: and exchangeSubviewAtIndex:withSubviewAtIndex: methods which change subview's z-order and those changes are reflected in subviews array order...