【问题标题】:Swift4, How to present another view controller by click button which programmatically created inside current view controller's subviewSwift4,如何通过单击按钮呈现另一个视图控制器,该按钮以编程方式在当前视图控制器的子视图中创建
【发布时间】:2018-07-12 14:14:19
【问题描述】:

我在 UIStackView 中以编程方式创建了一些 UIButton。 StackView 是原始视图控制器的子视图。

如何通过点击按钮呈现另一个视图控制器?

我曾尝试控制拖动以创建从原始控制器到目标控制器的转场,并尝试使用 self.performSegue(withIdentifier: "showMealTable", sender: self) 进行导航。

但它在运行时抛出错误说 "..has no segue with identifier 'showMealTable''".

这是我的 StackView 类

@IBDesignable class TimeLineHeadControl: UIStackView {
   //MARK: Properties
   private let timeLineControllerInstance = TimeLineController()
   ....
   button.addTarget(self.timeLineControllerInstance, action: #selector(TimeLineController.breakfastButtonTapped(button:)), for: .touchUpInside)
   ....
}

还有我原来的视图控制器

class TimeLineController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        //self.performSegue(withIdentifier: "showMealTable", sender: self)
    }

    ...

    @objc func breakfastButtonTapped(button: UIButton) {
        print("at Time Line Controller")
        self.performSegue(withIdentifier: "showMealTable", sender: self)
    }
    ...

}

Created segue

error message here

【问题讨论】:

    标签: swift swift4


    【解决方案1】:

    先说说报错的原因吧。

    这里:

    private let timeLineControllerInstance = TimeLineController()
    

    您使用上述行创建的此 VC 与您在应用程序中看到的 VC 不同。这是TimeLineController 的另一个全新实例,未通过情节提要进行初始化。因此,它没有segue。

    您需要实际设置当前显示为timeLineControllerInstance的VC。

    但是,无论哪种方式,您都违反了 MVC 原则。 TimeLineHeadControl 是一个视图。视图不应依赖于控制器。视图可以发送消息(目标操作/委托),控制器可以选择收听这些消息。控制器选择要控制的视图,而不是相反。

    你真的应该在视图控制器中调用addTarget

    // in viewDidLoad
    yourStackView.button.addTarget(self, action: #selector(breakfastButtonTapped(button:)), for: .touchUpInside)
    

    或创建TimeLineHeadControlDelegate 并使用委托模式。

    【讨论】:

    • 谢谢!我刚刚实现了委托模式来实现这一点并通过 perfomSegue 函数进行导航。
    【解决方案2】:

    根据定义,segue 不能真正独立于故事板而存在。即使您看到类的名称:UIStoryboardSegue。您不能以编程方式创建 segue,但您可以做的是在情节提要中设置 segue,然后在该按钮上设置一个函数并使用该函数执行操作。

    此外,您甚至可以在不使用 segue 的情况下实现此目的。您可以在通用视图控制器(基类)中创建一个方法,该方法将转换到新的视图控制器。在您的情况下,基类可以是 MealViewController,新的视图控制器可以是 MealTableViewController。

    - (IBAction)pushNewViewController
    {
        NewViewController *newVC = [[NewViewController alloc] init];
    
        // do any setup you need for newVC like passing data.
    
        [self presentModalViewController:newVC animated:YES];
    }
    

    现在您可以在单击相应按钮时调用此方法。

    【讨论】:

      【解决方案3】:

      您可以通过使用代码来做到这一点...

       @objc func breakfastButtonTapped(button: UIButton) {
              print("at Time Line Controller")
                  let vc = self.storyBoard.instantiateViewController(withIdentifier: "yourVCidentifier") as! YourVC
              self.present(vc,animated: true, completion: nil)
          }
      

      如果你想用 segue 做到这一点.. 将storyBoard segue标识符提供给您的segue,然后调用perform segue。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-25
        • 1970-01-01
        • 2012-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多