I am trying to create a new OS X application. I've got a table view where information should be displayed, underneath it there is a Segmented Control section with two buttons (+ and -).
I used this code to show up a dialog / modal:
#IBAction func addDevices(_ sender: NSSegmentedControl) {
let index = sender.selectedSegment
let controller = (self.view.window?.windowController as! MainWindowController)
controller.createNewDevices(sender)
print("works")
}
How can I differentiate between + button and - button pressed? At the moment, both buttons call up my dialog.
Thanks for your attention, I hope someone can help me!
P.S.: New to Stack, if I didn't post as you expected it, please let me know what I can do better!
You can use selectedSegment property.
var selectedSegment: Int
The index of the selected segment of the control, or -1 if no segment is selected.
Button "+" have index 0, and "-" have index 1.
You can do that:
switch sender.selectedSegment {
case 0: // do actions if "+"
case 1: // do actions if "-"
default: print("No actions for this button")
}
Related
I added a button in the main storyboard in Xcode. This button has an image as the background and its title "blueDoor" is shown on top of the background (see photo below).
There will be three buttons like this and they are linked to one IBAction. I would like to use sender.currentTitle to let the program know which button is clicked, but I don't want the text to show on the image.
How can I hide the text but still keep the title attribute so sender.currentTitle can be used? Or is there another way to do so?
A button with an image as the background:
You can use tag to do this.
Open storyboard > select your button > select Show the Attributes Inspector section in the right bar of the Xcode > scroll down and find Tag under the View section. And give different tags to your buttons.
Then your IBAction should be like this ->
#IBAction func didTapMyButtons(_ sender: UIButton) {
switch sender.tag:
case 0: // it is your first button's tag
// Do something with button which has tag `0`
case 1: // it is your second button's tag
// Do something with button which has tag `1`
case 2: // it is your third button's tag
// Do something with button which has tag `2`
default: break
}
Shortly: you can not do that. The currentTitle property is essentially a getter for button.titleLable.text. So is title(for: UIControl.State) setter (setTitle(String?, for: UIControl.State))
What docs say:
var currentTitle: String? { get }
Discussion
The value for this property is set automatically whenever
the button state changes. For states that do not have a custom title
string associated with them, this method returns the title that is
currently displayed, which is typically the one associated with the
normal state. The value may be nil.
This means whatever changes you bring to titleLabel.text, it is automatically reflected on a currentTitle property.
You can use tags as suggested or add a custom action handler for every button as you create them. E.g. for cancel and proceed buttons one will do it like so:
self.cancelButton.addTarget(self, action: #selector(self.cancelActionMethod), for: .touchUpInside)
self.proceedButton.addTarget(self, action: #selector(self.proceedActionMethod), for: .touchUpInside)
And then somewhere inside self:
#objc func cancelActionMethod() {
// some cancel specific actions
}
#objc func proceedActionMethod() {
// some cancel specific actions
}
I have a NSPopUpButton with a built up NSMenu.
However, when an NSMenuItem is selected, it keeps going back to the first item.
In this example, I'd expect "Maged" to be selected.
Any ideas?
Related question/answer: https://stackoverflow.com/a/53387962/157656
Duplicate:
It's been suggested that this is a duplicate of the question
How do I change/modify the displayed title of an NSPopUpButton
"I would like an NSPopUpButton to display a different title than the title of the menu item that is selected."
However, my question was about getting the NSPopUpButton to show the selected item.
In the end, I changed how I did it.
I am using a NSButton to show the menu and NSTextField to display the results.
If anyone is interested in the details, here they are.
Build the menu up and use .representedObject to store whatever you need to access at the other end. I used a struct with the name and code the in it.
You need to assign the NSMenu to the NSButton.menu
Then have a click, something like this.
#IBAction func changeVoiceClicked(_ sender: NSButton)
{
if let event = NSApplication.shared.currentEvent {
NSMenu.popUpContextMenu(sender.menu!, with: event, for: sender)
}
}
Your NSMenuItem should have an action on it, which using a selector points to a function.
Something like this:
#objc func voiceChanged(sender: NSMenuItem)
{
// cope will nil
var voice : VoiceDetail = VoiceDetail();
if (sender.representedObject != nil) {
voice = sender.representedObject as! VoiceDetail;
}
// Do what you need to on menu select.
// update text field.
}
in a navigation controller i have 2 bar button items linked in the StoryBoard: 1 on the right with System Item = Add and 1 on the left with System Item = Cancel. Both buttons are linked to the same action. how can i determine which one has been triggered using a switch statement?
#IBAction func pressedBarButtonItem(sender: UIBarButtonItem) {
switch sender {
case UIBarButtonSystemItem.Add:
print("UIBarButtonSystemItem.Add button has been pressed ...")
default:
break
}
}
this causes an error "Enum case "Add" is not a member of type 'UIBarButtonItem'" so is there an Enum attribute to the bar button that says it is a system type?
thanks
UIBarButtonSystemItem is used only at initialization to define a system image, those are not styles or types and are not stored or affected to the button.
You may want to use tags or outlet references to select the right action, or use different IBActions, which seems more appropriate.
Give tag to both the UIBarButtonItems in storyborad.
Say Add have tag value 1001 and Cancel have tag value 1002.
Compare tags in you IBAction.
#IBAction func pressedBarButtonItem(sender: UIBarButtonItem) {
switch sender.tag {
case 1001:
print("UIBarButtonSystemItem.Add button has been pressed ...")
case 1002:
print("UIBarButtonSystemItem.Cancel button has been pressed ...")
default:
break
}
}
I've tried a few times to set up several similar buttons, all connected to the same IBActions, and still can't seem to replicate the RadioButton Behaviour.
At the moment, I have 5 Buttons, all children of one NSView..
NSView
- ButtonOne - NSButton (Square Button)
- ButtonTwo - NSButton (Square Button)
- ButtonThree - NSButton (Square Button)
- ButtonFour - NSButton (Square Button)
- ButtonFive - NSButton (Square Button)
They're all connected to a common IBAction, which reads as:
#IBAction func activityButtonPressed(sender: NSButton) {
println("\(sender.title) Pressed")
}
Which works to the point where the actual mosueDown events are caught and sent to the func (as expected)..
how do I get them working in the Radio Button mode? i.e. have their NSOnState and NSOffState toggle when the various buttons are clicked?
When I try and change the button type to Radio Button, it automatically flips back to "Switch"....
Cheers,
A
just give the NSRadioButtons the same superview and action. And as noted by Good Doug in his answer,
[…] if you are using square button style, you can't use radio type. You want to use the On Off type in Interface Builder.
I really don't think you want to have your action method set the state of all buttons in the group… let AppKit do that for you.
From OS X Developer Release Notes: Cocoa Application Framework (10.10 and Earlier)
An NSButton configured as a radio button (with the -buttonType set to NSRadioButton), will now operate in a radio button group for applications linked on 10.8 and later. To have the button work in a radio group, use the same -action for each NSButton instance, and have the same superview for each button. When these conditions are met, checking one button (by changing the -state to 1), will uncheck all other buttons (by setting their -state to 0).
Since you specifically don't want to use NSMatrix...
First issue is that if you are using square button style, you can't use radio type. You want to use the On Off type in Interface Builder.
Here is the code I used for 4 buttons to test this out:
var buttonList : [NSButton] {
return [button1, button2, button3, button4]
}
#IBAction func buttonPressed(sender: NSButton) {
buttonList.forEach {
$0.state = $0 == sender ? .on : .off
}
}
As you can see, it iterates over all of the buttons, testing if it is the button that was pressed. It turns that button on while turning the other buttons off.
You will need to manage any state you want from there, or by checking the state of all of the buttons:
func whichButton() -> ActivityState {
if button1.state == .on { return .one }
if button2.state == .on { return .two }
...
}
where ActivityState.one is some enum case that you can use to determine which state you are in.
I believe that you are looking for NSMatrix:
You can configure this with as many rows and columns as you like:
You can then choose whether to allow a single choice or a variety:
You capture the selection in your IBAction with any combination of sender.selectedColumn and sender.selectedRow
Is it possible to hide or disable a tab bar item on a tab bar throughout the entire app for a certain use case?
Example:
While the user is logged in, and they do not have a Role of 'manager', the last tab bar item will be hidden throughout the app. When they log in again as a manager the last tab bar will be enabled and not hidden.
If you are inside the source file of the UITabBarController, just add below code in viewDidLoad method to disable last item
Also below code assumes you are having UITabBarItem items in tab bar. Otherwise you know what type of item is it so you can cast accordingly
if let items = tabBar.items as? [UITabBarItem] {
if items.count > 0 {
let itemToDisable = items[items.count - 1]
itemToDisable.enabled = false
}
}
Better code (in Swift 4):
tabBar.items?.forEach { $0.isEnabled = false }
Better solution (in Swift 5)
tabBarControlled?.tabBar.items?[2].isEnabled = isManager
Swift 5 one liner
let n = 2. //The tab number to disable
self.tabBarController!.tabBar.items![n].isEnabled = false