Swift4,如何通过在当前视图控制器的子视图中以编程方式创建的单击按钮呈现另一个视图控制器

时间:2018-02-02 05:59:43

标签: swift swift4

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

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

我尝试使用控制拖动来创建从原始控制器到目标控制器的segue,并尝试使用 self.performSegue(withIdentifier:&#34; showMealTable&#34;,sender:self)进行导航。< / p>

但它在运行时抛出错误说&#34; ..没有带标识符的segue&#39; showMealTable&#39;&#39;&#34;

这是我的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

3 个答案:

答案 0 :(得分: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并使用委托模式。

答案 1 :(得分:0)

根据定义,segue不能独立于故事板而存在。即使你看到了这个类的名字:UIStoryboardSegue。您不能以编程方式创建segue,但您可以做的是在storyboard中设置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];
}

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

答案 2 :(得分:0)

您可以使用代码执行此操作...

 @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,而不是调用执行segue。