如何在Cocoa中绘制锥形线+椭圆形阴影

2023-11-27

背景:

下图是 OS X Lion 中的 Mail.app。当源列表变得太长时,源列表底部的按钮上方会出现一条漂亮的阴影线。当您滚动时,源列表将移动到该阴影线下方。当您展开窗口以使源列表中的所有内容都适合而无需滚动时,阴影线就会消失。

问题:

我如何使用 Cocoa 绘制这条阴影线?我知道 NSShadow 等,但在我看来,这里发生的不仅仅是一个影子。有一条线巧妙地淡化为点(就好像您在 Photoshop 中对两端应用了渐变蒙版一样。)同样,阴影是oval当您接近线路末端时,该信号逐渐减弱。所以它不仅仅是一个普通的 NSShadow,是吗? (它绝对不是图像,因为当您扩展源视图的宽度时它可以很好地缩放。)

任何有关如何绘制此形状的提示将不胜感激。

enter image description here

对于那些坚持不懈的人来说,不,这并不违反保密协议,因为 Mail.app 已被苹果公开展示。


大概的概念:

.

  1. Create a layer "Layer A" with dimensions 150px × 10px
    and fill it with a Gradient with:
    • 下部颜色: #535e71 opacity: 33%
    • 鞋面颜色: #535e71 opacity: 0%
  2. 创建一个图层“Layer B”方面150px × 1px
    并用固体填充它#535e71 opacity: 50%
  3. Compose“A层”和“B层”together进入“C 层”。
  4. Apply 反射梯度掩模 from #ffffff to #000000到“C 层”。

视觉步骤:

enter image description here

功能代码:

MyView.h:

#import <Cocoa/Cocoa.h>

@interface MyView : NSView {
@private

}

@end

MyView.m:

#import "MyView.h"

@implementation MyView

- (CGImageRef)maskForRect:(NSRect)dirtyRect {
    NSSize size = [self bounds].size;
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);

    CGContextClipToRect(context, *(CGRect*)&dirtyRect);

    CGRect rect = CGRectMake(0.0, 0.0, size.width, size.height);

    size_t num_locations = 3;
    CGFloat locations[3] = { 0.0, 0.5, 1.0 };
    CGFloat components[12] = {
        1.0, 1.0, 1.0, 1.0,  // Start color
        0.0, 0.0, 0.0, 1.0,  // Middle color
        1.0, 1.0, 1.0, 1.0,  // End color
    };

    CGGradientRef myGradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, num_locations);

    CGPoint myStartPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGPoint myEndPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));

    CGContextDrawLinearGradient(context, myGradient, myStartPoint, myEndPoint, 0);

    CGImageRef theImage = CGBitmapContextCreateImage(context);
    CGImageRef theMask = CGImageMaskCreate(CGImageGetWidth(theImage), CGImageGetHeight(theImage), CGImageGetBitsPerComponent(theImage), CGImageGetBitsPerPixel(theImage), CGImageGetBytesPerRow(theImage), CGImageGetDataProvider(theImage), NULL, YES);

    [(id)theMask autorelease];

    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);

    return theMask;
}

- (void)drawRect:(NSRect)dirtyRect {
    NSRect nsRect = [self bounds];
    CGRect rect = *(CGRect*)&nsRect;
    CGRect lineRect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, (CGFloat)1.0);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
    CGContextClipToRect(context, *(CGRect*)&dirtyRect);
    CGContextClipToMask(context, rect, [self maskForRect:dirtyRect]);

    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat components[8] = {
        0.315, 0.371, 0.450, 0.3,  // Bottom color
        0.315, 0.371, 0.450, 0.0  // Top color
    };

    CGGradientRef myGradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, num_locations);

    CGPoint myStartPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGPoint myEndPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect));

    CGContextDrawLinearGradient(context, myGradient, myStartPoint, myEndPoint, 0);

    CGContextSetRGBFillColor(context, 0.315, 0.371, 0.450, 0.5 );
    CGContextFillRect(context, lineRect);

    CGColorSpaceRelease(colorSpace);    
}

