title: UIView display order issue?
body: <p><strong>The problem</strong></p>
  
  <p>When drawing a custom movie player controller on-screen (iOS 4), I use an <code>AVPlayerLayer</code> to display. I wish to composite some overlays on top of the player (ad banners, player controls, etc). At the moment, this works absolutely fine with the following hierarchy:</p>
  
  <pre>
  UIView(self.view)\
                   | UIView(controlsView)\
                   *                     | UIView [some movie player controls]
                                         | UIView [some more movie player controls]
                                         *
  </pre>
  
  <p>The <code>AVPlayerLayer</code> is a sublayer of <code>self.view</code>. On player load, I add the layer to <code>self.view</code> first and call <code>bringSubviewToFront:</code> on the <code>controlsView</code>, and then detect taps on it and programmatically show/fadeout on a timer/whatever. No issue here.</p>
  
  <p>Now that I have support for dynamically fetching and displaying advertising content, I would like to set up the following hierarchy:</p>
  
  <pre>
  UIView(self.view)\
                   | UIImageView (ad banner)
                   | UIImageView (another ad banner)
                   | ...
                   | UIView(controlsView)\
                   *                     | UIView [some movie player controls]
                                         | UIView [some more movie player controls]
                                         *
  </pre>
  
  <p>At player load, what I then do is attach to my <code>AVPlayer</code> instance some <code>addBoundaryTimeObserverForTimes:queue:usingBlock:</code> calls to fade the ad banners in and out at appropriate times. As I do this, I add the <code>UIImageView</code>s to <code>self.view</code> as subviews with no explicit ordering (hence they should be drawn on top of everything else), and <code>setHidden:YES</code> on them.</p>
  
  <p>I've <code>NSLog</code>'d and these fade blocks are correctly being executed, setting <code>view.alpha = 1.0f</code> and <code>view.alpha = 0.0f</code> for show and hide respectively on the ad banners, but nothing is appearing at all, even when explicitly setting the <code>UIImage</code> displayed by the view to a known working local image and the frame to <code>(0, 0, 320, 480)</code>, plus setting an <code>autoresizingMask</code> of</p>
  
  <pre><code>UIViewAutoresizingFlexibleTopMargin  |
  UIViewAutoresizingFlexibleLeftMargin |
  UIViewAutoresizingFlexibleRightMargin;
  </code></pre>
  
  <p>The <code>UIViewContentMode</code> is default (should be <code>UIViewContentModeScaleToFill</code>).</p>
  
  <hr>
  
  <p><strong>The 'solution' I've gone with for the problem</strong></p>
  
  <p>This doesn't actually address the issue at all, but I'm now using 0.1% opacity as a replacement for 0% opacity. Effectively hides the element without causing issues, and fadeins/fadeouts are working well.</p>
  
  <hr>
  
  <p><strong>Troubleshooting</strong></p>
  
  <p>To make sure I wasn't drawing the movie over the top of all non-controls views, I moved the <code>AVPlayerLayer</code> to an additional view, <code>videoView</code>:</p>
  
  <pre>
  UIView(self.view)\
                   | UIView(videoView)
                   | UIImageView (ad banner)
                   | UIImageView (another ad banner)
                   | ...
                   | UIView(controlsView)\
                   *                     | UIView [some movie player controls]
                                         | UIView [some more movie player controls]
                                         *
  </pre>
  
  <p>I explicitly call <code>sendSubviewToBack:videoView</code> and <code>bringSubviewToFront:controlsView</code>, but still no love. I can see the overlay ads on-screen if I don't call <code>setHidden:YES</code> when I first add them to the view hierarchy. The kicker is this: <em>the ad also disappears at the correct time</em> (in response to <code>overlayImage.alpha = 0.0f</code> in my animation blocks), so I know my animation blocks are fine.</p>
  
  <p>Here is a code snippet to do with adding the ad banners to my movie player's view:</p>
  
  <pre><code>for(MyCustomAdBannerClass *overlay in overlays)
  {
      UIImageView *overlayImage =
      [[UIImageView alloc] initWithImage:
       [UIImage initWithData:
        [NSData dataWithContentsOfURL:[overlay contentURL]]]];
      UIViewAutoresizing autoresizingFlags =
          UIViewAutoresizingNone;
      CGFloat x, y, width, height;
      width = [overlay width];
      height = [overlay height];
      // &lt;snip&gt; set x, y, autoresizing values of the above vars
      [overlayImage setFrame:CGRectMake(x, y, width, height)];
      [overlayImage setAutoresizingMask:autoresizingFlags];
      [self.view addSubview:overlayImage];
  }
  
  for(UIView *subview in self.view.subviews)
  {
      if(subview == controlsView)
          [self.view bringSubviewToFront:subview];
      else if(subview == videoView)
          [self.view sendSubviewToBack:subview];
      else
          [subview setHidden:YES];
  }
  </code></pre>
  
  <p>Here is the code I use for adding the overlay appear/disappear callbacks (<code>overlay</code> is an object with information about when to show the overlay and how long for, <code>overlayImage</code> is the <code>UIImageView</code> containing the actual ad banner):</p>
  
  <pre><code>[self.player
   addBoundaryTimeObserverForTimes:[NSArray arrayWithObject:
                                    [overlay startTime]]
   queue:dispatch_get_main_queue()
   usingBlock:^{
       [UIView
        animateWithDuration:0.7
        animations:^{
            overlayImage.alpha = 1.0f;
            dispatch_time_t popTime =
            dispatch_time(DISPATCH_TIME_NOW,
                          [overlay duration] * NSEC_PER_SEC);
            dispatch_after(popTime, dispatch_get_main_queue(),
                           ^(void){
                               [UIView
                                animateWithDuration:0.7
                                animations:^{
                                    overlayImage.alpha = 0.0f;
                                    [overlayImage removeFromSuperview];
                                }];
                            }];
                  }];
  }];
  </code></pre>
  
  <p>As I said, that <code>overlayImage.alpha = 0.0f;</code> call is being executed <em>correctly</em>.</p>
  
  <p><strong>NOTE:</strong> Just tried setting <code>overlay.alpha = 0.5f;</code> instead of <code>0.0f</code> when the views are first added. The overlay FADES IN properly now. So there is something funky going on with making the view 100% invisible which prevents it from being shown again at a later date. No crashes, so it's not just referencing dealloced memory.</p>
  
  <hr>
  
  <p><strong>Attempted workaround</strong></p>
  
  <p>I tried sending all the ad overlays behind <code>videoView</code> and then when each one was to be shown I called</p>
  
  <pre><code>[overlayImage removeFromSuperview];
  [self.view insertSubview:overlayImage aboveView:videoView];
  // dispatch hide animation
  </code></pre>
  
  <p>Still doesn't show them, but still fades properly when I omit <code>setHidden:YES</code>.</p>