Resolved UIViews intersecting, but CGRectIntersectsRect returns false

Discussion in 'iOS Programming' started by moonman239, Jan 3, 2017.

  1. moonman239, Jan 3, 2017
    Last edited: Jan 10, 2017

    moonman239 macrumors 68000

    Joined:
    Mar 27, 2009
    #1
    I have two UIViews, named Alice and Bob. Both have a fixed size. Alice's position in the superview is fixed using constraints. Bob is supposed to be dragged by the user until Bob intersects with Alice. However, a subsequent call to CGRectIntersectsRect does not necessarily return true even if Bob does intersect with Alice, which I've checked visually.

    Here's my code:
    Code:
    p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #000000} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #3e1e81} p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #008400} p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #4f8187} p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #000000; min-height: 13.0px} p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #d12f1b} p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #31595d} span.s1 {font-variant-ligatures: no-common-ligatures} span.s2 {font-variant-ligatures: no-common-ligatures; color: #ba2da2} span.s3 {font-variant-ligatures: no-common-ligatures; color: #4f8187} span.s4 {font-variant-ligatures: no-common-ligatures; color: #703daa} span.s5 {font-variant-ligatures: no-common-ligatures; color: #3e1e81} span.s6 {font-variant-ligatures: no-common-ligatures; color: #d12f1b} span.s7 {font-variant-ligatures: no-common-ligatures; color: #000000} span.s8 {font-variant-ligatures: no-common-ligatures; color: #272ad8} span.s9 {font-variant-ligatures: no-common-ligatures; color: #31595d}
    
    -(void)label:(DraggableLabel *)label newRect:(CGRect)rect
    
    {
    
        NSString *word = [NSString stringWithFormat:@"%@%@",[label text],wordFamilyName];
    
        NSURL *firstLetterUrl = [[NSBundle mainBundle] URLForResource:[[label text] lowercaseString] withExtension:@"m4a" subdirectory:@"sounds"];
    
        AVPlayerItem *wordSoundItem = [[AVPlayerItem alloc] initWithURL:wordSoundUrl];
    
        AVPlayerItem *firstLetterSound = [[AVPlayerItem alloc] initWithURL:firstLetterUrl];
    
        CGRect targetRect = [self.lastLettersLabel frame];
    
        targetRect.size.height += 50;
    
        targetRect.size.width += 50;
    
        if (CGRectIntersectsRect([self.lastLettersLabel frame], rect))
    
        {
    
            /* [label setUserInteractionEnabled:false]; */
    
        if ([word isEqualToString:correctString]) {
    
            // Child built the word we want him to.
    
            [label moveOnTopOfView:self.lastLettersLabel.rectangleView];
    
            [[self textCollectionView] setUserInteractionEnabled:false];
    
            labelDropped = label;
    
            if ([[someEnumerator allObjects] count] == 0) {
    
                // End of section.
    
                [self newActivityUnlocked];
    
            
    
            }
    
            [[self queuePlayer] play];
    
        }
    
        else
    
        {
    
            @try {
    
            [[self queuePlayer] insertItem:wordSoundItem afterItem:nil];
    
            }
    
            @catch (NSException *e)
    
            {
    
                NSLog(@"%@", [e reason]);
    
            }
    
            [[self queuePlayer] play];
    
        }
    
        }
    
        else
    
        {
    
        }
    
    }
    
     
  2. imk_87 macrumors newbie

    imk_87

    Joined:
    Oct 27, 2016
    Location:
    Rzeszow
    #2
    Are these both views have the same superview? If not you have to convert it using
    Code:
    convertRect:fromView:
     
  3. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #3
    To debug things like this you can print out the rectangles using NSStringFromCGRect. Something like this

    Code:
    NSLog(@"frame: %@", NSStringFromCGRect(frame))
    If you print out the relevant rects it will probably be obvious what the problem is.
     
  4. moonman239, Jan 9, 2017
    Last edited: Jan 10, 2017

    moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #4
    Logged both views' frames. Results:

    Frame 1:
    {{599, 593.5}, {70, 81}}
    Frame 2:
    {{708, 656}, {77, 84}}

    Edit: This confuses me. The debugger's results are consistent with CGRectIntersectsRect output, but not with what I'm seeing on my device. I have borders in both views.

    Wait - the window to be dragged into has a subview, but that doesn't appear to be relevant to my case.

    Edit #2: Here is the code that determines where the dragged view is to be moved:
    Code:
    
    NSArray *touchArray = [touches allObjects];
    
        CGPoint touchLocationInView = [[touchArray firstObject] locationInView:[self superview]];
    
        if (CGRectContainsPoint([self.superview bounds], touchLocationInView))
    
        {
    
        [self setCenter:touchLocationInView];
    
        }
    }
    
     
  5. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #5
    Did you take into account what@imk_87 said above? If the two views don't have the same superview then their frames aren't in the same coordinate system.
     
  6. moonman239, Jan 10, 2017
    Last edited: Jan 10, 2017

    moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #6
    Yes, the two views have the same superview. I verified this with the debugger.
    Edit: According to the storyboard, the constraints should be pinning the view's center to an entirely different location than is being presented.
     
  7. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #7
    I don't have a good answer for you.

    Another debugging tip of view positions is to set the background color of the various views to distinct colors (yellow, purple, red etc.) In your case I would probably set the alpha values also to be less than one. This way you can be clear on where the views are.

    Also, Xcode now has a view debugging capability that lets you see the view hierarchy in 3D, which should also help you figure this out. Move the views to a position where you believe they overlap and then view the 3D view hierarchy.

    I assume there's no funny stuff like setting a transform on any of the views.

    Looking at your code, moveToOriginalSuperview makes me wonder exactly what the superviews are. Also, you should never need to call setNeedsDisplay. Also your method is too big and does too many things. You should pull all the AVPlayer stuff out into other methods.
     
  8. moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #8
    I did something similar. I'm wondering if perhaps copying the view controller from a different version of my storyboard would help.

    Edit: For now, ignore [self moveToSuperview] - that method call is now irrelevant to the problem.
     
  9. moonman239, Jan 11, 2017
    Last edited: Jan 11, 2017

    moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #9
    There was a warning that the frame on Alice wouldn't be the same at runtime. After updating the frame, Xcode showed me that the frame is smaller than I'd set it to be. I added a width & height constraint, I'll see what that does.

    Edit: That fixed it!

    Also, to clarify: the frame being smaller meant that Bob didn't actually intersect with Alice. Alice's subview, with which Bob did intersect, was being drawn outside Alice.
     

Share This Page