How to set a tab bar item's title from a child view controller in interface builder? - interface-builder

I know programmatically I can set a child view controller's title and it will updated its related tab bar item's title but how do I set that up in Interface Builder?

Interface Builder doesn't have an exposed property for a view controllers title but it does allow you to set properties in the "User Defined Runtime Attributes" section under Identity Inspector tab. Just set the key path to title, type to String, and Value to your desired title. Also check out Apple's documentation. Or check out this blog for a visual walkthrough: http://ios-blog.co.uk/tutorials/user-defined-runtime-attributes/
You can also have finer grain control by setting these different properties:
self.navigationItem.title = #"my title"; //sets navigation bar title.
self.tabBarItem.title = #"my title"; //sets tab bar title.
self.title = #"my title"; //sets both of these.

Related

Change the title of the navigation bar when user taps on it

I'm quite new in swift programming but couldn't find an answer to the question how to change the title of the navigation bar when the user taps on it (see example app "ToDo" from Microsoft [former Wunderlist]). So first I choose the "Item A" out of a tableview and in the following screen the title stands in the navigation bar - so far so good. With a tap on this title "Item A" it should be possible to change the title (also for the previous tableview with the list of items by saving the changes in Realm). For now I just use the commands
title = selectedItem!.title
in my viewDidLoad in the upcoming view controller where .title equals the title from my "Item"-class
class Item: Object {
var parentCatergory = LinkingObjects(fromType: Category.self, property: "items")
#objc dynamic var title: String = ""
}
Any ideas? Or do I have to use a customized navigation bar, if so how?
Thanks in advance!
According to the UIViewController lifecycle, anything that you add to the method viewDidLoad() will be executed once when the view is loaded. If you want to change the title property on demand on a ViewController, is necessary invoke the navigation bar title property again from your tab action method. Check this post for more information: How to set the title of a Navigation Bar programmatically?

Hide NSWindow New tab button

In macOS 10.12 there is a new tab bar that is added to NSWindows for NSDocument apps. You can prevent the toolbar from appearing (see How do I disable the Show Tab Bar menu option in Sierra apps?). But how to remove the "+" button for adding new Windows?
According to the AppKit release notes, returning false for responding newWindowForTab(_:) action message in a NSDocumentController subclass disables "+" button in the tab bar.
override func responds(to aSelector: Selector!) -> Bool {
if #available(OSX 10.12, *) {
if aSelector == #selector(NSResponder.newWindowForTab(_:)) {
return false
}
}
return super.responds(to: aSelector)
}
See "New Button" section in the AppKit Release Notes for macOS 10.12.
Depends of your Application functionality you may subclass NSDocumentController and return empty array for documentClassNames property.
class MyDocumentController: NSDocumentController {
override var documentClassNames: [String] {
return [] // This will disable "+" plus button in NSWindow tab bar.
}
}
Here is a documentation of the documentClassNames property:
documentClassNames
An array of strings representing the custom document classes supported by this app.
The items in the array are NSString objects, each of which represents the name of a document subclasses supported by the app. The document class names are derived from the app’s Info.plist. You can override this property and use it to return the names of document classes that are dynamically loaded from plugins.
Source
And here is explanation how documentClassNames property affects NSWindow tab bar plus button appearance:
New Button
The plus button will be shown if newWindowForTab: is implemented in the responder chain. NSDocumentController informally implements newWindowForTab:, but only returns YES from respondsToSelector: for this selector if the self.documentClassNames.count > 0 and if the app has a default new document type. In other words, it only responds to it if NSDocument has at least one registered document class name which can be edited.
Source
Just set ‘Tabbing Mode’ to Disallowed in Interface Builder for your NSWindow.
Change this
#IBAction override func newWindowForTab(_ sender: Any?) {}
into this
#IBAction func myButton(_ sender: Any?) {}
This will hide the plus button. The tabbing still works

programmatically created NSMenu is only showing the first item

