How to dismiss own view controller and present another view controller in a button tap?

前端 未结 4 815
耶瑟儿~
耶瑟儿~ 2020-12-15 12:47

Let\'s say I have 3 view controller labeled \"A\",\"B\" and \"C\". Right now, \"A\" is the rootViewController of the window and it presents \"B\" modally when a button is ta

相关标签:
4条回答
  • 2020-12-15 12:48

    It seems that it is not possible to go from B to C without showing A briefly, which looks unprofessional. However, you can put a black subview over top of A until you've animated to C.

    In Swift 3:

    class A : UIViewController {
        ...
        func showB() {
            // Adding the black view before dismissing B does not work;
            // the view is not displayed.
            let black = UIView()
            black.backgroundColor = UIColor.black
            black.frame = self.view.bounds // assumes A is not zoomed
    
            let b = B()
            self.present(b, animated:true, completion: {
                self.view.addSubview(black)
            })
    
            // Note: self.present() will start the animation,
            // then b.imDone will be set.  It is done here for
            // clarity of what happens next, as if it were all
            // one function.
            b.imDone = {
                b.dismiss(animated:false, completion: {
                    self.present(C(), animated:true, completion: {
                        black?.removeFromSuperview()
                    })
                })
            }
        }
    }
    
    class B : UIViewController {
        var imDone : (() -> Void)?
        ...
        func f()
        {
            imDone?()
        }
        ...
    }
    
    class C : UIViewController
    {
        ...
    }
    
    0 讨论(0)
  • 2020-12-15 13:05

    you can do using protocol let say for example as bellow:-

    In to your B viewController setting Protocol :

    @class Bviewcontroller;
    
    @protocol BviewControllerDelegate <NSObject>
    - (void)BviewcontrollerDidTapButton:
    (Bviewcontroller *)controller;
    
    @end
    
    @interface Bviewcontroller : UIViewcontroller
    
    @property (nonatomic, weak) id <BviewControllerDelegate> delegate;
    - (IBAction)ButtonTap:(id)sender;
    
    @end
    

    in .m class

    - (IBAction)ButtonTap:(id)sender
    {
        [self.delegate BviewcontrollerDidTapButton:self];
    }
    

    Now in to you A_viewController .h class:

    #import "Bviewcontroller.h"
    
    @interface A_viewController : UIViewcontroller<BviewControllerDelegate>
    

    .m class

    - (void)BviewcontrollerDidTapButton:
    (Bviewcontroller *)controller
    {
        [self dismissViewControllerAnimated:YES completion:^{
    
    
          // here you can create a code for presetn C viewcontroller 
    
        }];
    }
    

    IMPORTANT when you preseting Bviewcontroller from A_viewController do not set delegate with object like

    -(void)presentNextViewCon
    {
                    bViewcontroller *gestureViewCon = [[bViewcontroller alloc]init];
            gestureViewCon.delegate = self;
    
    [self presentViewController:gestureViewCon animated:YES completion:nil];
    
    }
    

    UPDATE

    Here it is i create a demo that working like:

    enter image description here

    SAMPLE CODE LINK http://speedy.sh/2acSC/modelDemo.zip

    0 讨论(0)
  • 2020-12-15 13:06

    You can not dismiss B and present C simultaneously.

    To perform this task you should follow some tasks.

    • On pressing button on 'B' , Dissmiss 'B' without animation and set an global BOOL variable to notify that you want to present 'C'.
    • On -(void)viewDidAppear:(BOOL)animated of 'A'

      if (bool){ [self presentViewController:c animated:YES completion:nil]; }

    0 讨论(0)
  • 2020-12-15 13:08

    You are taking about a Button lets name it controlButton. Pass that button with B and C with custom init method. That means your UIViewController A is having controllButton reference. Using the method

    - (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents 
    

    set the trigger block in A and like this

    [_controllButton addTarget:self action:@selector(controllButtonTapped:)....];
    
    - (void)controllButtonTapped:(id)sender {
    
        [self dismissViewControllerAnimated:YES completion:^{
    
            // present you c here
    
            [self presentViewController:c animated:YES completion:NULL];
        }];
    }
    

    But the best option is to go with “Mediator Design pattern” where a coordinator is coordinating your present and dismiss actions.

    0 讨论(0)
提交回复
热议问题