Is assigning the same Action-method to multiple Cocoa UI objects e.g. NSButton possible? - objective-c

I'm currently learning ObjC and Cocoa programming, coming from the Java world.
To test my current skills and learning progress I'm creating a small calculator app from scratch (OSX not iOS).
My UI has 10 digit buttons 0-9 among others.
My first thought was, since the action receives the senders reference, to make one action
like -(IBAction)captureDigit:(id)sender and then just grab the digit from the button title.
But the interface builder only allows an action to be connected with one sender it seems.
So I ended up creating 10 captureDigit actions in my controller.
My Question:
is the first option possible somehow? I thought of adding the actions programmatically (is this possible?) to the buttons, but then I would have to add all digit buttons as outlets to my controller.
Bonus Question:
can a NSButton hold some kind of non visible value? Could not find this in the documentation.
Maybe this would violate the MVC pattern as the UI would then know of application specific data?
Thanks for any useful and kind answer in advance, I'm still learning

You can connect many senders to one target/action if you Control-drag from senders to the target, so that's not a problem.
WRT your bonus question, any NSView has an integer tag which you can set in Interface Builder. That's a convenient way to differentiate multiple similar views.

You can definitely connect more than more button to a single action. Also, you can use the tag field of any object to give it a "behind the scenes" value.

It's perfectly possible to add as many actions to a single controller. How is Interface Builder preventing you from doing this?
You could have a NSDictionary instance in your controller, in which you could match NSButtons to whatever data you want.

To make it easy, in IB create one button and drag from NSButton to File's owner it then shows all of the methods that we can send to NSButton, then select captureDigit:. Now copy and paste the button change the title, copy and paste in IB keeps the connection and use tag field as costique, nitrex have already said.

Related

Create a Mention friend in iOS with Objective-C

still learning iOS development, want to create something like mention friend likes in Facebook / Instagram.
Mention People UI in Instagram
Is it using new TableViewController and add subview to the same View Controller? (in this case, CommentViewController) , but, when i already have UITAbleViewController in my CommentViewController, how can i handle the second tableviewcontroller?
Looking at the image you provided it looks as though the best way to implement this would be a UIViewController that has a UITableView added to it. Each tableview that is created can have a delegate and datasource set for it. When the textview detects that a mention is being entered (more about detecting this later) you would trigger a second tableview to appear as an additional view (subview) that overlays your current tableview (or as the accessory view of the keyboard, the way apple and others present a textview over the keyboard for text entry ex: messages app).
In order to manage the two tableviews my suggestion would be to create two additional classes each of which conform to the UITableViewDelegate and UITableViewData source. The first one would be the CommentsTableViewManager and the second would be the MentionsTableViewManager. The first tableview would set the CommentsTableViewManager as its delegate and datasource while the second would use the MentionsTableViewManager.
The other problem you may run into later on is determining how to properly detect mentions being typed into the textview. I've actually created an open source library that will help you with this problem. It's located here: https://github.com/szweier/SZMentionsSwift the README should provide enough information for you to get started if you choose to use it.
I hope the information about helps get you started with your app.
From architecture prospective it's way better to have a single table view with altered data source container, depending on current mode.
Speaking an instagram way - either you're showing comments, or, if # symbol was detected, displaying a list of users. So almost all your UITableView's delegate and data source methods will start with something like if (isMentionMode) and you'll choose specific cell class/cell's height/amount of rows per section/etc depends on isMentionMode state.

Cocoa app design recommendation

I have a Mac app that needs to be based on multiple modules. That is, a single window with multiple views, and the default view with a menu. That menu should open one module on the default window and then if I select another module, the contents of the window should change with another view. Those views also have different states, so I made multiple views for each module.
In a nutshell, my app is a single AppDelegate.h/.m, a single xib file, with one NSWindow object and multiple NSView views. Those views have different states, so I load different other related NSViews.
To load a view, I use [window setContentView:viewNameView]; which I know that causes the old NSView to lose state, so I need to keep them all in memory for each module.
Is this the right approach?
Thank you!
You don't describe how and where you want the menu but a widely used method is to have a sourcelist on the left and the content on the right. You see this everywhere including Apples own apps.
If you create a sourcelist on the left of your window and place an NSBox on the right side.
Set up the sourcelist (NSOutlineView) to react to - outlineViewSelectionDidChange: which is an NSOutlineView delegate method.
Here you can check the identifier on the selected item in the menu and set the content view for the NSBox accordingly with - setContentView:
Here's a great introduction to using NSOutlineViews for anyone interested.
Edit: Depending on how many views you have it might be easier to have an NSTabView (in tabless mode) and just switch tabs in the - outlineViewSelectionDidChange: method. This is also widely used and the user won't see the difference.
You will want to look up NSWindowController for managing your window and xib, and NSViewController for managing views. The app delegate shouldn't do much (in fact you probably could remove the header file and merge it with .m).
Some references to look at:
https://www.mikeash.com/pyblog/friday-qa-2013-04-05-windows-and-window-controllers.html
https://developer.apple.com/library/mac/samplecode/ViewController/Introduction/Intro.html
Yes that will work. What you may end up needing as well, is a custom Navigation Controller. Unfortunately Cocoa doesn't have an NSNavigationController, so you'll have to write something on your own. But basically yeah what you'll do is swap out the contentView with the next view you want to display-- and keep a stack of views you've navigated to so you can support going back (or you could use a dictionary to add transition keys to create strongly linked transitions)
Here's an good example somebody posted in a previous thread-- if you just search for Cocoa Mac Navigation Controller you should find some helpful results :)
Mac OS X Cocoa multiview application navigation
Another thing that you may want to keep in mind, which came up for me, is if your views are of different sizes. If they are, and you are using auto-layout, you will need to update the constraints to resize the window appropriately as views are swapped out

