为啥我没有成功以编程方式使用 segue?

Posted

技术标签:

【中文标题】为啥我没有成功以编程方式使用 segue?【英文标题】:Why I am not successfull to use segue programmatically?为什么我没有成功以编程方式使用 segue? 【发布时间】:2021-07-04 17:36:57 【问题描述】:

我正在为 ScreenOne 使用情节提要,而我没有为 ScreenTwo 使用情节提要,我以编程方式进行编码,到目前为止对我来说没有问题,但我仍然没有成功声明 ScreenTwo 的“storyboardIdentifier”。 Here 有一个例子,但我不明白我将如何在应用程序内部处理这个例子。任何想法将不胜感激。

截图:

ScreenTwo:

class ForgotPasswordEmailCheckController: UIViewController 
  var storyboardId: String 
    return (value(forKey: "ForgotPasswordEmailCheckController") as? String)!
  

【问题讨论】:

这能回答你的问题吗? Segue without StoryBoard @EmilioPelaez,我也尝试过,但没有解决。我知道很多类似的问题,但它们有助于解决 请分享您以编程方式初始化 screenTwo 的代码 @abh,请稍等,我会更新 :) 【参考方案1】:

Storyboard 控制器(也将此控制器嵌入到导航控制器中):

class FirstVC: UIViewController 
    @IBOutlet weak var btn: UIButton!
    
    override func viewDidLoad() 
        super.viewDidLoad()
        btn.addAction(UIAction(handler:  action in
            
            let secondVC = SecVC()
            self.navigationController?.pushViewController(secondVC, animated: true)
        ), for: .touchUpInside)
    

第二个视图控制器:

class SecVC: UIViewController 
        
    override func viewDidLoad() 
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.blue
    

【讨论】:

让我试试,tnx :) btn?你在哪里声明的? 在您的第一个视图控制器中。不要忘记将它嵌入到导航控制器中,否则它将无法导航。 很抱歉我没听清楚,你可以更新你的答案吗?我在 SecVC 中声明了 btn.addAction...,但是我将如何声明 btn,在哪里? 它正在运行,但是当我单击 btn 时,它会抛出错误为“由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'-[SegueApp.ViewController btn:]:无法识别的选择器已发送到实例 0x7f819ce08690 '"【参考方案2】:

这是以编程方式实现的:

在 sceneDelegate 中设置你的初始导航控制器:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 
    guard let windowScene = (scene as? UIWindowScene) else  return 
    
    window = UIWindow(windowScene: windowScene)
    window?.makeKeyAndVisible()
    let controller = UINavigationController(rootViewController: MyController())
    window?.rootViewController = controller

现在在 firstController 中配置你的 navigationBar,使用我的扩展来做:

extension UIViewController 

func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) 
    
    if #available(ios 13.0, *) 
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.backgroundColor = backgoundColor
        
        navigationController?.navigationBar.standardAppearance = navBarAppearance
        navigationController?.navigationBar.compactAppearance = navBarAppearance
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
        
        navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
        navigationItem.largeTitleDisplayMode = .always
        navigationController?.navigationBar.tintColor = tintColor
        navigationItem.title = title
        
     else 
        // Fallback on earlier versions
        navigationController?.navigationBar.barTintColor = backgoundColor
        navigationController?.navigationBar.tintColor = tintColor
        navigationController?.navigationBar.isTranslucent = false
        navigationItem.title = title
    
  

这是你的第一个控制器的样子:

class MyController: UIViewController 

let button = UIButton() // declare your button

override func viewDidLoad() 
    super.viewDidLoad()
    
    configureNavigationBar(largeTitleColor: .white, backgoundColor: .black, tintColor: .white, title: "My Vc", preferredLargeTitle: true) // set nav bar with exetnsion
    
    view.backgroundColor = .white
        
    view.addSubview(button)
    button.backgroundColor = .systemBlue
    button.layer.cornerRadius = 9
    button.setTitle("My Button", for: .normal)
    button.addTarget(self, action: #selector (handelGoToSecondVc), for: .touchUpInside)
    button.translatesAutoresizingMaskIntoConstraints = false
    
    button.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16).isActive = true
    button.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16).isActive = true
    button.heightAnchor.constraint(equalToConstant: 50).isActive = true
    button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
    

    
