iOS Segues with Popover has undesirable default behavior

Discussion in 'iOS Programming' started by iRCL, Dec 22, 2011.

  1. iRCL macrumors 6502

    Joined:
    Nov 2, 2011
    #1
    I've got a weird issue with segues - I have a segue open a popover when a UIButton is tapped, all of this done through IB. (This is on iPad)

    But when I select an option from the Tableview on this popover I want it to dismiss the popover. And I don't want the popover to open twice if the user taps that UIButton twice..

    The way things work by default, tapping that UIButton keeps opening popovers on top of each other "forever" and also I still have the issue that when a cell from my Tableview is tapped, the popover remains.

    How can I solve these problems?
     
  2. jnoxx macrumors 65816

    jnoxx

    Joined:
    Dec 29, 2010
    Location:
    Aartselaar // Antwerp // Belgium
    #2
    When you'd open a "new" popover, you can check for previous ones, and just remove them animated (it's standard).
     
  3. iRCL thread starter macrumors 6502

    Joined:
    Nov 2, 2011
    #3
    How can I achieve this? It's a VC shown in a storyboard, and the segue is a link right from an originating VC to it. How can a new popover know if there are others? And how can it dismiss itself?
     
  4. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #4
    The view controller from which the segue starts should have this method:

    Code:
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    possibly the view controller from which the segue starts should hold onto a pointer to segue.destinationViewController within that method. It could check that pointer and say, if it's not nil, go to that view controller and have it dismissed as the new one comes up. And once the new one is up, assign it to that pointer.

    I'm not sure if that's the "proper" way for doing it, but it's probably how I would do it. (Note that I've never made an iPad app before, nor do I own one, so my exposure to the iPad's typical behaviors is limited to playing with them for a few seconds in my Apple Store and Best Buy.)
     
  5. jnoxx macrumors 65816

    jnoxx

    Joined:
    Dec 29, 2010
    Location:
    Aartselaar // Antwerp // Belgium
    #5
    [quote="ArtOfWarfare][/quote]
    Art, I thought he meant real Popups, not having the issue of pushing new viewcontrollers with the "storyboards", or am I a wrong?
    The thing is, an UIPopoverViewController, you can dismiss them with a method.
    Think that when he press his tableviewcell, he needs to check if popups are there, he will need to dismiss them, you have methods for these in the UIPopoverViewController reference if i'm not mistaking..
     
  6. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #6
    He's talking about segues, which I thought transitions are only called when using a storyboard.

    He said IB, which no longer exists, so I figured he meant storyboards.
     
  7. jaikob macrumors 6502

    jaikob

    Joined:
    Jul 1, 2008
    Location:
    Freeland, MI
    #7
    Correct, segues are controlled from storyboards, he probably meant the interface builder portion of Xcode.

    In your popover view controller, you need to create an IBAction to close your popover instead of using a segue. Is that what you are looking for?
     
  8. iRCL thread starter macrumors 6502

    Joined:
    Nov 2, 2011
    #8
    Correct, of course I meant the interface builder portion of Xcode.. I would not really agree w/Art that 'IB no longer exists' but whatever

    Well, yeah using an IBAction to close my popover instead of using a segue would resolve this problem... and that's what I'll do if nobody can come up with a more direct solution that actually keeps this logic within segues somehow

    But what I'm getting at is - why does this segue behavior even exist? I can't imagine a single situation where someone would want the default behavior I'm seeing. Everything done with a segue can be done by just using an IBAction and running custom code, but they're supposed to be time saving/convenient/handle things automatically.

    This is sort of like me using a UINavigationController and then having to manually handle a push or something.. it's the same type of built in feature that is supposed to take care of all that basic UI stuff for a person. Although on the other hand this would definitely not be the first time that Apple has put something similarly useless in their dev tools
     
  9. ap0110 macrumors newbie

    Joined:
    Jan 15, 2012
    #9
    iRCL, I know EXACTLY what you're talking about! This issue has just sucked about an entire working day. Obviously you can code around it but that defeats the point of using storyboards.

    Did you ever find a solution? None of the other responders seem to understand what you're talking about. It's pretty blatant, though. You have two view controllers, the first one inside a navigation controller. You put a button in the navigation bar. You Ctrl-drag from that button to the 2nd view controller and select a popover segue. It's all meant to be automagical and super easy to use.

    BUT when you actually go to use it, it doesn't work! You end up with an infinite stack of popovers. And since the class is actually UIViewController and not UIPopoverController (and you can't specify UIPopoverController in the storyboard or in any way identify it as such), you don't have the methods of a UIPopoverController, such as dismissPopoverAnimated.

    On top of that, you can't add anything to prepareForSegue to cancel the segue because at that point the segue's already happening. There's no cancelSegue method that I can tell.

    Have you found any other solutions? Every workaround that I've come up with so far is actually more involved than just creating the popover programmatically like I would have done before storyboards. So far the cleanest fix I've come up with is to use IBAction on the button and check if the 2nd view controller is already visible before doing performSegueWithIdentifier.
     
  10. iRCL thread starter macrumors 6502

    Joined:
    Nov 2, 2011
    #10
    Precisely! No, I haven't found a solution but I'm glad I'm not alone. Let me know if you find one and I'll do likewise. Thanks!
     
  11. IronSheep macrumors newbie

    Joined:
    Apr 13, 2012
    Location:
    Colorado, USA
    #11
    More information - not yet a solution...

    Take a look at the bare code generated by the Utility Application Template.
    (generate for both iPad and iPhone - "Universal" and use "storyboard")

    Run on the iPad simulator - what you'll see it that the button is on the right-side of the navigation bar and it works as we want (no forever-deeper set of popups!)

    So, is this maybe a left-side button issue?

    In the example code cited the segue is not being called, in "our" code (i'm guessing that your case is similar to mine) the segue is being called!

    So why? In the cited case the segue is being defined in storyboard but prepare is not being called. WHY? :confused:

    I'm now more than half a day and making no more progress either! AUGH!

    My hope is that this info will help trigger someone into determining more of
    what is happening and why!

    Regards,
    IronSheep
    --
    http://9CardGolf.ironsheep.biz
     
  12. IronSheep macrumors newbie

    Joined:
    Apr 13, 2012
    Location:
    Colorado, USA
    #12
    Here's more detail:

    CASE#1 - start, press button to cause popover, press done to dismiss:
    Code:
    (start app)
    2012-04-13 16:13:00.116 testUTApp[63445:f803] MainViewController - viewDidLoad
    
    (now press [info])
    2012-04-13 16:13:05.525 testUTApp[63445:f803] MainViewController - togglePopover by [<UIBarButtonItem: 0x6a440e0>]
    2012-04-13 16:13:05.527 testUTApp[63445:f803] FlipsideViewController - awakeFromNib
    2012-04-13 16:13:05.530 testUTApp[63445:f803] FlipsideViewController - viewDidLoad
    2012-04-13 16:13:05.531 testUTApp[63445:f803] MainViewController - prepareForSegue: [showAlternate]
    
    (now press [Done])
    2012-04-13 16:13:23.429 testUTApp[63445:f803] FlipsideViewController - done: [<UIBarButtonItem: 0x6b077b0>]
    2012-04-13 16:13:23.431 testUTApp[63445:f803] MainViewController - flipsideViewControllerDidFinish by [<FlipsideViewController: 0x6b52350>]
    Case #2: Start app, press [info] to cause popover, press again to dismiss:

    Code:
    (start app)
    2012-04-13 16:19:20.913 testUTApp[63477:f803] MainViewController - viewDidLoad
    
    (press [info] to open popover)
    2012-04-13 16:19:23.772 testUTApp[63477:f803] MainViewController - togglePopover by [<UIBarButtonItem: 0x6e40440>]
    2012-04-13 16:19:23.774 testUTApp[63477:f803] FlipsideViewController - awakeFromNib
    2012-04-13 16:19:23.778 testUTApp[63477:f803] FlipsideViewController - viewDidLoad
    2012-04-13 16:19:23.780 testUTApp[63477:f803] MainViewController - prepareForSegue: [showAlternate]
    
    (press [info] to close)
    2012-04-13 16:19:24.874 testUTApp[63477:f803] MainViewController - togglePopover by [<UIBarButtonItem: 0x6e40440>]
    
    In my app where this is NOT working i have identical code for all popover interactions (same delegate methods, etc.) and I have identical toggle* code. I also have identical segue definition and configuration in storyboard. The only difference seems to be that the button to invoke is in the back-button location on the navigation bar (left side vs. right side).

    In my non-working app (popovers keep starting causing a wonderfully deep shadow over time ;-) the toggle IBAction is not being called but the perform segue is being called both times!

    I so need a clue here!!! ;-)

    Regards,
    IronSheep
    --
    http://9CardGolf.ironsheep.biz
     
  13. IronSheep macrumors newbie

    Joined:
    Apr 13, 2012
    Location:
    Colorado, USA
    #13

Share This Page