Swift:从视图中获取价值的最佳方式

Swift: Best way to get value from view

我有一个自定义 UIView(称为 GridView),我对其进行了初始化,然后将其添加到 ViewController(详细信息ViewController)。 GridView 包含几个 UIButtons,我想在 DetailViewController 中知道这些按钮何时被触摸。我是 Swift 的新手,想知道获取这些事件的最佳模式是什么?

我认为你最好创建一个名为 GridView 的 class,它继承自 UIView。然后,您可以将所有 UI 元素与 class 连接为 IBOutlet 或任何使用类似标签的东西。稍后,您可以在 DetailViewController 中询问 GridView 的实例,以便您可以连接为 IBAction

封装是OOP的原则之一。

假设您的 GridView 实现如下所示:

class GridView : UIView {
    // Initializing buttons
    let button1:UIButton = UIButton(...)
    let button2:UIButton = UIButton(...)
    // ...

    // Adding buttons to view
    self.addSubview(button1)
    self.addSubview(button2)
    // ... 
}

现在,我们将添加将在触摸按钮时调用的选择器方法。让我们假设您的视图控制器的实现如下所示:

class DetailViewController : UIViewController {
    let myView:GridView = GridView(...)

    myView.button1.addTarget(self, action: "actionForButton1:", forControlEvents: UIControlEvents.TouchUpInside)
    myView.button2.addTarget(self, action: "actionForButton2:", forControlEvents: UIControlEvents.TouchUpInside)
    // ...

    func actionForButton1(sender: UIButton!) {
        // Your actions when button 1 is pressed
    }
    // ... Selectors for other buttons
}

我不得不说我的示例方法不是面向对象编程封装原则的一个很好的例子,但我这样写是因为你是新手Swift 而且这段代码很容易理解。如果你想防止重复代码,例如为每个按钮编写不同的选择器,如果你想将视图的属性设置为私有以防止来自 "outside" 的访问,就像我刚刚在 DetailViewController 中所做的那样,有更好的解决方案。我希望它能帮助你!

如果您想对通知执行此操作,请使用 1:

func postNotificationName(_ notificationName: String,
    object notificationSender: AnyObject?)

在您的按钮触发的方法中。然后,在您的 DetailViewController 中,在使用 2:

初始化时添加一个侦听器
func addObserver(_ notificationObserver: AnyObject,
    selector notificationSelector: Selector,
        name notificationName: String?,
      object notificationSender: AnyObject?)

这两个函数都可以从 NSNotificationCenter.defaultCenter() 调用。

另一种方法是在 DetailViewController 中初始化 GridView 后添加回调。回调本质上是一个闭包:

var callback : (() -> Void)?

您可以在需要时实例化,例如

// In DetailViewController initialization
gridView = GridView()
gridView.callback = { self.doSomething() }

GridView 中,您可以像这样触发回调:

func onButton()
{
    callback?()
}

回调只会在解包成功时执行。请确保您已阅读 Automatic Reference Counting,因为这些结构可能会导致强引用循环。

有什么区别?您只能连接一次回调(至少使用我在此处展示的方法),但当它触发时,接收方会立即执行其代码。对于通知,您可以有多个接收者,但事件传递会有一些延迟。