Change NSButton title position - objective-c

I want to change the title position of NSButton that has a background image so that i can place the title in the bottom left corner of the button and in the same time overlaps the image

Sounds like you need to override the drawing methods in NSButtonCell (that's what NSButton uses for drawing). I've created subclasses that "fake out" the NSButtonCell implementation for simple adjustments. To do this, create a subclass of NSButtonCell and set it up as the cell for your NSButton. Next override the drawing methods of NSButtonCell (there are multiple depending on what you're trying to do), adjust your target frame and then call the superclass (NSButtonCell) implementation.
Depending on how much you need to do though, you may just be writing your own drawing methods. This gives you the most control.

Related

How to create a custom NSSlider with a transparent middle bar and custom knob size

I've searched around for some code on NSSliderCell but I can't find a way to do what I'm looking for.
I'd like to create something like this (where the white line is the slider knob, 1 pixel width):
I'm going to use this for the time bar of a music track, so it's going to move every second (that's why I want to use a NSSlider to make things easy).
What do I need to do to make a slider, with a transparent middle bar, similar to the image above?
PS: It's not going to be touchable, it's just for display.
You can just override drawRect:, as when subclassing NSView, except in your implementation, use [self doubleValue] to determine where to draw the line. However, I don't see the point of subclassing NSSlider in this case. A custom NSView could have a property that determines where to draw the line, and then other code could set that property or bind to it.
That looks like a vertical split view to me with a 1 pixel wide divider. You might try that. There's a method to set the position of the divider so it would be easy to move as you need. And you can make the divider 1 pixel by creating a subclass of NSSplitview and overriding the dividerThickness method to return 1. Then you just set the background of the 2 subviews to black and there you go. It's easy to try so maybe it will work for you. Good luck.
I finally got it:
I created a NSSliderCell subclass with a property #property float x;
I overrode the drawKnob method and inside it I wrote:
-(void)drawKnob:(NSRect)knobRect{ self.x = knobRect.origin.x; }
I dragged a NSSlider into my window (made it small, changed it's width to the window's width) and changed it's cell class to the one I created;
And then when the music is playing, every time a second goes by I do:
[_timeBarSlider setMinValue:0];
[_timeBarSlider setMaxValue:myTrack.duration];
[_timeBarSlider setDoubleValue:myPlayer.currentPosition];
[[_timeBarImageView animator] setFrame:NSMakeRect(_timeBarSliderCell.x, yourYCoordinate, yourWidth, yourHeight)];
_timerBarSlider is the NSSlider I have in IB / _timerBarImageView is the image view that contains the vertical image line / _timerBarSlderCell is the NSSlider's cell (subclassed)
PS: the NSSlider is behind every object in that window, so that the user can't see it. You can't setHidden:YES on it because the drawKnob method will not be called.

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.

Xcode-style font picker

I'd like to add a font picker in my app. Xcode's Interface Builder has a great implementation which is used in Xcode's own preferences' window too.
It's the one with a little 'T' button (seemingly) inside the font name text field itself.
Is this a standard cocoa implementation?
You'll need to roll your own. See Subclassing NSControl. You'll subclass NSTextField and NSTextFieldCell. Read the entire guide, actually. Once you've got a good understanding, then you can override the drawing/geometry routines to return a rect whose width is slightly smaller (small enough to leave room for the font "button"). Then draw your font button. You'll respond to its mouse events on the font button the same as you would for any NSView.
There's no standard control for the preview text box with the button, but there is the standard NSFontPanel class that you can use to let users select the font once the 'T' button has been clicked.
Best idea is probably to override NSTextFieldCell. I've been able to get the desired appearance by overriding -drawInteriorWithFrame:inView:, and passing a slightly less wide frame when calling through to super, then drawing the button myself. You'd also have to implement the mouse tracking of the button yourself, but you could probably just create your own NSButtonCell instance and call through to it for a few methods with the sub-rect for the button.
For convenience, you may also want to create a NSTextField subclass that uses this cell instead of a straight NSTextFieldCell, but if you're loading stuff from a XIB, you can just change the class of the cell in the XIB and leave it in a regular text field view.

How to keep NSPanel within NSScreen visibleframe always

I have one floating NSPanel in my app, which user can move using mouse. I want my NSPanel to always visible within main screen. I want code to reposition my NSPanel with its original width and height within screen border in all the sides.
Thanks,
Subclass NSPanel and override the frame-relative methods. setFrameOrigin:, setFrame:display: and maybe others (see the documentation to find out all the methods). There is also promising - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen method.

Add a second image to a custom UIButton

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!