3
votes

I'm working on a game in Cocos2D for iOS and seeing a lot of constraint related warnings in the console. I've read many of the constraint related posts here on SO and other sites but have not been able to resolve this.

I have no NIB files and have not used XCodes user-interface builder in this project. Cocos2D just uses a programmatically created full-screen GLView. As far as I can tell all these constraints are coming from the MPMoviePlayerController interacting with the UIView itself.

I'm using this code for MPMoviePlayerController integration: https://github.com/cocos2d/cocos2d-iphone-extensions/blob/master/Extensions/CCVideoPlayer/iOS/CCVideoPlayerImpliOS.m

with some slight changes to show the video non-full-screen, and to get it to compile on iOS8:

- (void) setupViewAndPlay
{
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];    

    CGSize viewSize = [[CCDirector sharedDirector] viewSizeInPixels];

    // We want to show these animations windowed - not full screen
    // Native resolution of the movie is 480p = 640x360
    CGRect videoFrame = CGRectMake( 0, 0, 640, 360);
    if (viewSize.height < 768)
    {
        // On the iphone play at 1/2 size
        videoFrame = CGRectMake(0, 0, 320, 180);
    }
    videoFrame.origin.x = (viewSize.width - videoFrame.size.width) / 2.0f;
    videoFrame.origin.y = (viewSize.height - videoFrame.size.height) / 2.0f;
   [keyWindow addSubview: [_theMovie view]];
    [[_theMovie view] setHidden:  NO];
    [[_theMovie view] setFrame: videoFrame];
    [[_theMovie view] setCenter: keyWindow.center ];
    [keyWindow setAutoresizesSubviews:NO];
    [self updateOrientationWithOrientation: (UIDeviceOrientation)[[UIApplication sharedApplication] statusBarOrientation]];

    // Movie playback is asynchronous, so this method returns immediately.
    [_theMovie play];
}

Here is the warnings I'm seeing:

2014-10-01 11:32:45.360 SpaceBotAlpha[182:4484] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 

