1

There are numerous answers here that describe how to programmatically animate the primary split view:

let addButton = self.splitViewController!.displayModeButtonItem()
UIApplication.sharedApplication().sendAction(addButton.action, to: addButton.target, from: nil, forEvent: nil)

On an iPad this works wonderfully! But on an iPhone there is this annoying gray box that trails the primary view. By wrapping that action in a UIView.animate block, its possible to see it quite clearly:

Gray Box

The box is hardly visible when you actually dismiss the primary view by tapping over the detail view, but is really annoying when you programmatically dismiss it.

How can I remove this annoying view?

David H
  • 39,114
  • 12
  • 86
  • 125

1 Answers1

3

After banging my head on this for several days, I found a related answer that showed the culprit is the _UIPopoverSlidingChromeView view. The only solution I could find is similar to the solution of the above topic: to hide that view during the animation.

var foundChrome = false
var view: UIView! = self.view
var popView: UIView!

let displayModeButton = self.splitViewController!.displayModeButtonItem()

while view != nil {
   //print("View: ", Mirror(reflecting: view).subjectType, " frame: \(view.frame)")

   if let sv = view {
      if Mirror(reflecting: sv).description.containsString("Popover") { // _UIPopoverView
         for v in sv.subviews {
            //print("SV: ", Mirror(reflecting: v).subjectType, " frame: \(v.frame)")
            if Mirror(reflecting: v).description.containsString("Chrome") {
               foundChrome = true
               popView = v
               popView.hidden = true
               break
            }
         }
         if foundChrome { break }
      }
   }
   view = view.superview
}
if foundChrome {
   let duration: NSTimeInterval = 2.0
   UIView.animateWithDuration(duration, animations: { () -> Void in
      UIApplication.sharedApplication().sendAction(displayModeButton.action, to: displayModeButton.target, from: nil, forEvent: nil)
   })
   // must do this separately, doing in a completion block doesn't work, as it takes affect too soon
   let t = dispatch_time(DISPATCH_TIME_NOW, Int64(duration * NSTimeInterval(NSEC_PER_SEC)))
   dispatch_after(t, dispatch_get_main_queue()) {
      popView.hidden = false
   }
}

I realize this is somewhat esoteric, but if you experience the problem you will be happy for any way to work around it.

Community
  • 1
  • 1
David H
  • 39,114
  • 12
  • 86
  • 125
  • Where do you use this method? You mentioned "during the transition" but where would that be? – Rodrigo Lira Aug 04 '17 at 20:39
  • @RodrigoLira Its right there above - in the "if foundChrome" statement. The first part of the code looks for the "Chrome" view, and if found hides it. The "sendAction" initiates the close programmatically, and the dispatch blocks handle unhiding that gray box. – David H Aug 05 '17 at 14:19
  • Thank you! I got it now! – Rodrigo Lira Aug 05 '17 at 18:07