简体   繁体   English

斯威夫特| 关闭ViewController并推送其他ViewController

[英]Swift | Dismiss ViewController and Push other ViewController

Solved it: I forgot to declare tvx.selectionDelegate = self in VC1, thats why it never executed 解决了它:我忘了在VC1中声明tvx.selectionDelegate = self,这就是为什么它从未执行

I'v searched very long and fund two similar answers to my problem online: here 我搜索了很长时间,并在线为我的问题提供了两个类似的答案: 这里

But all of them work with dismissing and then presenting another view, and I want to dismiss and PUSH another ViewC. 但是所有这些都可以先关闭然后再显示另一个视图,我想关闭另一个PUB,然后按下另一个ViewC。

I have 3 ViewController: 我有3个ViewController:

VC1 lets Call it: DownloadsViewController VC1可以调用它:DownloadsViewController

VC2 lets Call it: SelectActionController VC2可以调用它:SelectActionController

VC3 lets Call it: fileInfoView VC3可以调用它:fileInfoView

VC1 presents VC2 modally then VC2 should dismiss and VC1 should PUSH VC3 immediately. VC1模态呈现VC2,然后VC2应该关闭,而VC1应该立即按下VC3。


I've tried: 我试过了:

VC2: VC2:

self.present(vx, animated: true, completion: nil) 

and the to put the PUSH animation in completion {} but it crashes. 并将PUSH动画放入完成{},但它崩溃了。


The next thing I've tried is to make a delegate and if I press a button on VC2 it call VC1 to dismiss VC2 and Push VC3. 我尝试的下一件事情是创建一个委托,如果我按VC2上的一个按钮,它将调用VC1以关闭VC2并按下VC3。 Like Here: 像这儿:

VC2: VC2:

protocol PushViewControllerDelegate: class {
func pushViewController(_ controller: UIViewController)
}

