5

How can I find out when a NSTabViewItem has been changed, i.e. a user has changed the view of an NSTabView?

Ideally I want to generate a notification but any solution would be welcome.

pkamb
  • 33,281
  • 23
  • 160
  • 191
Kevin
  • 1,469
  • 2
  • 19
  • 28

2 Answers2

5

My original answer suggested to observe selectedTabViewItem of NSTabView, but that doesn't seem to work (on testing I can only get it to observe NSKeyValueObservingOptionInitial).

A probably smarter solution is to use a delegate. Implement tabView:didSelectTabViewItem: in the relevant controller.

Docs here.

Monolo
  • 18,205
  • 17
  • 69
  • 103
  • Do you mean like this: [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (stvi:) name:@"selectedTabViewItem" object: nil ]; 'stvi' being the method being called.. In that case, it doesn't work, no notification is being posted. – Kevin Mar 27 '12 at 08:09
  • Thanks for the reply, unfortunately, I am getting the error 'NSTabView' may not respond to '-addObserver:forKeyPath:context:' Any ideas? – Kevin Mar 27 '12 at 08:26
  • Also, when you mention the bindings, to what would you normally bind the tab view? I am working on OS X, so the iOS issues is not a problem till now.. – Kevin Mar 27 '12 at 08:29
  • 1
    Regarding bindings: you bind a property to another, so you could have a property in a controller object automatically change its value based on `selectedTabViewItem` in your view. Then you can either observe the controller property or do something useful in its setter method. – Monolo Mar 27 '12 at 08:39
  • The program will compile now, but there is no visible effect, i.e. no message being displayed where you listed //Do your stuff here above when I change the tabs... Obviously I put in some code, in my case, to log the event happening – Kevin Mar 27 '12 at 08:45
  • 1
    Completely changed my answer - sorry for any confusion. – Monolo Mar 27 '12 at 09:13
  • Thanks for the revision.. I'm new to delegates so I would need to research a little bit how to implement them.. I have been trying the bindings solution, however there is a problem that I cannot seem to overcome.. How can I bind to a method, rather than an object? In other words, I need to bind a value (say an integer?) to the method selectedTableViewItem. How would I go about doing that? Thanks a lot for your help Monolo! – Kevin Mar 27 '12 at 09:19
  • I am getting the following error when I try set the `delegate` of a `tabView`: *** Assertion failure in -[NSTabView setDelegate:], Failed to set (contentViewController) user defined inspected property on (NSWindow): A TabView managed by a TabViewController cannot have its delegate modified – J.beenie May 08 '19 at 01:56
2

Here is an example in Swift 3.

Create a custom class for your NSTabViewController which acts as delegate of NSTabView. The NSTabViewController class already implements the NSTabViewDelegate protocol.

class CustomTabViewController: NSTabViewController {
    override func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) {
        let identifier = tabViewItem?.identifier as? String
        print(identifier)
    }

}

Then in Interface Builder:

  1. Assign the custom class you created to your Tab View Controller in the Identity Inspector in the right panel
  2. In the interface hierarchy panel on the left, control drag from the Tab View to the Custom Tab View Controller (the name will depend on your custom class) and select delegate from the little popover that appears

You can also implement other methods in your delegate as explained in the documentation of NSTabViewDelegate.

Pier
  • 10,298
  • 17
  • 67
  • 113