在Cocoa里玩转Dock图标

news/2024/7/7 19:41:47/文章来源:https://www.cnblogs.com/Galesaur-wcy/p/18282260

原文来自;https://cocoa.venj.me/blog/play-with-dock-icon/

今天我们来看一看如何在Cocoa程序中自定义Dock图标。Dock图标的自定义主要包括四方面:

  • 加徽章(Badge)
  • 换图标
  • 隐藏和显示最小化时的图标徽章
  • 增加自定义Dock菜单

本文将对如何进行这四方面的自定义进行简单的介绍,并且在最后研究一下腾讯QQ for Mac独特的Badge机制。本文的示例代码使用了Acorn和腾讯QQ的图标做例子,请这两家厂商不要介意。

1 Dock徽章

给Dock图标加Badge的方法很常见,也很简单,用代码来说事吧。

void AppShimController::SetBadgeLabel(const std::string& badge_label) {
NSApp.dockTile.badgeLabel = base::SysUTF8ToNSString(badge_label);
}

加Badge是用NSDockTile类的-setBadgeLabel:方法;移除Badge是把badgeLabel的内容设置为nil。这个方法在10.5以上都可以使用,除非需要兼容10.4以下的OSX--现在似乎已经没有很大的必要了,或者是有其他特别的理由,否则真的很难拒绝使用Cocoa的这个简单的API调用。 ;)

2 更换Dock图标

有很多程序能够动态的修改程序图标,如,Adium和iCal。我们通过代码,我们可以在程序运行的时候动态设置Dock图标。修改图标有两种方法,一种是直接指定一个NSImage对象设置应用程序的图标;另一种是用一个自定义的View,来显示为Dock图标。

// Customize Dock Icon
- (IBAction)changeDockIcon:(id)sender {[NSApp setApplicationIconImage:[NSImage imageNamed:@"Icon"]];
}// Restore Dock Icon
- (IBAction)restoreDockIcon:(id)sender {[NSApp setApplicationIconImage:nil];
}// Draw Dock Icon with Custom View
- (IBAction)changeDockIconWithCustomView:(id)sender {DockIconView *dockView = [[[DockIconView alloc] init] autorelease];[[NSApp dockTile] setContentView: dockView];[[NSApp dockTile] display];
}

 

用自定义View做图标不能自动刷新,所以如果Dock图标有所改变--如加Badge时,可能需要手动通过-display方法刷新。

上面介绍的两种方法修改的程序图标会在程序退出之后还原为在Info.plist里指定的应用程序图标。要永久的改变程序图标(也就是退出程序的时候也能显示修改后的图标)的方法是创建Dock图标的插件。因为这个话题涉及Bundle相关的内容,在这里就不详述了,详情可以参考苹果的文档,以后有机会我会专门写文章介绍Dock图标插件的话题。

3 隐藏和显示最小化时的图标徽章

OSX的窗口在最小化的时候,在缩略图的右下角会显示一个程序图标徽章。我们可以通过程序来显示和隐藏最小化图标的徽章。方法很简单如下:

1
2
3
4
5
6
7
8
9
// Show minimize icon badge
- (IBAction)showMinimizeBadge:(id)sender {
    [[self.window dockTile] setShowsApplicationBadge:YES];
}

// Remove minimize icon badge
- (IBAction)removeMinimizeBadge:(id)sender {
    [[self.window dockTile] setShowsApplicationBadge:NO];
}

4 Dock菜单

Dock菜单有两种方法指定--一种是直接在XIB中静态的设计菜单,然后通过Interface Builder关联到NSAppdockMenu属性;另一种是通过ApplicationDelegate-applicationDockMenu:方法,在程序中动态指定菜单。静态Dock菜单的指定方法如下:

所有操作通过Interface Builder就能完成。

动态指定Dock菜单的方法如下面的代码所示:

1
2
3
- (NSMenu *)applicationDockMenu:(NSApplication *)sender {
    return self.dynamicMenu;
}

为了简便起见,我实际上并没有通过代码动态的创建菜单,上面的示例代码仅仅是引用了一个XIB里的菜单对象,通过-applicationDockMenu:方法返回。

5 QQ风格的Dock徽章

你可能已经注意到了这个QQ图标的Badge和最上方的那个QQ图标的Badge有些不一样。没错,最上方的那个Badge是Lion的默认的风格的图标,是我做的一个示例,图标借用了腾讯QQ的图标。不过实际的QQ的Badge并不是使用OSX的系统Badge。具体腾讯怎么做的我也不是很清楚,不过我用自定义View用腾讯的空白Badge图标做了一个模仿的例子:

