【问题标题】:How can I link this button and this action programmatically?如何以编程方式链接此按钮和此操作?
【发布时间】:2014-11-11 03:03:47
【问题描述】:

目前我有两个简单的类,一个是容器视图控制器,一个是子视图控制器。我在 ContainerViewController.swift 文件中有一个操作,但需要在 HomeViewController.swift 文件中调用它。我显然不能只打电话给ContainerViewController.presentDetailController(self),那我应该如何处理呢?

ContainerViewController.swift

import UIKit

class ContainerViewController: UIViewController {

    var currentDetailViewController: UIViewController?

    override init() {
        super.init()
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    convenience init(viewController: UIViewController) {
        self.init()

        currentDetailViewController = viewController
        self.presentDetailController(viewController)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        var homeViewController: HomeViewController = HomeViewController.alloc()
        self.presentDetailController(homeViewController)
    }

    override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() }

    func presentDetailController(detailViewController: UIViewController) {
        if((self.currentDetailViewController) != nil) {
            self.removeCurrentDetailViewController();
        }

        self.addChildViewController(detailViewController)

        detailViewController.view.frame = self.frameForDetailController()

        self.view.addSubview(detailViewController.view)
        self.currentDetailViewController = detailViewController

        detailViewController.didMoveToParentViewController(self)
    }

    func removeCurrentDetailViewController() {
        self.currentDetailViewController?.willMoveToParentViewController(nil)
        self.currentDetailViewController?.view.removeFromSuperview()
        self.currentDetailViewController?.removeFromParentViewController()
    }

    func frameForDetailController() -> CGRect {
        var detailFrame: CGRect = self.view.bounds

        return detailFrame
    }

}

HomeViewController.swift

import UIKit

class HomeViewController: UIViewController {

    func initView () {
        self.view.backgroundColor = UIColor.redColor()
        var button: UIButton = UIButton(frame: CGRectMake(20, 20, 50, 50))
        button.backgroundColor = UIColor.greenColor()
        button.addTarget(self, action: Selector("ContainerViewController.presentDetailController(self)"), forControlEvents: UIControlEvents.TouchDown) // This results in a fatal error!
        self.view.addSubview(button)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        initView();
    }
}

【问题讨论】:

  • 您必须使用委托将消息从子视图控制器传递回前一个视图控制器。 Reference question。您还可以从导航控制器获取视图控制器。
  • @zala 你能详细说明一下吗?我不确定我是否理解。
  • 是否要将动作从子控制器传回父控制器?
  • @zala 是的,没错。我需要从 HomeViewController.swift 文件中调用 ContainerViewController.swift 中的“presentDetailController”。

标签: ios swift uiviewcontroller


【解决方案1】:

我认为我们只能通过委托将消息传递回父视图控制器。可能还有其他方法,但这是唯一优雅的方法。

方法 - 1

1)

创建一个协议并在你的父视图控制器中实现

@interface ParentController : UIViewController <NaviagationDelegate>

@implementation ParentController
//implement method here
//{
// your action in parent controller
//}

2)

现在使用NaviagationDelegate在子控制器中创建属性

@property (nonatomic, weak) id <NaviagationDelegate> navigationDelegate;

在您的子控制器的事件操作上调用委托方法

    //Button action method
    {
        [self.navigationDelegate setText:@"action"];
    }

3) 在父视图控制器中将子控制器的delegate属性初始化为self

prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.destinationViewController isKindOfClass:[ChildContoller class]])
    {
        [segue.destinationViewController setNavigationDelegate:self];
    }
}

方法 - 2

通过检查从self.navigationController.viewControllers到parentController类的所有控制器来获取父控制器的引用。

【讨论】:

  • 实现将与委托的语法更改相同。我希望你也已经为 swift 编写了一些代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多