Custom NSButton and NSButtonCell - objective-c

I'm trying to create a custom button look.
From what I've gathered, NSButtonCell does the drawing, so I should actually be overwriting that instead.
But the issue is, my CustomButton class has other things like NSImage, mIsMouseOver etc. Currently the drawing is being done in the CustomButton class but I want to move it over to the cell.
question is, is there anyway I can access the image in the customButton class from the customButtonCell class so that I may use [image drawInRect:...]?
Regards,
Han

Your cell's drawWithFrame:(NSRect)frame inView:(NSView *)controlView method includes a reference to the NSView being drawn from which you can access the view's properties (such as image).

Usual way is to store the data in the NSCell subclass. Base cell class even has an -(id)image property, so, your button class should call [[self cell] image] when it is queried for image.
Actually, since you are subclassing NSButton, it contains all you need, just override cell's drawing methods. And if you need an extra property - define it in the cell, wrap in the control.

Related

Change self.view's class type

I have a app out for testing right now that's almost completely done - just a few bug fixes left. Unfortunately, the customer decided that they'd like the entire main page of the app to be inside of a scroll view (so that there's more room for the table at the bottom). I already have everything set up and I don't really want to move everything and change references. Is there an easy way to change the class of the main view to a scroll view? I've already tried changing the class in IB and setting the class type in the init method. If there isn't I'll probably just throw the top section of the view into a nib file and load it as a custom cell.
-EDIT- I ended up changing the class type in IB and then doing
[(UIScrollView *) self.view setScrollEnabled:YES];
[(UIScrollView *) self.view setContentSize:CGSizeMake(0,2000)];
in viewDidLoad. Thanks for the help, wish I could accept all your answers.
When you are referring to [self view], I am going to assume you mean in a view controller. The view of a view controller can be any view that derives from UIView. Thus a scrollview is completely acceptable.
I don't really want to move everything and change references.
what would you have to move? why would you have to change references? Only thing you should need to do is add a scroll view to your view controller, set the view controllers view to it, and add the current view as a subview to the new scroll view. No references need to be changed, nothing has to be moved.
Refer to loadView method in documentation of view controller.
Here is a simple (untested!) example
- (void)loadView {
UIScrollView *scrollView = [[UIScrollView alloc] init] autorelease];
//Set the properties of scrollview appropriately....
self.view = scrollView;
}
Now the root view of your view controller will be a scroll view.
Note
- As the documentation states, do not do this if you are using interface builder to initialize your views/view controller. I could not tell from your description if this was the case or not. If it is, you should be able to change the view type in interface builder.
You need to set the contentSize property of your scrollview.
Since you are using IB, the easiest way to do this is to put all your UI elements into a view and add this single view to your scroll view. In the viewDidLoad method, set the content size of the scrollview to be the same size as the view that contains all your UI.
As an aside, there are much easier ways to reference views than walking down the view hierarchy, as you seem to be doing. viewcontroller.view.something.tableview. Add a connection to the tableview from your view controller in IB and it doesn't matter where that tableview is in the view hierarchy. You'll always be able to reach it from viewcontroller.tableview, no matter how you rearrange your nibs.
I think you have to use a pointer with proper type. Example for Google Maps: let's say you changed you base view's class to GMSMapView.
MapViewController.h
#property GMSMapView *mapView;
MapViewController.m
-(void)awakeFromNib{
[super awakeFromNib];
self.mapView = (GMSMapView*)self.view;
// ... etc.
}

How to make NSTextField use custom subclass of NSTextFieldCell?

I've been looking for a solution to make my NSTextField bottom-aligned and I've found this and adjusted it for my needs. So now I have this custom NSTextFieldCell but how do I tell my NSTextFields to use this class (programmatically)?
Since you ask how to do it programmatically, you can also use the setCellClass: method on your NSTextField subclass. Call it in the load or initialize class methods:
+(void)load
{
[self setCellClass:[MyTextFieldCell class]];
}
It will not have any bearing on your text fields defined in Interface Builder, as the text field cell set there takes precedence.
Have you tried setCell: method of the NSControl class?
- (void)setCell:(NSCell *)aCell

Highlighting selected item in a NSCollectionView using NSBox