NSTableView problems - displaying custom TableView from with a SplitView panel

I am developing my first app for OSX. Sorry for asking stupid questions. I have spent a few hours trying to figure this out on my own, with no luck so far.
I want to make an iTunes-like interface. I used NSSplitView, placed NSView for navigation and NSTableView above that. [I am aware that there better alternatives to NSSplitView, yet my goal is to both - develop an app and also to learn Cocoa/OSX in the process.]
Atop NSView panel designated for navigation, I am trying to place NSTableView. However, my table is not being displayed. I therefore have questions...
I understand that for cells to be populated, controller must implement NSTableViewDataSource. I tried that, but was so far unsuccessful - to the point that I don't see the table. Please advise:
Can I have a working NSTableView-derived custom class also implementing NSTableViewDataSource? If this cannot work, please advise why or point me to an explanation.
Am I correct in thinking that all elements can be manipulated programmatically, in the sense that I use IBOutlet in headers to point to the right object, yet do nothing with InterfaceBuilder - have everything controlled from within my Objective-C code? Do I have to use IB?
Thank you.
Yes that will work but it's an unusual approach. Generally the tableview delegate/datasource is something enclosing the tableview. You'd normally only subclass NSTableView if you require some additional functionality not provided by default (for me that has been custom behaviour to input).
Yes you can do it all programmatically, however you will find it much easier to use IB. The IB-loaded views are created programmatically under the hood, using the information contained in the nib file. You will find it long-winded and tedious pretty quickly.
WRT to your issue with not seeing the table, you will need to add logging/breakpoints on the few key delegate/datasource methods to ensure they are being called (start with the daddy of them all numberOfRowsInTableView:). If they are not then you aren't setting the delegate/datasource correctly in the tableview.

iOS text popup with clickable links

I'm looking for a simple solution to presenting popup text in an iOS app that contains text with hyperlinks.
At the moment, my text pops up as a UIAlertView. The user has a 'Close' button below which dismisses the box. However, this class (UIAlertView) doesn't allow the use of hyperlinks within the message text. I understand that creating a whole new custom UIAlertView is frowned upon (not to mention probably overkill for what I want to achieve).
Perhaps I'm barking up the wrong tree by using UIAlertViews. I'm new to iOS and don't know the scope of what's available. Essentially, I need a dialog (or window) to pop up, containing a string of text, a (close/back/dismiss) button, and possible hyperlinks within the text. Those hyperlinks in turn launch other popups/windows/dialogs of their own.
What I'm working on here is a simple dictionary application. It's a table view containing terms. The terms lead to definitions, and in most cases, the definitions themselves reference other terms. Fairly simple, and if possible I'd like to use standard API classes.
Any wisdom would be appreciated. If I truly have to go down the route of creating my own custom UIAlertView class, then sobeit! In this case, some pointers for lightweight class creation would be appreciated. I'm not looking to add fancy colours or anything, just the ability to click on bits of text.
I think you'll need to create your own UIView sub-class to do the trick, controlled by a UIViewController subclass. One trick I've used to make it look more like an alert view is to have your main popup view embedded in a fullscreen view with a clear background.
In general, Apple SDKs make it really easy to do standard things (UIAlertView), but if you want to tinker with it (embedded links), you need to do it yourself.

Must a button control be added as a property in the Interface?

I'm new to Objective C and there are a few basic things that I do not yet understand from the tutorials and books I've looked at. For this question I am confused about whether a button needs to be connected to a property in the Interface as well as being connected to the IBAction method.
Seems like a simple question that might help others. Thank you.
You should hook up items in interface builder to IBOutlets only if you need to operate on them in the view controller. For instance, if you wanted to change the button's title text to be localized on load, then you would hook it up. If all you want to do is respond to a specific action on the button (touch up inside for instance), then you only need to hook up the IBAction portion. The short answer is that you are not required to hook up the IBOutlet.