Mac开发基础17-NSButton(二)

NSButton是一个功能强大且灵活多样的控件,除了基本使用和常见API外,还有一些进阶用法和技巧可以提高按钮的可用性和实现细节。在以下内容中,我会详细介绍一些进阶使用技巧,并封装一个常用的工具类来实现自定义的多种按钮类型。

进阶使用和技巧

1. 自定义按钮的外观和行为

Objective-C

// 自定义按钮的边框颜色和宽度
- (void)customizeButtonAppearance:(NSButton *)button {
    button.wantsLayer = YES;  // 启用 Core Animation
    button.layer.borderColor = [NSColor redColor].CGColor;  // 设置边框颜色
    button.layer.borderWidth = 2.0;  // 设置边框宽度
    button.layer.cornerRadius = 5.0;  // 设置圆角半径
    button.layer.masksToBounds = YES;  // 避免超出的部分显示
}

Swift

// 自定义按钮的边框颜色和宽度
func customizeButtonAppearance(_ button: NSButton) {
    button.wantsLayer = true  // 启用 Core Animation
    if let layer = button.layer {
        layer.borderColor = NSColor.red.cgColor  // 设置边框颜色
        layer.borderWidth = 2.0  // 设置边框宽度
        layer.cornerRadius = 5.0  // 设置圆角半径
        layer.masksToBounds = true  // 避免超出的部分显示
    }
}

2. 控制按钮的按下和松开行为

Objective-C

- (void)addCustomTrackingToButton:(NSButton *)button {
    NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:button.bounds
                                                                options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow)
                                                                  owner:self
                                                               userInfo:nil];
    [button addTrackingArea:trackingArea];  // 添加追踪区域,用于鼠标进入和离开时的事件处理
}

- (void)mouseEntered:(NSEvent *)event {
    [self.button setTitle:@"Mouse Entered"];  // 鼠标进入时改变按钮标题
}

- (void)mouseExited:(NSEvent *)event {
    [self.button setTitle:@"Mouse Exited"];  // 鼠标离开时恢复按钮标题
}

Swift

func addCustomTrackingToButton(_ button: NSButton) {
    let trackingArea = NSTrackingArea(rect: button.bounds,
                                      options: [.mouseEnteredAndExited, .activeInKeyWindow],
                                      owner: self,
                                      userInfo: nil)
    button.addTrackingArea(trackingArea)  // 添加追踪区域,用于鼠标进入和离开时的事件处理
}

override func mouseEntered(with event: NSEvent) {
    self.button.title = "Mouse Entered"  // 鼠标进入时改变按钮标题
}

override func mouseExited(with event: NSEvent) {
    self.button.title = "Mouse Exited"  // 鼠标离开时恢复按钮标题
}

3. 自定义按钮图层属性

Objective-C

- (void)setButtonShadow:(NSButton *)button {
    button.wantsLayer = YES;  // 启用 Core Animation
    button.layer.shadowColor = [NSColor blackColor].CGColor;  // 设置阴影颜色
    button.layer.shadowOpacity = 0.5;  // 设置阴影透明度
    button.layer.shadowOffset = CGSizeMake(3, -3);  // 设置阴影偏移
    button.layer.shadowRadius = 10.0;  // 设置阴影半径
}

Swift

func setButtonShadow(_ button: NSButton) {
    button.wantsLayer = true  // 启用 Core Animation
    if let layer = button.layer {
        layer.shadowColor = NSColor.black.cgColor  // 设置阴影颜色
        layer.shadowOpacity = 0.5  // 设置阴影透明度
        layer.shadowOffset = CGSize(width: 3, height: -3)  // 设置阴影偏移
        layer.shadowRadius = 10.0  // 设置阴影半径
    }
}

4. 响应鼠标拖动事件

Objective-C

- (void)trackMouseDragForButton:(NSButton *)button {
    [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskLeftMouseDragged handler:^NSEvent * _Nullable(NSEvent * _Nonnull event) {
        NSPoint location = [event locationInWindow];
        [NSCursor.closedHandCursor push];  // 鼠标拖动时改变光标为闭手
        button.frame = NSMakeRect(location.x - button.frame.size.width / 2, 
                                  location.y - button.frame.size.height / 2, 
                                  button.frame.size.width, 
                                  button.frame.size.height);  // 更新按钮位置
        return event;
    }];
}

Swift

func trackMouseDragForButton(_ button: NSButton) {
    NSEvent.addLocalMonitorForEvents(matching: .leftMouseDragged) { event in
        let location = event.locationInWindow
        NSCursor.closedHand.push()  // 鼠标拖动时改变光标为闭手
        button.frame = NSRect(x: location.x - button.frame.size.width / 2,
                              y: location.y - button.frame.size.height / 2,
                              width: button.frame.size.width,
                              height: button.frame.size.height)  // 更新按钮位置
        return event
    }
}

5. 动画效果

Objective-C

