Je veux un simple bouton-poussoir (celui avec les coins arrondis), et pour ajouter un fond à celui-ci. J'ai essayé 2 choses:
1 - utilisation d’une image de bouton rond: cela fonctionne bien, jusqu’à ce que j’ai besoin de redimensionner le bouton, ce qui rend les parties rondes moche.
2 - étendre le bouton et y ajouter de la couleur - mais j'ai des problèmes lorsque je clique sur le bouton - je veux que l'état "poussé" ait la même couleur que l'état "normal", mais ce n'est pas le cas.
c'est le code que j'utilise pour étendre le bouton:
override func drawRect(dirtyRect: NSRect)
{
if let bgColor = bgColor {
self.layer?.cornerRadius = 4
self.layer?.masksToBounds = true
self.layer?.backgroundColor = bgColor.CGColor
bgColor.setFill()
NSRectFill(dirtyRect)
}
super.drawRect(dirtyRect)
}
Quoi qu'il en soit, ni l'approche 1 ni l'approche 2 n'ont fonctionné, alors comment puis-je atteindre cet objectif? Juste un simple bouton .. :(
EDIT: Je parle d’OSX
Remplacez la méthode drawWithFrame de NSButtonCell:
func drawWithFrame(cellFrame: NSRect, inView controlView: NSView) {
var border = NSBezierPath(roundedRect: NSInsetRect(cellFrame, 0.5, 0.5), xRadius: 3, yRadius: 3)
NSColor.greenColor().set()
border.fill()
var style = NSParagraphStyle.defaultParagraphStyle()
style.alignment = NSCenterTextAlignment
var attr = [NSParagraphStyleAttributeName : style, NSForegroundColorAttributeName : NSColor.whiteColor()]
self.title.drawInRect(cellFrame, withAttributes: attr)
}
J'ai fait un bouton et réussi. Cela ressemble à ceci:
Code:
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
// Drawing code here.
if let bgColor = bgColor {
self.layer?.cornerRadius = 4
self.layer?.masksToBounds = true
self.layer?.backgroundColor = bgColor.cgColor
bgColor.setFill()
NSRectFill(dirtyRect)
}
}
drawRect est remplacé par draw, et CGColor est remplacé par cgColor. La différence entre le vôtre et le mien est l'ordre. Vous avez appelé super.draw(dirtyRect)
en dernier et je l’ai appelé en premier. Peut-être que votre bouton ressemble à ceci:
J'espère que cela peut résoudre votre problème.
Solution OBJECTIVE-C (pourrait aider certains types à trébucher sur ce fil)
Cette sous-classe étend IB - vous pouvez donc contrôler IB soit:
Il inclut également une petite animation alpha en vol stationnaire.
Nouveaux contrôles dans IB (cliquez pour voir la capture d'écran)
//
// SHFlatButton.h
//
// Created by SH on 03.12.16.
// Copyright © 2016 SH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface SHFlatButton : NSButton
@property (nonatomic, strong) IBInspectable NSColor *BGColor;
@property (nonatomic, strong) IBInspectable NSColor *TextColor;
@property (nonatomic, strong) IBInspectable NSColor *BGColorHover;
@property (nonatomic, strong) IBInspectable NSColor *TextColorHover;
@property (nonatomic) IBInspectable CGFloat CornerRadius;
@property (strong) NSCursor *cursor;
@end
Et la mise en place ...
//
// SHFlatButton.m
//
// Created by SH on 03.12.16.
// Copyright © 2016 SH. All rights reserved.
//
#import "SHFlatButton.h"
@implementation SHFlatButton
- (void)awakeFromNib
{
if (self.TextColor)
[self setAttributedTitle:[self textColor:self.TextColor]];
if (self.CornerRadius)
{
[self setWantsLayer:YES];
self.layer.masksToBounds = TRUE;
self.layer.cornerRadius = self.CornerRadius;
}
}
- (void)drawRect:(NSRect)dirtyRect
{
if (self.BGColor)
{
[self.BGColor setFill];
NSRectFill(dirtyRect);
}
[super drawRect:dirtyRect];
}
- (void)resetCursorRects
{
if (self.cursor) {
[self addCursorRect:[self bounds] cursor: self.cursor];
} else {
[super resetCursorRects];
}
}
- (void)updateTrackingAreas {
NSTrackingArea* trackingArea = [[NSTrackingArea alloc]
initWithRect:[self bounds]
options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways
owner:self userInfo:nil];
[self addTrackingArea:trackingArea];
}
- (void)mouseEntered:(NSEvent *)theEvent{
if ([self isEnabled]) {
[[self animator]setAlphaValue:0.9];
if (self.BGColorHover)
[[self cell] setBackgroundColor:self.BGColorHover];
if (self.TextColorHover)
[self setAttributedTitle:[self textColor:self.TextColorHover]];
}
}
- (void)mouseExited:(NSEvent *)theEvent{
if ([self isEnabled]) {
[[self animator]setAlphaValue:1];
if (self.BGColor)
[[self cell] setBackgroundColor:self.BGColor];
if (self.TextColor)
[self setAttributedTitle:[self textColor:self.TextColor]];
}
}
- (NSAttributedString*)textColor:(NSColor*)color
{
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setAlignment:NSCenterTextAlignment];
NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
color, NSForegroundColorAttributeName,
self.font, NSFontAttributeName,
style, NSParagraphStyleAttributeName, nil];
NSAttributedString *attrString = [[NSAttributedString alloc]initWithString:self.title attributes:attrsDictionary];
return attrString;
}
EDIT: Le boutonDOITavoir la bordure désactivée!
essayez simplement d'ajouter ces deux lignes de code dans votre fonction.Je pense que vous obtenez un problème de largeur de bordure.
redéfinit func drawRect (dirtyRect: NSRect)
{
if let bgColor = bgColor {
self.layer?.cornerRadius = 4
self.layer?.masksToBounds = true
self.layer?.backgroundColor = bgColor.CGColor
self.layer?.borderColor = UIColor.blackcolor()
self.layer?.borderWidth = 2.0
bgColor.setFill()
NSRectFill(dirtyRect)
}
super.drawRect(dirtyRect)
}
Vous devez remplacer la fonction layoutSubviews, c'est-à-dire.
override func layoutSubviews() {
self.layer.cornerRadius = self.frame.height/2
self.layer.borderColor = UIColor.blue.cgColor
self.layer.borderWidth = 2
}
J'ai commis un exemple de projet ici . Tout votre code associé a été écrit dans button.Swift et il est dans Swift 3. En outre, je n'ai pas défini l'image de fond pour le bouton, je vous laisse cette tâche.
P.S .: La réponse ci-dessous concerne UIButton, pas NSButton. Certains seront probablement valables, probablement pas tout ...