【问题标题】:Swift: Creating a button that calls a method in another class1Swift:创建一个调用另一个类中的方法的按钮1
【发布时间】:2015-06-18 14:28:49
【问题描述】:

我有 2 个类,第一个类名为“store”,我在其中创建了一个调用方法的按钮:“storeSelected” 位于第二个类中,名称为 ExploreViewController
该方法应该打印“完成”并将我带到另一个视图控制器。 如果没有打印“完成”的 segue,但是在放置 segue 代码时,应用程序会崩溃。

错误是:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<Glam.ExploreViewController: 0x14ed3be20>) has no segue with identifier 'ok'' .........

// ExploreViewController Class

let _sharedMonitor: ExploreViewController = { ExploreViewController() }()

class ExploreViewController: UIViewController, UIScrollViewDelegate {

    class func sharedMonitor() -> ExploreViewController {
        return _sharedMonitor
    }


    func storeSelected(sender: UIButton) {                        
        println("done") // it entered here and "done" is printed                                                                   
        self.performSegueWithIdentifier("ok", sender: self) //here is the problem                           
    }
}







// another class named "Store"  
// button is created

let monitor = ExploreViewController.sharedMonitor()
btn.addTarget(monitor, action: Selector("storeSelected:"), forControlEvents: UIControlEvents.TouchUpInside)

【问题讨论】:

  • 你确定有一个手动的segue,标识符“ok”链接到你的ExploreViewController 吗?
  • 是的,我有,例如,当我将 segue 放入 viewdidload 时它工作正常。 @Wezly
  • ExploreViewController 中处理按钮事件是否有特定原因? - 我会从Store 执行此操作,然后从Store 添加第二个手动segue 到您想去的任何地方。
  • Store类是UIView类型的类,我可以在里面放segue代码吗? @Wezly
  • 啊 - 我不知道。你应该在当前可见的 View Controller 中处理 segue,我假设你的 Store 对象在某个地方?

标签: ios objective-c swift ios8 segue


【解决方案1】:

假设您有一个视图控制器,您可以在其中创建 Store 对象 - 您应该将按钮操作传回此视图控制器,并从它添加一个 segue 到您想要的目的地。

最佳做法是使用一种协议,将按钮操作委托给它包含的 viewController,如下所示。

Store.swift

protocol StoreDelegate: NSObject {
    func didPressButton(button:UIButton)
}

class Store: UIView {

    weak var delegate:StoreDelegate!

    override init(frame:CGRect) {
        super.init(frame:frame)

        var button = UIButton()
        button.setTitle("button", forState: .Normal)
        button.addTarget(self, action: "buttonPress:", forControlEvents: .TouchUpInside)
        self.addSubview(button)
    }

    func buttonPress(button:UIButton) {
        delegate.didPressButton(button)
    }

}

ViewController.swift

class ViewController: UIViewController, StoreDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        addStoreObj()
    }

    func addStoreObj() {
        var store = Store()
        store.delegate = self // IMPORTANT
        self.view.addSubview(store)
    }

    func didPressButton(button:UIButton) {
        self.performSegueWithIdentifier("ok", sender: nil)
    }

}

此代码未经测试,但我希望您明白 - 您的 Store 对象将按钮按下活动委托给包含 ViewController 的对象,然后 ViewController 执行您在情节提要中附加到它的 segue .

【讨论】:

  • 这是委托设计模式的一个很好的例子,但我只是想知道这是否是执行此操作的唯一方法(尽管我可以看到它是最佳实践)?我正在考虑通过引用传递 ViewController,但我可以看到它很糟糕。
  • 另一种方法可能是将闭包从主视图控制器传递到存储视图,但您仍然需要从视图控制器中操作 segue,因此,可能仍需要传递引用。跨度>
  • 太棒了,谢谢!人们不要忘记:store.delegate = self
  • 'buttonPress' 方法没有被调用的原因是什么?
  • 另外不要忘记在你的代码中这样做:protocol StoreDelegate : class { ...} 也定义弱 var delegate:StoreDelegate?避免内存泄漏
猜你喜欢
  • 1970-01-01
  • 2020-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多