(
    "<NSLayoutConstraint:0x17774f20 H:|-(34)-[MPKnockoutButton:0x177db4e0](LTR)    (Names: '|':_UIBackdropContentView:0x18c7e040 )>",
    "<NSLayoutConstraint:0x17774f50 H:[MPKnockoutButton:0x177db4e0]-(34)-[MPDetailSlider:0x18cb1f60](LTR)>",
    "<NSLayoutConstraint:0x17774f80 H:[MPDetailSlider:0x18cb1f60]-(34)-[UIView:0x18cb6780](LTR)>",
    "<NSLayoutConstraint:0x17774fb0 UIView:0x18cb6780.right == _UIBackdropView:0x18caec50.right - 34>",
    "<NSLayoutConstraint:0x18cafac0 H:|-(0)-[_UIBackdropView:0x18caec50]   (Names: '|':MPVideoPlaybackOverlayView:0x1778ad80 )>",
    "<NSLayoutConstraint:0x18cc77b0 H:[_UIBackdropView:0x18caec50]-(0)-|   (Names: '|':MPVideoPlaybackOverlayView:0x1778ad80 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x1776da10 h=-&- v=-&- _UIBackdropContentView:0x18c7e040.midX == _UIBackdropView:0x18caec50.midX>",
    "<NSAutoresizingMaskLayoutConstraint:0x1776da40 h=-&- v=-&- _UIBackdropContentView:0x18c7e040.width == _UIBackdropView:0x18caec50.width>",
    "<NSAutoresizingMaskLayoutConstraint:0x177aa050 h=-&- v=-&- MPVideoPlaybackOverlayView:0x1778ad80.width == MPVideoContainerView:0x1778b8e0.width>",
    "<NSAutoresizingMaskLayoutConstraint:0x1775e480 h=-&- v=-&- MPVideoContainerView:0x1778b8e0.width == MPSwipableView:0x18cba6f0.width>",
    "<NSAutoresizingMaskLayoutConstraint:0x177a8ce0 h=-&- v=-&- MPSwipableView:0x18cba6f0.width == MPMovieView:0x177c7eb0.width>",
    "<NSAutoresizingMaskLayoutConstraint:0x17766310 h=--& v=--& H:[MPMovieView:0x177c7eb0(0)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x17774f50 H:[MPKnockoutButton:0x177db4e0]-(34)-[MPDetailSlider:0x18cb1f60](LTR)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

All the posts I've found about constraints assume that interface builder has been used.

Any clues? Thanks!


Just in case anyone finds this post looking for info about rotation: I noticed something odd in that on iOS8 the MPMoviePlayerController seems to auto-rotate to the correct orientation and if I leave the updateOrientationWithOrientation method as-is (see GitHub link) then it appears at 90 degrees to what is required. So on iOS8 I detect the version inside updateOrientationWithOrientation and exit without doing anything on iOS8.

4
have you read the message and looked into translatesAutoResizingMaskIntoConstraints?LearnCocos2D
I tried setting to YES and to NO the translatesAutoResizingMaskIntoConstraints switch but it did not help. This problem is still occurring, and I'm still getting the same spam in the console.Sez
I've just hit this problem, as far as I can tell it's a bug in iOS 8.x. The constraints in question are way down in the MPMoviePlayer view hierarchy. You could, in theory, drill down to them and set their translatesAutoresizingMaskIntoConstraints=NO, but I'm personally opting to leave it alone.Reuben Scratton

4 Answers

9
votes

I was having the same constraints issues. However, sez's answer didn't work for me so I dug a little deeper. In my case the problem was calling [videoConroller prepareToPlay] before setting the video controller view's frame and adding it to a superview.

I was creating the instance of my MPMoviePlayerController and calling prepareToPlay in viewDidLoad as I had the url at this time. However, I was waiting until viewDidAppear to actually size the video player and add it to the view hierarchy.

Simply moving that method call to after adding the view to the hierarchy solved my problem. Also, I was able to have a frame that did not match the parent view's bounds.

8
votes

Did you try using a MPMoviePlayerViewController instead of MPMoviePlayerController ? (It works for me :-)) Then set translatesAutoresizingMaskIntoConstraints to YES. Just like this :

     MPMoviePlayerViewController *moviePlayerViewController = [MPMoviePlayerViewController new];
    [moviePlayerViewController.view setTranslatesAutoresizingMaskIntoConstraints:YES];

I hope this be useful for you!..

3
votes

OK, I eventually resolved this by getting rid of the CCVideoPlayer extension that I was trying to hack and just directly using MPMoviePlayerController. When I get around to doing Mac I'll have to roll a new solution for that.

The key to getting rid of the constraint messages was that the windowed size of the movie's view has to match its super-views size. To do this I constructed a UIView in code with the correct size and position, and made the MPMoviePlayerController's view a child of that.

Here's part of that code:

_videoFrameView = [[UIView alloc] initWithFrame:frameUI];
[_videoFrameView setBackgroundColor:[UIColor redColor]];
[mainView addSubview:_videoFrameView];

_movie = [[MPMoviePlayerController alloc] init];
[_movie setRepeatMode:(MPMovieRepeatModeNone)];
[_movie setControlStyle:MPMovieControlStyleNone];
[_movie setScalingMode:MPMovieScalingModeAspectFit];
[_movie setMovieSourceType:(MPMovieSourceTypeStreaming)];
CGRect movieFrame;
movieFrame.size = frameUI.size;
[[_movie view] setFrame:movieFrame]; // player's frame size must match parent's

[_videoFrameView addSubview: [_movie view]];
[_videoFrameView bringSubviewToFront:[_movie view]];

a more detailed paste of the approach is shown in this gist. I based my approach on ideas shown in this other answer.

0
votes

In iOS 9.1.2 below lines resolved. Also the warning repeatedly printed till I relaunch the app. These lines solved it .

moviePlayerController = [[MPMoviePlayerController alloc]initWithContentURL:videoUrl];
    [moviePlayerController.view setTranslatesAutoresizingMaskIntoConstraints:NO];