- (void)animateButton:(NSButton *)button {
    // 创建一个基本动画来改变按钮的透明度
    CABasicAnimation *fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    fadeAnimation.duration = 1.0;  // 动画持续时间
    fadeAnimation.fromValue = @(1.0);  // 起始状态
    fadeAnimation.toValue = @(0.0);  // 结束状态
    fadeAnimation.autoreverses = YES;  // 动画结束后反转
    fadeAnimation.repeatCount = HUGE_VALF;  // 无限循环动画
    
    // 将动画添加到按钮的图层上
    [button.layer addAnimation:fadeAnimation forKey:@"fadeAnimation"];
}

Swift

func animateButton(_ button: NSButton) {
    // 创建一个基本动画来改变按钮的透明度
    let fadeAnimation = CABasicAnimation(keyPath: "opacity")
    fadeAnimation.duration = 1.0  // 动画持续时间
    fadeAnimation.fromValue = 1.0  // 起始状态
    fadeAnimation.toValue = 0.0  // 结束状态
    fadeAnimation.autoreverses = true  // 动画结束后反转
    fadeAnimation.repeatCount = .greatestFiniteMagnitude  // 无限循环动画
    
    // 将动画添加到按钮的图层上
    button.layer?.add(fadeAnimation, forKey: "fadeAnimation")
}

封装工具类

为了方便创建和管理多种类型的按钮,我们可以封装一个工具类。这个工具类可以用于生成不同类型的按钮,并应用各种自定义设置。

Objective-C

#import <Cocoa/Cocoa.h>

@interface NSButtonFactory : NSObject

+ (NSButton *)createCustomButtonWithTitle:(NSString *)title target:(id)target action:(SEL)action;
+ (NSButton *)createImageButtonWithImage:(NSImage *)image target:(id)target action:(SEL)action;

@end

@implementation NSButtonFactory

+ (NSButton *)createCustomButtonWithTitle:(NSString *)title target:(id)target action:(SEL)action {
    NSButton *button = [[NSButton alloc] init];  // 初始化按钮
    [button setTitle:title];  // 设置标题
    [button setTarget:target];  // 设置目标
    [button setAction:action];  // 设置动作方法
    [self applyCustomStyleToButton:button];  // 应用自定义样式
    return button;
}

+ (NSButton *)createImageButtonWithImage:(NSImage *)image target:(id)target action:(SEL)action {
    NSButton *button = [[NSButton alloc] init];  // 初始化按钮
    [button setImage:image];  // 设置按钮图片
    [button setTarget:target];  // 设置目标
    [button setAction:action];  // 设置动作方法
    [self applyCustomStyleToButton:button];  // 应用自定义样式
    return button;
}

+ (void)applyCustomStyleToButton:(NSButton *)button {
    button.wantsLayer = YES;  // 启用 Core Animation
    button.layer.borderColor = [NSColor blueColor].CGColor;  // 设置边框颜色
    button.layer.borderWidth = 1.0;  // 设置边框宽度
    button.layer.cornerRadius = 4.0;  // 设置圆角半径
    button.layer.masksToBounds = YES;  // 避免超出的部分显示
}

@end

Swift

import Cocoa

class NSButtonFactory {
    
    static func createCustomButton(title: String, target: AnyObject?, action: Selector?) -> NSButton {
        let button = NSButton()  // 初始化按钮
        button.title = title  // 设置标题
        button.target = target  // 设置目标
        button.action = action  // 设置动作方法
        applyCustomStyle(to: button)  // 应用自定义样式
        return button
    }
    
    static func createImageButton(image: NSImage, target: AnyObject?, action: Selector?) -> NSButton {
        let button = NSButton()  // 初始化按钮
        button.image = image  // 设置按钮图片
        button.target = target  // 设置目标
        button.action = action  // 设置动作方法
        applyCustomStyle(to: button)  // 应用自定义样式
        return button
    }
    
    private static func applyCustomStyle(to button: NSButton) {
        button.wantsLayer = true  // 启用 Core Animation
        button.layer?.borderColor = NSColor.blue.cgColor  // 设置边框颜色
        button.layer?.borderWidth = 1.0  // 设置边框宽度
        button.layer?.cornerRadius = 4.0  // 设置圆角半径
        button.layer?.masksToBounds = true  // 避免超出的部分显示
    }
}

使用示例

Objective-C

// 创建自定义标题按钮
NSButton *customButton = [NSButtonFactory createCustomButtonWithTitle:@"Custom Button" target:self action:@selector(buttonClicked:)];

// 创建图片按钮
NSButton *imageButton = [NSButtonFactory createImageButtonWithImage:[NSImage imageNamed:@"buttonImage"] target:self action:@selector(buttonClicked:)];

Swift

// 创建自定义标题按钮
let customButton = NSButtonFactory.createCustomButton(title: "Custom Button", target: self, action: #selector(buttonClicked(_:)))

// 创建图片按钮
let imageButton = NSButtonFactory.createImageButton(image: NSImage(named: "buttonImage")!, target: self, action: #selector(buttonClicked(_:)))
posted @ 2024-08-06 16:52  Mr.陳  阅读(11)  评论(0编辑  收藏  举报