@objc func handelGoToSecondVc() 
    let controller = SecondController()
    controller.title = "second Vc"
    navigationController?.pushViewController(controller, animated: true)
 

第二个控制器:

class SecondController: UIViewController 

override func viewDidLoad() 
    super.viewDidLoad()
    
    view.backgroundColor = .green
 

这是结果:

完整代码:

import UIKit

class MyController: UIViewController 

let button = UIButton() // declare your button

override func viewDidLoad() 
    super.viewDidLoad()
    
    configureNavigationBar(largeTitleColor: .white, backgoundColor: .black, tintColor: .white, title: "My Vc", preferredLargeTitle: true) // set nav bar with exetnsion
    
    view.backgroundColor = .white
        
    view.addSubview(button)
    button.backgroundColor = .systemBlue
    button.layer.cornerRadius = 9
    button.setTitle("My Button", for: .normal)
    button.addTarget(self, action: #selector (handelGoToSecondVc), for: .touchUpInside)
    button.translatesAutoresizingMaskIntoConstraints = false
    
    button.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16).isActive = true
    button.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16).isActive = true
    button.heightAnchor.constraint(equalToConstant: 50).isActive = true
    button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
    

    
@objc func handelGoToSecondVc() 
    let controller = SecondController()
    controller.title = "second Vc"
    navigationController?.pushViewController(controller, animated: true)
 


class SecondController: UIViewController 

override func viewDidLoad() 
    super.viewDidLoad()
    
    view.backgroundColor = .green
 


extension UIViewController 

func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) 
    
    if #available(iOS 13.0, *) 
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.backgroundColor = backgoundColor
        
        navigationController?.navigationBar.standardAppearance = navBarAppearance
        navigationController?.navigationBar.compactAppearance = navBarAppearance
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
        
        navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
        navigationItem.largeTitleDisplayMode = .always
        navigationController?.navigationBar.tintColor = tintColor
        navigationItem.title = title
        
     else 
        // Fallback on earlier versions
        navigationController?.navigationBar.barTintColor = backgoundColor
        navigationController?.navigationBar.tintColor = tintColor
        navigationController?.navigationBar.isTranslucent = false
        navigationItem.title = title
    
  

【讨论】:

tnx 这么多,我将在哪里使用扩展 UIViewController ...? @Skysoft13 将其复制并粘贴到您的控制器类下面...我用完整的代码更新我的答案。 它的工作方式非常类似于 tnx,但如果你看问题,我的 ViewController 不是以编程方式编写的,我有情节提要和 SecondView 控制器以编程方式编写。如果您查看其他答案,这是根据我的问题,但它不起作用,我们是否有可能像这样申请? @Skysoft13 当然可以!使用我的扩展配置导航栏,在 sceneDelegate 中设置启动导航控制器(只需替换控制器的名称,例如:删除 MyController() 并粘贴到 ViewController() ),删除我的按钮声明及其在 viewDidLoad 中的设置和约束使用您的 IBOutlet 及其设置和约束,像我的代码一样设置按钮目标...如果您需要我的建议,请以编程方式进行,您将完全控制场景中的对象... tnx 这么多,我非常感谢你的帮助,tnx 这么多:)

以上是关于为啥我没有成功以编程方式使用 segue?的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式展开 Segue?

Segue 和 Button 以编程方式快速

在 Swift 中以编程方式制作 Segue

在没有按钮连接的情况下以编程方式执行 Segue?

无法以编程方式执行 segue

为啥我在c编程中不能成功使用return选项?