【问题标题】:Swift | Dismiss ViewController and Push other ViewController斯威夫特 |关闭 ViewController 并推送其他 ViewController
【发布时间】:2017-09-29 14:16:15
【问题描述】:

已解决:我忘记在 VC1 中声明 tvx.selectionDelegate = self,所以它从未执行过

我搜索了很长时间,并在网上为我的问题提供了两个类似的答案: here

但所有这些都与关闭然后呈现另一个视图一起工作,我想关闭并推送另一个 ViewC。

我有 3 个 ViewController:

VC1 叫它:DownloadsViewController

VC2 让我们称之为:SelectActionController

VC3 让我们称之为:fileInfoView

VC1 以模态方式呈现 VC2,然后 VC2 应关闭,VC1 应立即推送 VC3。


我试过了:

VC2:

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

然后将 PUSH 动画置于完成状态 {} 但它会崩溃。


我尝试的下一件事是创建一个委托,如果我按下 VC2 上的一个按钮,它会调用 VC1 来关闭 VC2 并推送 VC3。喜欢这里:

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:

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)

        }
    }

我尝试的 Trird 是创建一个全局变量,如果它关闭,只需将 Bool 变量设置为 true,VC1 中的 func 应该会识别它(我的意图)。唯一的问题是它不会将解雇视为 ViewDidAppear 或类似的东西。


所以这些都不起作用。

有人对此有想法吗?

【问题讨论】:

  • 你能贴一些代码吗?
  • 将 PUSH 动画置于完成状态 {} 但它崩溃了。 - 错误消息是什么?您是否在主线程的完成块中添加该动画?
  • @EvertonCunha 哪个控制器或代码,如果有帮助,我什至可以分享整个代码?
  • 发布你的完成块代码。
  • @PranavKasetti 我做了

标签: ios swift xcode


【解决方案1】:

编辑在 OP 评论后

只需使用协议。 让您的第一个控制器采用它,并添加所需的功能。 在第二个控制器中设置一个协议变量,该变量将第一个控制器作为参考,并在您关闭第二个控制器时调用该函数。 你现在可以使用dismiss函数做任何你想做的事情,传递数据,发送到另一个控制器......

第一个视图控制器:

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)
    }
}

第二个视图控制器:

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()
        }
    }
}

【讨论】:

  • 问题不在于从 VC1 推送到 VC3 的代码。我知道很多方法可以做到这一点。问题是在关闭 VC2 时从 VC1 执行代码
  • 好吧,我不明白,我编辑了我的答案,这是我声明的协议的基本用法。希望对您的问题有所帮助
  • 你确定不需要把“guard let proto...”放在完成:在 2nd VC?
  • 我确实在第二个控制器中使用了保护语句
【解决方案2】:

根据你在 Github 上的文件,我想你忘了声明

tvx.selectionDelegate = self

func imagePressed

【讨论】:

    【解决方案3】:

    我希望您需要对您的

    执行关闭操作
    public func tableView(_ tableView: UITableView, didSelectRowAt indexPath:
    

    在“SelectActionController”中对吗?

    在这种情况下,您必须执行以下操作,

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

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

    我已经分享了一个与您的情况相关的示例项目,请参考。 https://github.com/Bharath-MallowTech/StackoverflowSolutions/tree/master/viewcontrollerDismissAndPush

    【讨论】:

    • 是的 didSelectRow 在 VC2 aka SelectActionController 中
    • @ChrisBerger:然后像共享的代码一样在解除块完成中执行委托调用。它对我来说很好。如果您需要参考,请查看链接中的项目。
    • 我什至无法构建应用程序 bc 它在 pushViewController(self) 中无法识别自我
    • @ChrisBerger:看来您对这个问题有多个答案,所以在这里给您一个小提示,我的建议是不要使用推荐的通知方法,因为由于时间原因我遇到了很多问题通知问题。
    • @ChrisBerger:你必须通过viewcontroller吗,通过viewcontroller有什么用吗?
    【解决方案4】:

    你能发布一些你一直在尝试的代码吗? self 这里是什么?是VC1VC2还是VC3

    您可以做的是查看协议,因此您将VC1 用作delegate,当您关闭VC2 时,它也将调用它的委托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()
            })
        }
    }
    

    不确定这是否有效,因为我现在在我的电脑上,所以没有尝试过。但是根据您的需要进行更改并进行测试。

    【讨论】:

    • 不起作用,我不知道为什么,我也尝试过只是打印smth。 out 但 func showVC3() 永远不会被执行。 Mybe 只适用于礼物。我再次希望它推动
    【解决方案5】:

    即使我有同样的情况,在呈现视图控制器之后,我需要推送到其他视图控制器。如果我们有 vc1、vc2、vc3,我们从 vc1 呈现 vc2,然后单击 vc2 的按钮,我们需要推送到 vc3,我所做的是,我将 vc3 设置为根视图控制器。您可以按照以下方式检查代码。

    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)
    
    }
    

    上面的方法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
        }
    }
    

    在上面声明var window: UIWindow?,可以将这些方法写在appdelegate中,通过创建appdelegate实例来调用。

    【讨论】:

      猜你喜欢
      • 2017-07-04
      • 2017-08-04
      • 1970-01-01
      • 1970-01-01
      • 2017-07-22
      • 2017-03-24
      • 2011-10-05
      • 2021-08-13
      • 1970-01-01
      相关资源
      最近更新 更多