Is there a way find the edges in an NSArray of UIViews.
For instance, the diagram below shows a collection of UIViews (1 to 7). Each view abuts another view. So view 1 could be (0,0,70,20) and view 6 is (70,0,30,50).
How would I return an array of lines which are the separators between views. In the example below, there would be 6 separators (the internal lines).
---------------------
| 1 | 6 |
| | |
-------------| |
| 2 | 3 | |
| |-----| |
| | 4 |------|
-------------| |
| 5 | 7 |
---------------------
My first attempt gets the internal lines of each square (the lines which are not on the outside of the container view), removes the duplicates (ie those between 3 and 4),
..and then removes the lines which are touching other lines on the edge until there is one left. Unfortunately this removes the right-most vertical line.
My code for this last part:
NSMutableArray *sidesToDiscard = [[NSMutableArray alloc] init];
for (NSValue *rect1 in self.sides)
{
for (NSValue *rect2 in self.sides)
{
if ([rect1 isEqualToValue:rect2])
{
} else
{
BOOL xIsSame = (rect2.CGRectValue.origin.x == rect1.CGRectValue.origin.x);
BOOL bothAreVertical = (rect2.CGRectValue.size.width == 0 && rect1.CGRectValue.size.width == 0);
BOOL areTouchingOnVertical = ((rect1.CGRectValue.origin.y + rect1.CGRectValue.size.height == rect2.CGRectValue.origin.y) || (rect1.CGRectValue.origin.y == rect1.CGRectValue.origin.y + rect2.CGRectValue.size.height));
BOOL yIsSame = (rect2.CGRectValue.origin.y == rect1.CGRectValue.origin.y);
BOOL bothAreHorizontal = (rect2.CGRectValue.size.height == 0 && rect1.CGRectValue.size.height == 0);
BOOL areTouchingOnHorizontal = ((rect1.CGRectValue.origin.x + rect1.CGRectValue.size.width == rect2.CGRectValue.origin.x) || (rect1.CGRectValue.origin.x == rect2.CGRectValue.origin.x + rect2.CGRectValue.size.width));
if (((xIsSame && bothAreVertical) && areTouchingOnVertical) || ((yIsSame && bothAreHorizontal) && areTouchingOnHorizontal))
{
// if are touching then remove, leaving one left...
[sidesToDiscard addObject:rect1];
[sidesToDiscard addObject:rect2];
}
}
}
}
[self.sides removeObjectsInArray:sidesToDiscard];
You can convert each view (rectangle) into 4 end points. Remove duplicated points. Since each line segment is formed by connecting two points, you can iterate through all possible line segments by iterating through all possible point pairs, and you want to find the line segments which are
To check 1, you have to iterate through all edges of views, remove the intersection of the line segment and the edges. If nothing is left, you know it might be the line segment you want.
3 and 4 are easy to check.
Iterate through all line segments which satisfy 1, 3, 4. If there are two line segments intersecting, remove the shorter one. What are left must satisfy 2.
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