我做的这个模仿示例,字体有些不太像,Badge文字的定位也有点不准确,不过我猜想腾讯的思路基本是和我类似,现在给出我写的实现。再次强调一下,这并非腾讯官方的方法,示例代码仅供参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
- (void)drawRect:(NSRect)dirtyRect
{
    // Drawing code here.

    // Draw Dock Icon
    NSImage *image = [NSImage imageNamed:@"qqbadge"];
    NSImageView *imageView = [[NSImageView alloc] initWithFrame:self.frame];
    imageView.image = image;
    [self addSubview:imageView];
    [imageView release];

    // Draw Badge Label
    NSRect labelFrame;
    CGFloat width = self.frame.size.width;
    CGFloat height = self.frame.size.height;
    labelFrame.origin = CGPointMake(width * 0.62, height * 0.60);
    labelFrame.size = CGSizeMake(width * 0.25, height * 0.25);
    self.label = [[NSTextField alloc] initWithFrame:labelFrame];
    self.label.backgroundColor = [NSColor clearColor];
    self.label.textColor = [NSColor whiteColor];
    self.label.drawsBackground = NO;
    self.label.stringValue = self.labelText;
    //在使用的时候,需要修改徽章Label,只需设置这个view对象的labelText属性即可
    NSFont *font = [NSFont fontWithName:@"Arial" size:32];
    [self.label setFont:font];
    [self.label sizeToFit];
    [self.label setBordered:NO];
    [self addSubview:self.label];
    [self.label release];
}

方法大致是,通过自定义View,绘制一个带空白Badge的图标,然后绘制一个图标徽章Label到Badge的位置,控制其大小,使其正好位于Label内部。

不过这种方法绘制的Badge有一个缺陷,那就是Badge的Label的长度不能太长,超过2个数字就不适合用这样的方法了。相比起来,用系统自带的Badge在Label很长的时候会自动拉长,更加灵活,而且只需一行代码,简单很多。可能腾讯这么做的目的最初是为了兼容Mac OS X 10.4才用了自定义View来绘制Badge;不过时代在进步,既然Cocoa已经提供了一个很简单的绘制Badge的API,腾讯是不是也应该更新一下了,况且,QQ for Mac现在的版本已经不再兼容10.6以下的系统了。

最后,本文的所有代码都已经包含在了一个示例项目Play With Dock中了,上图是运行的例子,代码已经推送到Github上了,有兴趣的可以看看,并且批评指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/736950.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VMware vSphere Tanzu部署_10_开启Tanzu功能

1.开启Tanzu功能 1.1. Tanzu开启的必要条件网络需要为vds网络或者nsx网络 esxi集群需要开启DRS和HA功能 需要配置Tanzu存储策略 需要部署有负载均衡(nsx或者haproxy或者nsx avi) 需要配置有Tanzu Kubernetes内容库1.2. 初始化Tanzu启用Tanzu功能选择tanzu网络为VDS网络选择需要…

如何计算弧线弹道的落地位置

1)如何计算弧线弹道的落地位置2)Unity 2021 IL2CPP下使用Protobuf-net序列化报异常3)编译问题,用Mono可以,但用IL2CPP就报错4)Wwise的Bank在安卓上LoadBank之后,播放没有声音这是第393篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术…

内推失败!

简历的重要性相信大家都是清楚的,简历的好坏直接决定了面试机会的多少,以及是否有面试机会。 例如,上周我这把一个 92 院校的同学推荐给朋友表哥了,他表哥是某知名电商公司 Leader 级别的人物,他去这个 PDD 已经 5 年了,是位不折不扣的大佬,但推荐的结果却令人感到失望,…

Springboot+Vue加密通信

前言本文旨在给出Springboot+Vue 框架下的加密通信具体实现,同时为照顾非行业内/初学读者,第一小节浅显的解释下加解密方式,老鸟直接跳过。 1 加解密方式常见的加解密方式大概分成对称加密、非对称加密与信息摘要算法三类。下面仅从使用角度简单介绍下加解密方式: 1.1 对称…

VMware vSphere Tanzu部署_09_配置tanzu内容库

配置Tanzu内容库Tanzu内容库订阅地址为:https://wp-content.vmware.com/v2/latest/lib.json如下为配置步骤在vcenter中配置内容库即可

Centos7下安装Redis

1.安装依赖 redis是由C语言开发,因此安装之前必须要确保服务器已经安装了gcc,可以通过如下命令查看机器是否安装:gcc -v如果没有安装则通过以下命令安装:yum install -y gcc2.下载redis安装包并解压# 下载,我是在root下执行的下载,所以我的下载目录为:/root/redis-6.2.6…

Winform SynchronizationContext多线程更新画面控件

SynchronizationContext在通讯中充当传输者的角色,实现功能就是一个线程和另外一个线程的通讯。需要注意的是,不是每个线程都附加SynchronizationContext这个对象,只有UI线程是一直拥有的。故获取SynchronizationContext也只能在UI线程上进行SynchronizationContext context…