class SelectActionController: UIViewController, UITableViewDelegate, UITableViewDataSource {
weak var delegate: PushViewControllerDelegate?

public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{

    if self.delegate != nil {
        self.delegate?.pushViewController(self)}

VC1: VC1:

func pushViewController(_ controller: UIViewController) {

        controller.dismiss(animated: true) { () -> Void in

            self.performSegue(withIdentifier: self.segue2, sender: nil)

            //let vx = self.storyboard?.instantiateViewController(withIdentifier: "FileInfo") as! fileInfoView
            //self.navigationController?.pushViewController(vx, animated: false)

        }
    }

The Trird thing I tried was to make a global Variable and if it dismisses, just set a Bool variable to true and an func in VC1 should recognize it(my intention). 我尝试过的Trird方法是创建一个全局变量,如果将其忽略,只需将Bool变量设置为true即可,并且VC1中的func应该可以识别它(我的意图)。 Only problem it doesn't regognize dismissing as ViewDidAppear or stuff like that. 唯一的问题是它不会将其视为ViewDidAppear或类似的东西。


So none of that worked. 因此,这些都不起作用。

Does anyone has an Idea to this? 有人对此有想法吗?

EDITED after OP comment OP评论后编辑

Just use a protocol. 只需使用协议即可。 Let your first controller adopt it, and add the required function. 让您的第一个控制器采用它,并添加所需的功能。 Set a protocol variable in the second controller who takes the first one for reference and call the function when you dismiss the second controller. 在第二个控制器中设置一个协议变量,该控制器变量将第一个作为参考,并在您关闭第二个控制器时调用该函数。 You can now use the dismiss function to do whatever you want, pass data, send to an other controller... 现在,您可以使用dismiss函数执行所需的任何操作,传递数据,发送到其他控制器...

first view controller : 第一视图控制器:

protocol CustomProtocol {
    func dismissed()
}

class AViewController: UIViewController, CustomProtocol {

    @IBOutlet weak var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func toVC2(_ sender: UIButton) {
        let VC = self.storyboard!.instantiateViewController(withIdentifier: "BViewController") as! BViewController
        VC.customProtocol = self
        VC.view.backgroundColor = .white
        self.present(VC, animated: true, completion: nil)
    }

    func dismissed() {
        let yourViewController = UIViewController()
        yourViewController.view.backgroundColor = .red
        guard let navigationController = self.navigationController else {return}
        navigationController.pushViewController(yourViewController, animated: true)
    }
}

second view controller : 第二个视图控制器:

class BViewController: UIViewController {

    var customProtocol: CustomProtocol?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func quit(_ sender: UIButton) {
        self.dismiss(animated: true) {
            guard let proto = self.customProtocol else {return}
            proto.dismissed()
        }
    }
}

I hope you need to perform the dismiss action on your 我希望您需要对自己执行撤消操作

public func tableView(_ tableView: UITableView, didSelectRowAt indexPath:

in "SelectActionController" right ? 在“ SelectActionController”中对吗?

In such case you have to do as follows, 在这种情况下,您必须执行以下操作,

public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 公共功能tableView(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath){

if self.delegate != nil {
     dismiss(animated: true) {
        self.delegate?.pushViewController(self)}
    }
}

I have shared an example project related to your situation, please refer it. 我已经分享了一个与您的情况有关的示例项目,请参考。 https://github.com/Bharath-MallowTech/StackoverflowSolutions/tree/master/viewcontrollerDismissAndPush https://github.com/Bharath-MallowTech/StackoverflowSolutions/tree/master/viewcontrollerDismissAndPush

Could you post some code on what you've been trying? 您能发布一些您尝试过的代码吗? What is self here? 这里的self是什么? Is it VC1 , VC2 or VC3 ? VC1VC2还是VC3

What you could do is have a look at protocols, so you use VC1 as a delegate and when you dismiss VC2 it will also call it's delegate showVC3() . 您可以做的是看一下协议,因此您将VC1用作delegate并且在关闭VC2也将其称为委托showVC3() You then place that delegate.showVC3() in the completion block for your dismiss . 然后, delegate.showVC3()您的delegate.showVC3()放置在完成块中,以进行dismiss

// Declare it in VC1
@protocol MyDelegate {
    func showVC3()
}

class VC1: UIViewController, MyDelegate {
    var vc2: VC2ViewController = VC2ViewController()
    var vc3: VC3ViewController = VC3ViewController()

    func showVC2() {
        vc2.delegate = self
        self.present(self.vc2)
    }

    func showVC3() {
        self.present(self.vc3)
    }
}

// In VC2
class VC2: UIViewController {
    var delegate: MyDelegate?

    func closeVC2() {
        self.dismiss(animated: true, completion: {
            self.delegate?.showVC3()
        })
    }
}

Not sure if this works, haven't tried it out since I'm on my PC at the moment. 不确定是否可行,因为我目前在电脑上,所以没有尝试过。 But change it according to your needs and test it out. 但是根据您的需要进行更改并进行测试。

According to your File from Github, I think you forgot to declare 根据您来自Github的文件,我认为您忘记声明了

tvx.selectionDelegate = self

in the 在里面

func imagePressed

Even i had the same situation , that after presenting a view controller , i need to push to some other view controller. 甚至我也有同样的情况,即在呈现视图控制器之后,我需要推送到其他视图控制器。 If we have vc1, vc2, vc3, We presented vc2 from vc1, then on button click of vc2 we need to push to vc3, what i did is, i set vc3 as root view controller. 如果我们有vc1,vc2,vc3,我们从vc1中展示了vc2,那么在单击vc2的按钮时,我们需要推送到vc3,我所做的是,我将vc3设置为根视图控制器。 You can check code as per below. 您可以按照以下方式检查代码。

func goToHomeScreenPage(transition : Bool)
{
    let _navigation : UINavigationController!

    let startVC : TabbarViewController = Utilities.viewController(name: "TabbarViewController", onStoryboard: StoryboardName.Login.rawValue) as! TabbarViewController

    _navigation = UINavigationController(rootViewController: startVC)

    _navigation.setNavigationBarHidden(true, animated: true)

    let transitionOption = transition ? UIViewAnimationOptions.transitionFlipFromLeft : UIViewAnimationOptions.transitionFlipFromLeft
    gotoViewController(viewController: _navigation, transition: transitionOption)

}

the above method gotoviewcontroller() is below, 上面的方法gotoviewcontroller()在下面,

func gotoViewController(viewController: UIViewController, transition: UIViewAnimationOptions)
{
    if transition != UIViewAnimationOptions.transitionCurlUp
    {
        UIView.transition(with: self.window!, duration: 0.5, options: transition, animations: { () -> Void in
            self.window!.rootViewController = viewController
        }, completion: { (finished: Bool) -> Void in
            // do nothing
        })
    } else {
        window!.rootViewController = viewController
    }
}

Declare var window: UIWindow? 声明var window: UIWindow? on top, you can write these methods in appdelegate and call them by creating appdelegate instance. 最重要的是,您可以在appdelegate中编写这些方法,并通过创建appdelegate实例来调用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM