I'm working on a Cocoa programming exercise, and I need to be able to determine which of two NSTextView objects is currently being edited. I think it's something to do with finding the first responder and checking to see if it's equal to one text field or another, but I can't quite get it to work. Any help would be appreciated.
I suggest you to read the Cocoa Event-Handling Guide, and especially the section called Responder-Related Tasks. You will find all the information you need.
Related
I am writing my first Cocoa/OSX app. I have been having problems with an NSTableView derived class. The problems is that there is no table in the containing NSView - the table is not visible.
I previously pasted my code at NSTableView is not being displayed
If you know NSTableView well and it could assist, it would greatly help. I have spent a couple of days on this, with no luck.
Additional details:
NSLog shows that NSTableView subclass init() is called once. This is probably good. The method numberOfRowsInTableView() is called multiple times. I don't know whether this good or bad. The method tableView:objectValueForTableColumn:row: is never invoked. The method drawRect() of NSView is called after initialization of TableView. Yet, commenting out [super drawRect:dirtyRect]; line changes nothing.
Please note that I use the same NSTableView subclass as [also] a NSTableViewDataSource. I understand that this is not the common "pattern," yet I don't see why this cannot work. If there is a logical explanation, please advise my approach is not workable.
I do not use and do not want to use InterfaceBuilder.
Thank you for taking time to read my question.
I managed to come up with the solution. See the referred page for more information, if interested. Thanks.
BTW, the best NSTableView tutorial which I have seen - one that allowed me do what I needed is at: http://www.knowstack.com/nstableview_fromcode/
I have a class that contains several textfields. I need to know when one is done being edited and send the new information to one of my other objects.
This question seemed similar but in Objective C? The buttons should be visible when the user is done entering the value in the textfield
Objective-j doesn't have the same functions.
Browsing the documentation I found several functions that seemed like they might be able to help such as, textDidEndEditing but didn't understand how to use it. There are several more that sound related and I don't know what to use.
Summary: when the textfield is done being edited I need to perform another function. Also there are multiple textfields so I need to know which one is edited.
controlTextDidEndEditing is the delegate method you should implement. Or you can just set the target/action of the textfield
Short and sweet:My end goal is to, using one UILabel with two words, display one word in bold, and the other in normal font. All solutions I've found are over my head! :(
More detail:
I asked a question the other day that didn't give me the answer I was hoping for, and now it looks like I need to recreate ABPeoplePickerNavigationController using a UITableViewController and contents from ABAddressBook. If you read my previous question and can come up with a better solution, awesome! If not...
When I recreate the PeoplePicker, I really want to mimic Apple's default implementation exactly, especially how they use both bold and normal fonts for a contacts' name in the same label.
Now, I know this question has been asked a lot, on SO and elsewhere. Many people have had this need, and the solutions vary:
use a webview
use the UIStringDrawing methods
subclass UILabel and override drawrect
delve into CoreText
use the ThreeTwenty library
use two uilabels, create one as bold, one as normal, and place them next to each other (would require me to then subclass UITableViewCell in order to place two labels
Solutions #2, #3, and #4 seem the most robust, and according to what I've read in other questions, it's how Apple is actually doing it. Unfortunately, these techniques are a little over my head at the moment, and I'm having a hard time following the limited amount of details I'm finding on the web. I haven't really done anything with explicit drawing yet.
Has anybody implemented this yet themselves? Any code samples you can provide to help me get the hang of these more advanced techniques?
Thanks!
There's a 6th solution. Use 2 UILabels. Create one, in bold, with the bold text, and ask it to size to fit. Then once you've laid it out, you can create the second and place it right next to the first.
You should read the "Table View Programming Guide for iOS" there is a section titled "Subclassing UITableViewCell" it does exactly what you want (i.e. draw strings of different properties).
So, just to round this out, I ended up finding a 7th option. :)
I went with OHAttributedLabel. I still wasn't able to wrap my head around UIStringDrawing methods or overriding drawRect in a subclassed UILabel; I think those would have been the cleanest solution. However, OHAttributedLabel seems solid, is super lightweight, and does exactly what I need it to do.
Good luck! If anyone finds more solutions, or feels like they want to explain UIStringDrawing or or drawRect in more detail, feel free to post!
Update:
I've been using Matt Thompson's TTTAttributedLabel and have been really happy with it.
https://github.com/mattt/TTTAttributedLabel
I want to expand on the functionality of NSTextField. AMong the things I want to achieve is:
Changing the look and feel of the caret.
Detecting when the text reaches a certain number of characters and then coloring the text after that limit differently. *
To my great frustration after spending quite some time googling I find hundreds of hits that simply state "Sublass NSTextField and use this code.", and to my humiliation I have found myself unable to grok exactly how to do this.
I would be extremely grateful if someone could give me a working example of a subclass that achieves one of the two things I list above, and instructions* on how to implement the code so I can try and figure out how it works by looking at some actual live code.
I am extremely apologetic for my late response!
Apologies to all of you. I have a colic infant at home, and as you (or at least those of you that have children) can imagine this takes up quite a lot of your available time. Thank you all for your responses.
I see that one of my main problems is that I don't have a sufficient understanding of delegates and outlets. I have purchased the book recommended here (and many other places. Some sort of "Bible" I gather) and I'm looking into it as we speak in the few silent hours I have these days. :)
But although I can see it's going to be an indispensable tool for me I still gain the most understanding from studying examples rather than reading the theory* and so I would be extremely grateful if someone would create a project with a proper subclass of the relevant class since I understand that I should probably not be extending the NSTextfield class?
I would instantly mark Mark Thalmans post as the answer as I'm sure it's a proper "for dummies" response, but I'll hold out for a few days since I'd really love a file to peruse. But I am not ungrateful!
Oh, and; Please believe me guys when I say I'm not quite as useless in languages I actually know. It's just that these concepts with the Interface Builder and GUIs connection to the code is very unknown to me. I usually just write the code and keep it at that.
*Yes, my first little training project is indeed a Twitter Utility.
*Like to a child
*Not that reading the theory hasn't got tremendous value for me as well. I wouldn't be where I am without Colin Moock definitive guide to AS3
setInsertionPointColor: will take care of setting the caret color, and using delegate methods would be the best way to color the text after the number of characters change. In general, a lot of classes in Cocoa are like this; you can subclass them, but most of the functionality you need to change are in delegate methods.
NSTextField is special, because it doesn’t actually implement text editing. That’s done by a shared (per-window) NSTextView, known as the field editor. You can provide a special field editor for a given NSTextField. This is canonically done by subclassing NSWindow (!) and overriding -fieldEditor:forObject:. When I was looking this up, though, I found NSTextFieldCell’s -setUpFieldEditorAttributes: method, which looks as though it could return a different field editor than the one it’s handed.
Recommended reading: Control and Cell Programming Topics for Cocoa, Text System Overview.
Martin,
I started with the "New File" dialog and chose "Cocoa" on the left and then Objective-C class.
That will generate the following code, without the comments. Then all you need to do is change the NSObject in the"#interface" line of the header to "NSTextView" and you have a working subclass. If you are using XCode 3.0 you can go to Interface Builder and change class of your NSTextField to "MyTextView".
You should also pick up Aaron Hillegass' book "Cocoa Programming for Mac OS X, Third Edition" It has bee updated for Leopard, if you haven't already.
Good Luck.
#import <Cocoa/Cocoa.h>
#interface MyTextView : NSTextView {
// Outlets & Members go here
}
// Actions & messages go here
#end
#import "MyTextView.h"
#implementation MyTextView
#end
If you really have to subclass it, you have to subclass the NSTextFieldCell. Informations about NSCells are available online.
Don't subclass the cell if not absolutely necessary. Use the delegate methods.
At least the color can be changed using NSTextField's bindings, use those.
You may also be able to get some of the functionality required with a formatter.
I'm slowly learning Objective-C and Cocoa, and the only way I see so far to capture key events in Text Views is to use delegation, but I'm having trouble finding useful documentation and examples on how to implement such a solution. Can anyone point me in the right direction or supply some first-hand help?
Generally, the way you implement it is simply to add the required function to your view's controller, and set its delegate. For example, if you want code to run when the view loads, you just delegate your view to the controller, and implement the awakeFromNib function.
So, to detect a key press in a text view, make sure your controller is the text view's delegate, and then implement this:
- (void)keyUp:(NSEvent *)theEvent
Note that this is an inherited NSResponder method, not a NSTextView method.
Just a tip for syntax highlighting:
Don't highlight the whole text view at once - it's very slow. Also don't highlight the last edited text using -editedRange - it's very slow too if the user pastes a large body of text into the text view.
Instead you need to highlight the visible text which is done like this:
NSRect visibleRect = [[[textView enclosingScrollView] contentView] documentVisibleRect];
NSRange visibleRange = [[textView layoutManager] glyphRangeForBoundingRect:visibleRect inTextContainer:[textView textContainer]];
Then you feed visibleRange to your highlighting code.
It's important to tell us what you're really trying to accomplish — the higher-level goal that you think capturing key events in an NSTextView will address.
For example, when someone asks me how to capture key events in an NSTextField what they really want to know is how to validate input in the field. That's done by setting the field's formatter to an instance of NSFormatter (whether one of the formatters included in Cocoa or a custom one), not by processing keystrokes directly.
So given that example, what are you really trying to accomplish?
I've done some hard digging, and I did find an answer to my own question. I'll get at it below, but thanks to the two fellas who replied. I think that Stack Overflow is a fantastic site already--I hope more Mac developers find their way in once the beta is over--this could be a great resource for other developers looking to transition to the platform.
So, I did, as suggested by Danny, find my answer in delegation. What I didn't understand from Danny's post was that there are a set of delegate-enabled methods in the delegating object, and that the delegate must implement said events. And so for a TextView, I was able to find the method textDidChange, which accomplished what I wanted in an even better way than simply capturing key presses would have done. So if I implement this in my controller:
- (void)textDidChange:(NSNotification *)aNotification;
I can respond to the text being edited. There are, of course, other methods available, and I'm excited to play with them, because I know I'll learn a whole lot as I do. Thanks again, guys.