I'm trying to create a menu with a drop down menu with a custom background for every cell.
First i tried to adapt NSPopUpButton but i couldn't find a way to change the cells background image. Using setImage: would slide the text to the right of the background. Next I stopped at NSComboBox but i couldn't find a way to change the arrow button. Can someone please help with and idea? Next thing would be to create a custom controller but i would like to use something already done.
To customise the arrow button in NSComboBox, you need to create a subclass of NSComboBoxCell and set your combo box to use that cell. If you've configured your control in IB, you can easily change the class of your cell there. If you're programmatically creating your combo box, create a subclass of NSComboBox, override + (Class)cellClass and return your custom NSComboBoxCell subclass from that method.
Now for the drawing. In your NSComboBoxCell subclass, you need to override
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView.
(I've tried overriding - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView but the cell frame it provides stops short of drawing the actual button area, i.e. it only covers the text input area.)
Your custom - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView should look something like this:
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
[super drawWithFrame:cellFrame inView:controlView];
// Constrain to the far right of the provided frame to draw the button
NSRect bounds = NSMakeRect(cellFrame.origin.x + cellFrame.size.width - cellFrame.size.height, cellFrame.origin.y, cellFrame.size.height, cellFrame.size.height);
// Draw your custom button inside the bounds rect
}
I'm not sure if I understood your question correctly. If you want to show a menu at an arbitrary position somewhere in your UI: NSMenu provides convenience methods for achieving that. Have a look at the documentation for + popUpContextMenu:withEvent:forView:, + popUpContextMenu:withEvent:forView:withFont: and – popUpMenuPositioningItem:atLocation:inView: to find the one that best fits your needs. Like that you can display a menu at whatever position you like.
If you instead want to display arbitrary content inside a menu, have a look at the documentation of NSMenuItem's - setView:. This allows you to insert views inside menus. Together with the above method of displaying menus wherever you want, you can create all sorts of solutions for "PopOver" needs.
Related
I want to get rid of the rounded corners of a UIButton (type = Round Rect Button). I want to stack some buttons to give a UITableView look and want to get rid of the rounded corners in some instances. Is this possible? (MonoTouch)
If th type is rounded rect, it has the rouded corner. Use a custom type to do exactly what you want.
If you're in interface builder, just select custom type, you can then use a background image or normal layer attributes (border, shadow...).
In code, don't create a new classe, jsut create a button and set the type to custom.
Create the image of the button you want (in Photoshop, or whatever else floats your boat), change the button type to "Custom" and then import the created image to your project and set it under the "Image:" drop down in Interface Builder.
Tada, customization complete.
Have a look at UIButtonType to see all the types of button you can create (including a custom one). E.g.
var b = new UIButton ();
b.ButtonType = UIButtonType.Custom;
OTOH if you want to do things that looks like UITableView then I strongly suggest you to look at MonoTouch.Dialog and its sample application - which includes ownerdraw elements. It will be as easy (or easier) than dealing with several buttons (and much easier than using UITableView).
Please see the image below.
How was this 'pop-up' view created? Suppose I wanted to completely imitate that view with the fonts, how would I do so?
There is not a SDK exposed component for this, but this could very easily be made using a hierarchy of views:
UIView - Main view. Uses a bezier path to create a protrusion to
point from the source. Has a border and drop shadow added to its
layer.
UIButton - Smaller font
UIButton - Larger font
UIButton - Change font type
UIButton - Container for sepia.
UILabel - "Sepia" text
UISwitch - turning sepia on and off
Just show and hide the view with an animation. Also, create delegate callbacks to tell the delegate when events occur in the popover.
// Delegate returns if the text can get smaller to enable/disable the button
- (BOOL) didSelectSmallerFont:(CGFloat)fontSize;
// Delegate returns if the text can get larger to enable/disable the button
- (BOOL) didSelectLargerFont:(CGFloat)fontSize;
- (void) didChangeFont:(UIFont*)font;
- (void) didToggleSepia:(BOOL)enabled;
etc.
The pyramid shape is not associated with the button that was clicked to present the popup. It would be a subview of the popup view, either a UIImageView or possibly drawn on a UIView, although a UIImageView would be the easier solution. You could definitely code the popup view to point that arrow at any point on the screen or in any direction. What I would do is instantiate the popup by means of an init method called initFromPoint:, then pass the center value of the button used to launch the popup. Then within the viewDidLoad method of the popup place the point appropriately based on the point.
It seems like more and more OS X apps these days are doing all kinds of fancy drawing stuff for custom controls. Apps like Twitterific, Things, EventBox, Versions just to name a few....
So basically I'm looking for any information on how to get started doing this kind of thing. Not sure if it is just done by subclassing controls and using custom drawing or if it is something entirely different.
Any help is greatly appreciated. THanks!
It depends entirely on what you want to do.
The "Show Raw Properties" button in Versions for instance is an NSButton subclass, because basically what we needed is standard button behavior with our own look. One way to subclass a button is to simply implement your own -drawRect:(NSRect)rect method in the NSButton subclass, but we decided to stick with the way NSButton is implemented in Cocoa, meaning most drawing is done by the button's cell, so the implementation looks like this:
In the NSButton subclass:
+ (Class) cellClass
{
return [OurButtonCell class];
}
- (void)drawRect:(NSRect)rect
{
// first get the cell to draw inside our bounds
// then draw a focus ring if that's appropriate
}
In the NSButtonCell subclass (OurButtonCell):
- (void)drawInteriorWithFrame: (NSRect) rect inView: (NSView *) controlView
{
// a bunch of drawing code
}
The Timeline view in Versions is actually a WebView, the page that you see in it uses javascript to collapse headers you click on.
The rule of thumb I use for where to start out with a custom control is:
To customize the look of a standard Cocoa control:
subclass the appropriate control (like e.g. NSButton and NSButtonCell)
stick as close as makes sense to the way the default control is implemented (e.g. in a buttoncell, start from the existing attributedTitle instance method to draw the button title, unless you always want to draw with the same attributes regardless of what's set up in IB or if you need to draw with different attributes based on state, such as with the trial expiration button in Versions' main window)
Creating an entirely new UI element:
subclass NSView and implement pretty much all mouse and key event handling (within the view, no need to redo "hitTest:") and drawing code yourself.
To present something that's complex, of arbitrary height, but isn't a table:
See if you can do it in HTML, CSS and JS and present it in a WebView. The web is great at laying out text, so if you can offload that responsibility to your WebView, that can be a huge savings in pain in the neck.
Recommended reading on learning how to draw stuff in your own custom view's drawing methods: Cocoa Drawing Guide
Customizing the look of for instance an NSTableView is an entirely other cup of tea, thanks to the complexity of a tableview, that can happen all over the place. You'll be implementing your own custom cells for some things you want to do in a table, but will have to change the way rows are highlighted in a subclass of the actual NSTableView object itself. See for instance the source code for iTableView on Matt Gemmell's site for a clear example of where to draw what.
Finally, I think Abizer's suggestion to go check out the code of BWToolkit is a great idea. It might be a bit overwhelming at first, but if you can read and understand that code you'll have no trouble implementing your own custom views and controls.
Have a look at some excellent example code: BWToolkit
I'd like to change the appearance of the default UISearchBar. As an example, how would you recreate the search box in the Google iPhone app as seen below? How would you overlay an image to produce this effect?
(source: isedb.com)
Upon some investigating of possibilites to customize the search bar, I'm inclined to say this is a custom component that has nothing to do with UISearchBar, but instead recreates its functionality.
You don't need to subclass anything.
Create a new UIView that has the buttons and text field and then when then entire view is going to load do this:
[self.searchDisplayController.searchBar addSubview:customSearchBarView];
Make sure to set the new text field as the first responder so it has access to the keyboard.
I'm trying to figure out a best way to implement the picture-editing capability shown in the native address book app on iPhone.
On the built-in address book, this is how the picture looks like before editing:
qkpic.com/2f7d4 http://qkpic.com/2f7d4
And after clicking edit, notice how "Edit" overlay is added and the image becomes clickable:
qkpic.com/fb2f4 http://qkpic.com/fb2f4
What would be the best way to implement something like this? Should I make the image a button from the beginning and have tapping disabled at first? If so, what steps are required to add an overlay/label to the image (in above example, gray border + the text "Edit" is added)
The easiest way is to use Interface Builder, create a container view, then add a UIImageView and UILabel as subviews to it. You would position and style the text and the image but set the UILabel to hidden. Make the whole container view respond to touches. It's easy to do since UIView is derived from UIResponder so all you have to do is override touchesEnded. Whenever you want to change the text label, just set the UILabel to hidden=NO.
There's more to it, however. Notice how the image has rounded corners? You'll want to override the UIImageView's drawRect method to implement a custom drawing routine to do that. There's lots of sample code around and it wasn't part of your original question so I'll stop here.