2015-01-20 2 views
0

У меня есть пользовательский UIView (называемый GridView), который я инициализирую, а затем добавляю в ViewController (DetailViewController). GridView содержит несколько UIButtons, и я хотел бы знать в DetailViewController, когда эти кнопки касаются. Я новичок в Swift, и мне интересно, какой лучший образец использовать для получения этих событий?Swift: Лучший способ получить значение из вида

+0

Кажется, что NSNotificationCenter будет одним из способов. Любые конкретные советы о том, как реализовать, будут оценены. – colindunn

ответ

1

Если вы хотите сделать это с помощью уведомлений, используйте 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().

Другим методом было бы добавить обратные вызовы, которые вы подключаете после инициализации GridView в DetailViewController. Обратный вызов является, по существу, закрытием:

var callback : (() -> Void)? 

, который вы можете создать при необходимости, например.

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

В GridView вы можете вызвать функцию обратного вызова, как это:

func onButton() 
{ 
    callback?() 
} 

Обратный вызов будет только выполнять, если разворачивание успешно. Убедитесь, что вы прочитали Automatic Reference Counting, потому что эти конструкции могут привести к сильным опорным циклам.

В чем разница? Вы можете подключить обратный вызов только один раз (по крайней мере, с помощью метода, который я показал здесь), но когда он запускается, приемник немедленно выполняет свой код. Для уведомлений вы можете иметь несколько приемников, но есть некоторая задержка в доставке событий.

+0

Спасибо! Я не знал о обратных вызовах. Оба варианта кажутся жизнеспособными. – colindunn

+1

Вы также можете сделать «делегат», если у вас много кнопок, которые имеют смысл, это может быть более полезным, чем подключение большого количества обратных вызовов. –

0

Я думаю, вам лучше создать класс под названием GridView, который унаследован от UIView. Затем вы можете подключить все элементы UI к вам классом, как IBOutlet, или что-то вроде тега. Позже вы можете запросить экземпляр GridView в DetailViewController, чтобы вы могли подключиться как IBAction.

Инкапсуляция является одним из принципов ООП.

1

Давайте предположим, что ваш 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, и этот код легко понять. Если вы хотите предотвратить дублирование кодов, таких как написание разных селекторов для каждой кнопки, и если вы хотите, чтобы свойства вашего представления были приватными, чтобы предотвратить доступ извне, как это я делал только в DetailViewController, есть гораздо лучшие решения. Надеюсь, это просто поможет вам!

Смежные вопросы