web-dev-qa-db-fra.com

NSButton avec coins arrondis et couleur de fond

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 

13
Roee84

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)
}
5
rocky

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.

5
A.Flash

Solution OBJECTIVE-C (pourrait aider certains types à trébucher sur ce fil)

Cette sous-classe étend IB - vous pouvez donc contrôler IB soit:

  • Couleur de fond 
  • Couleur de fond sur le survol
  • Titre du titre 
  • Couleur du titre en survol
  • Rayon de coin

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!

1
Pat_Morita

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)
}
0
Akash vishwakarma

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 ...

0
Sanchit Kumar Singh