I'm using CGRect's for hitboxes, and my collisions seem to be a bit off. I want to quickly see where my hitboxes actually are.
I tried a bunch of different approaches but most of them seem to be outdated, or just didn't work for me.
I tried this already and a bunch of similar approaches.
What is the simplest way to show the borders of a CGRect?
With cocos2d 2.0, in ccConfig.h there is a CC_SPRITE_DEBUG_DRAW symbol. If you set that to 1, the box will be drawn during the visit cycle.
If CC_SPRITE_DEBUG_DRAW, as YvesLeBorg suggested, doesn't suit you, you can override draw method in you layer or nodes and draw in that method using helper functions from CCDrawingPrimitives.h. Don't forget to call [super draw].
Related
I recently discovered that in > iOS5 UINavigationBar does not get its drawRect called. I want to figure out how to draw with Core Graphics in a category.
The end goal I am trying to achieve is eliminating images from my app and have everything drawn at runtime. I am also trying to make this library automatic, so that users don't have to think about using my custom classes.
Is there a way to replace a class with one of your own at runtime? like: replaceClass([UINavigationBar class], [MyCustomBar class]);
Thanks in advance.
Is there a way to replace a class with one of your own at runtime?
In Objective-C this is know as class posing.
Class posing is based on the use of NSObject's poseClass method, which is now deprecated (on 64 bit platforms, including the iPhone).
Alternative approaches have been investigated; you can read about one here, but they do not seem quite to fit the bill.
I found the solution, Instead of messing with draw rect, I just made some methods that draw to a UIImage then set the image as the background view for the elements i am customizing. It makes my custom UI magic again.
I have recently started creating my own controls and I seem to have a bit of trouble understanding how I should use drawRect.
Basically I have 3 Questions.
Is it a good idea to have conditional drawRect's? ie. different drawing code based on properties or instance variables.
What is the best method for animating changes to the drawRect's drawing? For example, a fuel gauge control with animated fill and un-fill.
And, finally, the examples I have seen for animating with drawRect tend to use timers, is that really a good method in practice? It seems like the heavier apps would have issues with that method.
I guess a 4th would be, is there, perhaps, a better place to do this kind of stuff?
Is it a good idea to have conditional drawRect's? ie. different drawing code based on properties or instance variables.
Sure, why not? If your drawRect: method becomes unwieldy, you could split it into multiple methods that you then call from drawRect: depending on the properties of your view. E.g. you could have methods like drawBackground, drawTitle, etc.
What is the best method for animating changes to the drawRect's drawing? For example, a fuel gauge control with animated fill and un-fill.
That depends. For very small views, you could call setNeedsDisplay from a timer, but for larger views, you'll often run into performance issues with this approach.
Animating changes is often better done by compositing your view out of multiple subviews or layers that can be animated with Core Animation (or the simplified UIView animation methods).
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
Today I decided to try to use CALayers to show a rectangular box overlaying a NSView. The layer will contain some text and will be turned on and off depending on when it is necessary to show the variable text. The reason I wanted to use CALayer for this was the nifty rendering and animation you can easily do with CALayer. I implemented my layer and it worked like a charm. However, after using my GUI and clicking several times on various buttons turning the layer on and off, it seemed that the hierarchy of what I thought was my layer view was skewed. I think focus must have been switched to some other NSView which again was turned off. I basically got very confused as to which layer I was handling at a given time and I lost control of the view hierarchy.
My question is: should I use subviews of NSView, or CALayers to show something that may occur many times on and off in an application? It seems to me that it is easy to loose control of which layer you are working on. Is there a way to identify by name the current layer so you can reuse the layer, or is it best to work with layers, delete them and then re-create the layer the next time you need them?
Thanks for your time. Cheers, Trond
FWIW,
I have often turned CALayers "on and off" very quickly, with no problems at all. So you can do that if you want to!
Deleting them and recreating them quickly on the fly, does not seem to cause any problems. (It's not a big resource user, and I've never seen any other problems doing that.) So definitely do that if you want to!
I actually don't understand what you mean about "naming" layers - of course, as iVars they have a name! You have to name all your CALayers.
Here's a typical bit of production code (from a .h file):
CALayer *rearLayer;
CALayer *hugeBasket; // holds everything for ez-on/off
CALayer *theActualSkyline; // nb, same name as similar UIView
CALayer *someTrees; // minor stuff
CALayer *someBushes; // overs
// for the stupid help basket..
CALayer *LLDRear;
CALayer *LLDArrowLeft;
CALayer *LLDArrowRight;
CALayer *LLDPointlessUpArrow;
CALayer *LLDYetAnotherStupidShadow;
// etc etc..
And so on and on. I don't really see how you can "not" name them, you know!
Finally,
4, Don't forget layers are much "better" than NSViews, because: NSViews have shoddy/buggy relationship between overlapping siblings: they essentially don't work. Read about that here:
port an iOS (iPhone) app to mac?
Hope it helps!
PS - these may also help with CALayers...
Exactly what should happen in a CALayer's display/drawRect methods?
What's the difference and compatibility of CGLayer and CALayer?
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.