复数与复变函数选题

【参考】《复变函数论》钟玉泉编 《复变函数论学习指导书》钟玉泉编

Kubernetes基于helm安装 harbor

Kubernetes基于helm安装 harbor 之前harbor的安装都是借助docker完成一键安装部署,安装完成之后harbor组件均运行到一台机器上面,本文实践harbor在k8s环境中的部署。 准备工作 根据harbor官方要求:Kubernetes cluster 1.20+ Helm v3.2.0+结合ingress-nginx版本要求,建议K8S…

pdf的表格怎么转换成word?

Adobe设计PDF文件格式的目的是支持跨平台、多媒体集成的信息出版和发布,特别是对网络信息发布的支持。为了实现这一目标,PDF具有许多其他电子文件格式无法比拟的优势。如今,越来越多的电子书籍、产品描述、公司通知、网络数据和电子邮件开始使用PDF格式文件。但是PDF却不能直…

高效存储的秘诀:bitmap 数据结构在标签中的应用

在当今大数据和信息爆炸的时代,如何有效地管理和查询海量的数据成为了企业和开发者面临的重大挑战。其中,标签系统作为数据管理中的一种重要手段,被广泛应用于用户画像、商品分类、内容推荐等多个场景。然而,随着标签数量的急剧增加,传统的数据存储和查询方式已难以满足高…

2024年值得收藏的几款开源主机安全系统hids

随着云技术的迅速发展,主机安全系统HIDS作为服务器安全的最后一道防线,无论传统的硬件厂商,还是各大云厂商如阿里、腾讯云非常重视并闷声发大财。HIDS主机安全开源的项目虽多,但能实际用的极少,笔者经过大量搜索,找到以下几款优秀的产品供大家参考: 1、OpenHFWOpenHFW全…

代码随想录算法训练营第四十六天 | 买卖股票的最佳时机

121.买卖股票的最佳时机 题目链接 文章讲解 视频讲解动规五部曲:dp[j][0]: 表示持有股票的最大现金,dp[j][1]表示不持有股票的最大现金 递推公式:第j天持有股票的最大现金为:之前就持有这只股票和今天持有这只股票取最大值: dp[j][0] = max(dp[j-1][0], -prices[j]); 第j天…

Asp.Net Core -Authorizationz授权

授权的内部实现参考 动态授权参考动态授权 基于权限的授权 1.定义权限-Permissionspublic class Permissions{public const string Admin = "Admin";public const string Users = "Users";public const string UserCreate = Users+ ".Create";pu…

结对项目

命令行参数处理: 使用 argparse 或者 sys 模块处理命令行参数,以接收用户输入的题目数量和题目范围(例如最大数值)。 生成四则运算题目: 随机生成题目,每个题目包括两个操作数和一个运算符。 控制生成的题目数量和数值范围,确保生成的题目符合小学生的学习要求(比如操作…

详解微服务应用灰度发布最佳实践

本次分享是站在 DevOps 视角的灰度发布实践概述,主要内容包括以下四个方面:第一,灰度发布要解决的问题;第二,灰度发布的四种典型场景;第三,如何把灰度发布融入到应用的研发流程中,即把灰度发布与 DevOps 工作融合;第四,对于外部流量灰度场景,演示如何通过工具将其落…

OpenBMB Hugging Face THUNLP,联袂献上经典大模型课

这个夏天,THUNLP 携手 Hugging Face 和 OpenBMB,推出 大模型公开课第二季。在大模型公开课第二季中,将有全球知名开源社区 OpenBMB X Hugging Face 梦幻联动;MiniCPM、ChatDev、Ultra对齐 等明星开源项目作者亲自授课,带领同学从深度学习开始快速了解大模型的相关理论并进…

nginx开启https

生成自签名证书 如果是在运营商处获得的证书,则不用这一步点击查看代码 mkdir /etc/nginx/ssl cat > /etc/nginx/ssl/nginx.cnf <<EOF [ req ] default_bits = 2048 distinguished_name = req_distinguished_name req_extensions = req_ext x509_extension…

(三)JS逆向——爬取易车网

爬取易车网的车辆配置信息 所以主要就是确定这几个是怎么生成的 搜索x-sign值的位置,打断点,找到构建x-sign的函数 注意,一定要看清是否是正确的url,x-timestamp明显是时间戳 进入这个函数 x-sign值,是对这个字符串做md5,这个字符串由三部分构成,参数、时间戳、和一个固…

.Net知识技能大全

.Net知识技能大全 更多请见https://www.dotnetshare.com C#常见运算符一元运算符(+、-、!、~、++、--) 算术运算符(*、/、%、+、 – ) 移位运算符(<< 、>> ) 关系和类型测试运算符(==、!=、<、>、<=、>=、is 和 as) 逻辑运算符(&、^ 和 |…