How do I make the NSCollectionView update to show the currently selected item using an NSBox? Displaying selection in a list seems like a basic thing, but I'm having all kinds of trouble with this.
I've read this question and also looked at the sample code from Apple. There seems to be several ways to do this.
Using a subclasses of NSCollectionViewItem and special "prototype view".
Using a NSBox.
I wish to use the NSBox way since it seems simples and is also used in the official code sample.
It's apparently done as described in the following quote by alternegro:
If a different background color will suffice as a highlight, you could
simply use an NSBox as the root item for you collection item view.
Fill the NSBox with the highlight color of your choice. Set the NSBox
to Custom so the fill will work. Set the NSBox to transparent.
Bind the transparency attribute of the NSBox to the selected attribute
of File Owner(Collection Item) Set the value transformer for the
transparent binding to NSNegateBoolean.
I'm stuck at the very first part: "use an NSBox as the root item for you (sic) collection item view". I've tried to change the "Custom Class" to a FoobarBox that inherits from NSBox, but it doesnt seems to help as I cannot change the background color to blue nor can I bind the transparency. Any pointers on how to make the selection display in my NSCollectionVuew would be appreciated.
First, create a class for your ListView that inherits from NSBox
#interface MyListViewBox : NSBox
#property (unsafe_unretained) IBOutlet NSCollectionViewItem *controller;
#end
Then, in Interface Builder, specify your class name as "Custom class" property as shown on my screenshot
Then you will realize IB does not show NSBox properties or binding in the GUI (at least with version 4.5.2), so I decided to change the properties programmatically.
Create an outlet for NSCollectionViewItem in your NSBox subclass (as seen above)
Use IB to link the outlet to your NSCollectionItemView
in -(void)awakeFromNib for your NSBox subclass, add the following code
-(void)awakeFromNib {
//properties are not showing up in XCode Inspector IB view
//configuring the box here :-(
self.boxType = NSBoxCustom;
self.borderType = NSLineBorder;
self.fillColor = [NSColor selectedControlColor];
//bind the "transparent" property of NSBox to the "selected" property of NSCollectionViewItem controller
//controller is bound as IBOutlet in IB
NSValueTransformer* transformer = [NSValueTransformer valueTransformerForName:NSNegateBooleanTransformerName];
[self bind:#"transparent"
toObject:self.controller
withKeyPath:#"selected"
options:[NSDictionary dictionaryWithObjectsAndKeys:transformer, NSValueTransformerBindingOption, nil]];
}
In XCode 4.5.2, you can just delete the NSView that comes automatically with the NSColletionView and drag in an NSBox (which will have all the appropriate bindings available). Make sure you re-bind the CollectionView to your new Box.

Handling custom selection style in view based NSTableView

How do I go about drawing my own custom selection style for a view based NSTableView? I tried putting a BOOL var in my NSTableCellView subclass and set that to YES if it is clicked and then I can successfully draw my custom selection. But how do I change that BOOL var to NO when another view is clicked? Thanks for any help.
EDIT: After reading through the NSTableView docs, it looks like I need to subclass NSTableRowView to override the selection drawing, but what do I do with my NSTableRowView subclass? How do I get the table to use it?
Alright, I figured it out. You just have to subclass NSTableRowView. It has methods for drawing the background for selected and deselected rows. To get the table view to use your subclass just implement the table view delegate method tableView:rowViewForRow: and return an instance of your subclass.
To make things clear, I think we should give the code of the delegate method :
- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row
{
MyNSTableRowView *rowView = [[MyNSTableRowView alloc]init];
return rowView;
}

Get Index of Object in TouchesEnded

i have a UIViewController with many UIImageViews. I need in touchEnded event get a index of this UIimage.
How do Make?
Thank's
make a custom UIImageview class which is subclass of UIControl. and add a target method for this class.set the tag for each UIImageview. and change the class name of UIImageview in inspector window to that custom class.
[imageview addTarget: self action:#selector(findIndex:)forControlEvents:UIControlEventTouchUpInside ]
you can set this method using xib also.
and define findIndex method in your viewController class.
Instead of UIImageViews, why don't you use UIButtons? You can set the image with setImage:forState:, and the target action and object with addTarget:action:forControlEvents. When your target action gets called, the button will be sent as the sender argument.