@end

(我第一次使用纯粹的低级 CoreGraphics,因此可能未达到最佳标准,有待改进。)

This is an actual screenshot of what the code above produces:
enter image description here
The drawing stretches to the view's dimensions.

(I formerly had two techniques shown here: "Technique A" & "Technique B".
"Technique B" provided superior results and was way simpler to implement as well, so I ditched "Technique A".
Some comments may still refer to "Technique A" though. Just ignore them and enjoy the fully functional code snippet.).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在Cocoa中绘制锥形线+椭圆形阴影 的相关文章

  • (Kiss)XML xpath 和默认命名空间

    我正在开发一个 iPhone 项目 需要解析一些 xml xml 可能包含也可能不包含默认名称空间 我需要知道如何解析 xml 以防它使用默认命名空间 由于我需要读取和写入 xml 因此我倾向于使用 KissXML 但我愿意接受建议 这是我
  • iOS:生成pdf时绘制文本时如何设置字体?

    我在ios应用程序中使用drawpdf函数生成pdf 同时调用nsobject类中的drawtext函数 它根据我指定的框架和字符串清楚地绘制文本 我的代码是 void drawText NSString textToDraw inFram
  • Objective-C NSString for 循环与characterAtIndex

    我试图逐个字符地循环遍历 NSString 但出现 EXC BAD ACCESS 错误 您知道如何正确执行此操作吗 我已经在谷歌上搜索了几个小时但无法弄清楚 这是我的代码 m self textLength self text length
  • 如何在 Mac OSX Mavericks 中正确运行字符串工具?

    如何在 Mac OSX Mavericks 中正确运行字符串工具 我尝试按照我在网上找到的示例来运行它 strings a UserParser class 但我收到此错误 错误 Applications Xcode app Content
  • NSTextField 字体样式在选择时重置

    Context 在 Interface Builder 中 我有一个不可编辑的标签 NSTextField 标签的内容是使用 Cocoa Bindings 创建的 绑定的值是NSAttributedString 使用数值转换器创建 看图片
  • Cocoa 应用程序菜单栏不可点击

    我正在我的可可应用程序中构建一个菜单栏 其中包含以下代码 implementation我的自定义应用程序CustomApplication void setUpMenuBar CustomApplication sharedApplicat
  • 与大多数其他 OS X 应用程序相比,我到底应该传递什么给 -[NSApp activateIgnoringOtherApps:] 才能让我的应用程序“自然”启动?

    当我学习如何自己启动 NSApplications 时 我使用的代码 基于here https bitbucket org rsc plan9port src 18c38bf29b0b8eb3ffd0afb44d22f9bfcda8bc58
  • “预期的 ';'在 Swift 下的顶级声明符之后”

    我正在尝试将所有颜色设置在一个 Swift 文件中 该文件可以在我的整个应用程序中使用 下面的代码会导致 import Foundation import UIKit class DotColors let tsblueColor UICo
  • watchOS 错误:控制器接口描述中的未知属性

    我将 WKInterfacePicker 添加到情节提要中 并将其连接到界面控制器中的 IBOutlet 运行应用程序时 它在控制台中显示一条错误消息 控制器的接口描述 watchPicker 中的未知属性 Code interface I
  • UIPickerView selectRow 未按预期工作

    我创建了一个UIPickerView它有两个组件 第一个组件 A 的行数固定为 13 另一个组件 B 的行数可变 具体取决于 A 中选择的行 加载时UIPickerView我调用以下命令 以便我可以在两个组件中默认选择 但是我遇到的问题是只
  • rvm:未找到命令 MAC OX

    真的 我不知道发生了什么 对不起 如果这个问题太菜鸟了 但我找不到这个问题的解决方案 bash rvm 找不到命令 我试过这个 curl L https get rvm io https get rvm io bash s 版本最新 但我仍
  • 处理 UICollectionView 中的点击手势

    由于我无法使用任何框架来创建相册 因此我尝试使用 Collection View 创建自己的相册 但我一开始就陷入困境 我的目标是将网络服务中的所有图像显示到我的集合视图中 因为所有图像都已显示 下一步是当有人点击任何单元格时 我可以在新视
  • Cornerstone 与 Mac OS X 版本 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何使用 Objective-C 解析 JSON?

    我是 iPhone 新手 谁能告诉我解析此数据并获取活动详细信息 名字和姓氏的步骤 error false data activity id 35336 user id 1 user first name Chandra Bhusan us
  • iOS8 自签名证书已安装但仍不受信任

    由于我无法控制的原因 我需要使用自签名证书针对平台进行 iOS 开发 它是一个在 SAN 中具有特定 IP 地址的根证书 当证书安装在 OSX 系统帐户下时 所有浏览器现在将正常信任对给定 IP 地址的任何访问 通过电子邮件将同一证书发送到
  • 如何在禁用状态下更改 UIButton 图像 alpha?

    我有一个带有图像的 UIButton 在其禁用状态下 该图像应具有 0 3 alpha UIButton button UIButton buttonWithType UIButtonTypeCustom UIImage arrowImag
  • XOR或其他简单的文件混淆方法ios目标c

    我正在开发一个使用受版权保护的 pdf 文件的 ios 应用程序 我正在寻找一些简单的方法来混淆文件以确保安全 这些方法不需要我经历额外的大众市场 CCATS 加密审查流程 但也将确保版权所有者已尽我所能来保证他们的数据安全 当然 我用密码
  • 辅助功能标识符在 iOS 模拟器的辅助功能检查器中不可见

    我想使用辅助功能检查器来验证在模拟器 iOS 9 2 中运行的应用程序中的所有辅助功能标识符 辅助功能检查器能够返回多个辅助功能字段 但不能返回标识符 知道为什么以及如何我能看到它们吗 实际上有一种方法 克里斯 普林斯 Chris Prin
  • 在 UIScrollView 中禁用 2 根手指滚动

    我想在我的应用程序中禁用两指滚动UIScrollView 我对其进行了子类化 并使用以下代码调整了其内置手势识别器 for UIGestureRecognizer mgestureRecognizer in scroller gesture
  • 在 Python 的 Textmate 中突出显示尾随空格?

    我想做类似的事情this http remysharp com 2008 03 30 trailing white space in textmate Textmate 提示 这样当我在 Python 中编写代码时 尾随空白总是以某种方式突