I am writing a Mac app with minimal IB usage -- see programatically create initial window of cocoa app (OS X).
Here is my code (via Xamarin/C#):
public override void DidFinishLaunching(NSNotification notification) {
// create and show a window, then . . .
NSMenu fileMenu = new NSMenu();
NSMenu appMenu = new NSMenu();
// add some items to both menus, then . . .
NSMenuItem file = new NSMenuItem("file");
file.Submenu = fileMenu;
NSMenuItem app = new NSMenuItem("app");
app.Submenu = appMenu;
NSMenu topLevelMenu = new NSMenu();
topLevelMenu.AddItem(app); // these two lines in
topLevelMenu.AddItem(file); // either order
NSApplication.SharedApplication.Menu = topLevelMenu; // incidentally, setting the MainMenu doesn't appear to do anything
}
}
The weird thing is that only the first menu item I add shows up, and its title is changed to the name of my app. So for the above code, I would see the app menu, only, with a title of MyAppName, but the correct items. If I were to instead add the file NSMenuItem first, I would see that menu, again with its name changed to my app name, and the view menu would not show up at all.
I don't mind the changed title; I suppose Apple wants to always show the name of the active app. But it bugs me that I can't get the additional menus to appear.
How can I get all of my menus to show up across the top of the screen?
I just needed to add titles to my menus:
fileMenu.Title = "file";
appMenu.Title = "whatever";
The title of the first one is still changed to the name of the app.

Automatic Styling/Tinting of NSToolbarItem

Is there a way to tell OS X to automatically style/tint a NSToolbarItem?
I've added an "Image Toolbar Item" via IB/Xcode and set the icon to a black PDF as described in the documentation.
However, my result does not resemble that of, for instance, the App Store:
I'm looking for something akin to what the TabBar in iOS does by default.
I'm new to OS X development... So any guidance would be appriciated!
Images need to be made template'd in order to get the correct styling (such as the engraved & blue styling).
This can be done in code with -[NSImage setTemplate:] or by having your image names end with "Template" (requiring no code changes).
To get the blue styling specifically, you have to set a borderless NSButton as the custom view of the toolbar item (rather than it being a standard item). That button has to have a type that results in it showing its state (e.g. a Round-Textured Toggle button), and when it has an On state, it will get then blue styling.
If you're trying to create a tinted toolbar item in code, This is how I did it. Create the correct type of button NSButtonTypeToggle then set the buttons properties, then add the button to the toolbar item's custom view and finally the toolbar item is returned.
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSToolbarItemIdentifier)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag {
// create toolbar items
NSToolbarItem *toolbarItem = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
toolbarItem.label = #"title";
NSImage *iconImage = [NSImage imageNamed:NSImageNameColumnViewTemplate];
NSButton *button = [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 40.0, 40.0)];
button.title = #"";
button.image = iconImage;
[button setButtonType:NSButtonTypeToggle];
button.bezelStyle = NSBezelStyleTexturedRounded;
button.action = #selector(toggleColumnView:);
[toolbarItem setView:button];
return toolbarItem;
}

In Interface builder, how can I add a custom button to a window title bar?

In my OS X app, using Interface Builder, I have a window that looks like this:
I'd like to add a button to the right-hand side, to achieve this:
If this is possible, how can I do it?
It is not possible to do with Interface Builder, however you can get it done with little bit of coding :
NSButton *closeButton = [window standardWindowButton:NSWindowCloseButton]; // Get the existing close button of the window. Check documentation for the other window buttons.
NSView *titleBarView = closeButton.superview; // Get the view that encloses that standard window buttons.
NSButton *myButton = …; // Create custom button to be added to the title bar.
myButton.frame = …; // Set the appropriate frame for your button. Use titleBarView.bounds to determine the bounding rect of the view that encloses the standard window buttons.
[titleBarView addSubview:myButton]; // Add the custom button to the title bar.
Swift 2.2 and Auto Layout, Create an "OK" button to the right of the title bar:
let myButton = NSButton()
myButton.title = "OK"
myButton.bezelStyle = .RoundedBezelStyle
let titleBarView = window!.standardWindowButton(.CloseButton)!.superview!
titleBarView.addSubview(myButton)
myButton.translatesAutoresizingMaskIntoConstraints = false
titleBarView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[myButton]-2-|", options: [], metrics: nil, views: ["myButton": myButton]))
titleBarView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-1-[myButton]-3-|", options: [], metrics: nil, views: ["myButton": myButton]))
With auto layout, you don't need to hard-code button's frame. And it is always on the right of the title bar even you resize the window.

Resources