Add a second image to a custom UIButton - objective-c

I've got an Custom UIButton. It's got
a "static" background image
a variable text (the Title) which gets set in the code
Now I would like to add an icon (UIImage/UIImageView) inside the button on the left of the text. (I use the indent to move the text slightly to the right). Is there an easy way of adding that icon (and referencing it from code, so I can change it) or would you recommend creating a completely new button e.g. based on a UIView? (e.g. a view, that responds to touches)?
I'm just trying to get a feel for what the best approach would be for this. Any experience?

Two ways:
I prefer doing this by subclassing a UIView and (as you mention) implement the UITouch-responder methods. You're also able to override drawRect: what I really like because it makes your app soooooo much faster!
Since UIButton is a subclass of UIView, you can add a UIImageView to your button by using addSubview:. If you save it in your main-class (#property (...) UIButton *button) you can always access it by calling [self button]. You can also subclass your UIButton and add this #property. That's up to you.
It's totally up to you. However I prefer the first way!

Related

MVC and the use of a UIButton to dynamically create UI elements

I understand the concept of MVC. At least I hope I do but there is a particular situation that I have encountered recently that makes me think that I actually have no idea.
Problem:
I am trying to create a class that when applied to an existing button adds the functionality of editing that button's title. It does so by dynamically generating a UITextField that will in turn be populated with the Button's new name. I hold the logic of adding the UITextField in a class called CustomAnimation and initializing it in the following way:
CustomAnimation *yar = [[CustomAnimation alloc] initWithButton:customButton];
The problem that I encounter is when I am trying to dynamically create a UIButton from a custom class like CustomAnimation and try to assign a target/action to it. Since the UIButton is actually generated inside the ViewController FROM the CustomAnimation class the former should get a pointer to the parent ViewController and then set it as the target.
[classButton addTarget:viewController action:#selector(dostuff:) forControlEvents:UIControlEventTouchUpInside];
All is good except one thing - dostuff method should reside inside the ViewController in order to be visible for that button and here everything turns into a hack.
What is the correct approach when you want to generate temporary UI elements from inside a Class instead of the Controller?
Thank you
There are lots of ways you can look at MVC in terms of granularity. If I understand your question correctly you are trying to implement MVC at a single control level which is - in my opinion - too finely grained. I try to aim for a more coarse approch where a controller manages a chunk of UI controls, e.g. a view or a window.
You could argue that the editability of the buttons label is bahavior that belongs to the button (encapsulated by it), hence its implementation is or should be part of the overall implementation of the button. Once you accept that, you could implement this as a subclass of UIButton and move the code that is in CustomAnimation to your subclass of UIButton. Or encapsulate CustomAnimation in your subclass of UIButton, whichever is more appriopriate.

NSButton draw alternate image on click

I know this is probably super easy, but I'm having a hard time wading through header files and could use some guidance.
I have an NSPopUpButton defined in a nib with a menu attached to it. I have defined it in the nib to be "Pull Down" type with no arrow (the images given to me by our designer include a special arrow he wants to use). It is a borderless button. The title properly is empty, though I have set the image and alternateImage.
What I'm looking for is a configuration, either in the nib, file's owner implementation, or by subclass NSPopUpButton, that will allow me to display the button's alternate image (or any other image) while the button's menu is being displayed. Instead, it looks like the system is dimming the button's image.
I've tried numerous nib configurations, various properties of NSButton and NSButtonCell, overriding mouseDown and mouseUp. Nothing I do works.
If playing with the "Type" property doesn't help, you may well have to subclass the drawing of NSButtonCell to get what you want.
- (void)drawImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSView *)controlView in NSButtonCell seems promising.
I think it's custom NSButtonCell class time; I don't know of any way to override the theme for this type of button.
Your only alternative would be to use a regular NSButton with the appropriate image and show the menu at the correct position manually, which would probably be a lot easier to implement.

IOS custom button

I need a custom button like Instragram has in profile tab (the buttons that shows the number of photos and followers) but i don't know how to start to implement it.
Do i need to subclass UIButton or is there other way easier?
I think, the easiest approach would be to create a UIButtom with the typeUIButtonTypeCustom and add a subview to it with imageviews and labels as subviews to create the UI. Composition over inheritance.
Subclassing UIButton seems to me to be the obvious solution. I agree that subclassing UIViewController makes no sense. You don't use UIViewController objects to manipulate individual subviews within a view hierarchy controlled by another UIViewController object.
There are plenty of ways to do this, personally I would subclass UIViewController. Then you can edit its .xib in interface builder to make it look however you want and set different values programmatically. Then to detect a tap on the button you can just use the touchesBegan and touchesEnded (I'm pretty sure those aren't complete method names, check in the docs for more info on them) methods. If you want you could also set up a UITapGestureRecognizer for the view instead.

Should I use IB or Subclass UIView

So, I developed a kind of drop down button class.
Let's call it DDButton.
I mainly export one function :
-(void) addButtonWithImage:(UIImage*)image andTarget:(id)target andSelector:(SEL)selector
which lets the user add another button to the drop down.
I will need to use DDButton in different screens of my app.
I would like to use it like:
DDButton* ddb = [[DDButton alloc] initWithFrame:rect];
[ddb addButtonWithImage....]
[ddb addButtonWithImage....]
My question is since I never subclassed UIView before how should I implement it, and how should I use it later ?
Do I use IB and create a stub UIView which I'll connect to the DDButton in the Identity Pane ?
if so , how exactly I instantiate the view later on.
Or,
Do I subclass UIView ? if so , what methods I should override ? Do you I setup my buttons in the initializer ? in LayoutSubView ? In drawRect ?
I would love to hear the best approach here.
Thanks!
Edit
Let's say I choose the IB way : I have a main button which I set regardless of the
addButtonWithImage() calls, actually all calls to addButtonWithImage just "append" to that button. I want to main button to be the size of the view, until other buttons are added and then the view grows appropriately. However, I want the size of the view to be chosen by the user at first...using setFrame I guess.
Meaning in the awakeFromNib I can't count on the frame size yet (it only take the xib size I assume). So where would I setup my main button ? LayoutSubView ? setFrame ? I'm not sure.
Add your view to the interface in IB as a UIView, then change the class in the identity pane. If you need to do initialization in code, use a -(void)awakeFromNib method. I would suggest setting up the buttons when they are added in addButtonWithImage....
I'd probably do a subclass, building views in code is a good thing to learn.
Override drawrect: to do any custom drawing you need to do, if you're just adding a UIImageview or something and doing positioning you could just override initWith...: and do your custom initialisations.

Looking for info on custom drawing of interface components (Cocoa)

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