随机推荐

  • 提高性能的最佳方法(并包括某种故障转移)

    我们有一个应用程序正在运行 其中 IIS 和 SQL 在同一台计算机上 它是一个windows2003standard 服务器 在VM 上运行4gigs RAM 现在用户数量正在不断增长 还有一些巨大的统计数据 它们可以由用户运行 但对其他
  • C# 2.0 中的 HashSet 替换

    I using List
  • 无法从中央传输工件 org.apache.maven.plugins:maven-surefire-plugin:pom:2.7.1 (http://repo1.maven.org/maven2)

    我在 SpringSource Tool Suite 中创建了一个新的 Maven 项目 我在我的新 Maven 项目中收到此错误 转移失败 org apache maven plugins maven surefire plugin po
  • 无需下载即可获取文件大小

    如何从 URL 获取文件大小 在 Flutter 中 我可以通过使用以下方式获得它 http Response response await http get url print response contentLength 但这会下载整个
  • Python:PyQt QTreeview 示例 - 选择

    我正在使用 Python 2 7 和 Qt 设计器 并且我是 MVC 新手 我在 Qt 中完成了一个视图 为我提供了目录树列表 以及用于运行事物的控制器 我的问题是 给定 Qtree 视图 选择目录后如何获取目录 代码快照如下 我怀疑它是
  • 扩展 Django 的通用视图

    我正在用 Django 编写我的第一个应用程序 但我遇到了一个问题create object通用视图 在我的urls py 我有 r new CreateView as view 问题是 当用户提交 新 表单时 我需要操作将保存到数据库的数
  • 使用 Java 的文件资源管理器 - 如何进行?

    我准备使用 Java 创建一个文件浏览器 目的是尽可能模仿默认浏览器的行为 无论底层操作系统是什么 我没有用 Java 做过任何 GUI 编程 我已经查找了 Swing SWT 和 JFace 并且我将通过本教程开始我的项目 http ww
  • window.navigator.userAgent 真的会被弃用吗?

    I just 在 MDN 上阅读关于window navigator userAgent 已弃用 此功能已从 Web 标准中删除 尽管某些浏览器可能仍然支持它 但它正在开发中 被丢弃 不要在旧项目或新项目中使用它 页面或网络应用程序 使用它
  • 使用 gdb/gdbserver 远程调试共享库

    我的问题是关于使用 gdb gdbserver 远程调试嵌入式 Arm 处理器上的应用程序 我可以调试应用程序本身 但应用程序动态链接到实现内部通信协议的共享库 我希望能够在共享库函数中设置断点 因此尝试找出一些设备发现问题 我已确保该库使
  • 将 RxJS Observable 收集到数组

    我想使用 RxJS 将异步事件世界与同步世界 桥接 具体来说 我想创建一个函数 它返回在某个时间间隔内收集的事件数组 我可以创建 Observable 来执行我想要的操作 var source Rx Observable interval
  • 无法识别“pip”[重复]

    这个问题在这里已经有答案了 我尝试安装PySide但我从 powershell 收到错误如下 pip The term pip is not recognized as the name of a cmdlet function scrip
  • 检测可移动介质的弹出/插入

    我正在开发一个项目 需要能够检测何时插入或移除 CD 或 USB 驱动器 我发现一些源代码本应执行此操作 但是 当我插入或弹出 CD 时 似乎没有任何反应 有人可以验证来源是否正确 并指出我在这里可能做错了什么吗 public class
  • 有人可以解释一下这个 C++ typedef 吗?

    我已经有一段时间没有使用 C 了 刚刚开始使用它 虽然大部分内容都有道理 但有些地方我发现有点混淆 例如 有人可以解释一下这一行的作用吗 typedef bool OptionManager OptionHandler const ABSt
  • Android 加速度计精度(惯性导航)

    我正在考虑为 Android 手机实现惯性导航系统 但我意识到考虑到加速度计的精度和读数的持续波动 这很难 首先 我将手机放在平坦的表面上 并在 X 和 Y 方向上采样了 1000 个加速度计读数 与桌子平行 因此这些方向上没有重力作用 然
  • pandas json_normalize 具有非常嵌套的 json

    我一直在努力normalize一个非常嵌套的 json 文件 我稍后将进行分析 我正在努力解决的是如何进一步深入正常化 我经历了pandas io json json normalize文档 因为它完全按照我想要的方式执行 我已经能够将其中
  • 按时间间隔聚合一个数据帧来自另一个数据帧

    我正在尝试聚合两个数据帧 df1 and df2 第一个包含 3 个变量 ID Date1 and Date2 df1 ID Date1 Date2 1 2016 03 01 2016 04 01 1 2016 04 01 2016 05
  • QList什么时候会发生深拷贝?

    在我正在上的一堂课上 我正在同时处理几个问题QLists 我听说 Qt 尽可能不进行列表的深层复制 据我了解 这意味着执行此操作时不会发生深层复制 QList
  • 使用 angularjs 导出到 xls

    我正在开发 Angular JS 应用程序 但我陷入了必须使用 Angular JS 将数据导出到 Xls 的情况 我在互联网上搜索了很多导出功能或任何 Angular js 库 所以我可以做到这一点 或者至少我可以了解如何导出 我没有任何
  • 使用 .gif 的动画启动画面

    我想使用动画gif对于启动画面 所以我改变了src在 config xml 中放入我的 gif 中 如下所示
  • 如何在Cocoa中绘制锥形线+椭圆形阴影

    背景 下图是 OS X Lion 中的 Mail app 当源列表变得太长时 源列表底部的按钮上方会出现一条漂亮的阴影线 当您滚动时 源列表将移动到该阴影线下方 当您展开窗口以使源列表中的所有内容都适合而无需滚动时 阴影线就会消失 问题 我