SF Symbol 与scaleAspectFill 不能很好地配合使用

2023-12-03

我注意到 SF 符号并不能很好地与scaleAspectFill.

例如,给定一个圆形方面,用细边框填充 UIImageView,将其图像设置为UIImage(systemName: "person.crop.circle.fill")看起来像下面这样。请注意,图像并没有一直延伸到边缘。

enter image description here

将图像设置为UIImage(systemName: "person.fill")看起来像这样。不知怎的,它搞乱了自动布局高度约束(即使 contentMode 设置为也是如此)center).

enter image description here

我的解决方法是将 SF 符号导出为 png 并将它们加载到 Xcode 中,但这当然并不理想。我是否错误地使用了 SF 符号?


当我们创建一个UIImage使用 SF 符号,它会获得矢量支持,并且图像的行为更像是字体字符而不是图像。

如果我们跳过的话会更容易理解cornerRadius目前。

例如,如果我将标签的文本设置为O并给它一个黄色背景,它看起来像这样:

enter image description here

字符未到达边界框的边缘。

所以,当我们使用:let thisImage = UIImage(systemName: "person.crop.circle.fill")并设置图像视图的图像,我们得到:

enter image description here

正如我们所看到的,所有 4 个边都有“填充”。

要“删除”填充,我们可以将CGImage支持一个UIImage...但我们需要记住一些事情。

因此,有 6 个示例 - 每个示例都是此“基本”控制器的子类:

class MyBaseVC: UIViewController {

    let imgViewA = UIImageView()
    let imgViewB = UIImageView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        [imgViewA, imgViewB].forEach { v in
            // use AspectFill
            v.contentMode = .scaleAspectFill
            // background color so we can see the framing
            v.backgroundColor = .systemYellow
            v.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(v)
        }
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            
            imgViewA.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
            imgViewA.centerXAnchor.constraint(equalTo: g.centerXAnchor),
            imgViewA.widthAnchor.constraint(equalToConstant: 160.0),
            imgViewA.heightAnchor.constraint(equalTo: imgViewA.widthAnchor),
            
            imgViewB.topAnchor.constraint(equalTo: imgViewA.bottomAnchor, constant: 20.0),
            imgViewB.centerXAnchor.constraint(equalTo: g.centerXAnchor),
            imgViewB.widthAnchor.constraint(equalToConstant: 160.0),
            imgViewB.heightAnchor.constraint(equalTo: imgViewB.widthAnchor),
            
        ])
        
    }
    
}

第一个示例仅显示带有空黄色背景图像视图的布局:

class Example1VC: MyBaseVC {
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

它看起来像这样:

enter image description here

第二个示例从“person.crop.circle.fill”创建图像并设置第一个图像视图:

class Example2VC: MyBaseVC {
    override func viewDidLoad() {
        super.viewDidLoad()

        let nm = "person.crop.circle.fill"
        
        // create UIImage from SF Symbol at "default" size
        guard let imgA = UIImage(systemName: nm)?.withTintColor(.lightGray, renderingMode: .alwaysOriginal) else {
            fatalError("Could not load SF Symbol: \(nm)!")
        }
        print("imgA size:", imgA.size)
        imgViewA.image = imgA
    }
}

Output:

enter image description here

到目前为止,没有什么是你没见过的。

该代码还将生成的图像大小输出到调试控制台......在这种情况下,imgA size: (20.0, 19.0)

因此,我们将该图像保存为 20x19 png 并将其加载到第二个图像视图中:

class Example3VC: MyBaseVC {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let nm = "person.crop.circle.fill"
        
        // create UIImage from SF Symbol at "default" size
        guard let imgA = UIImage(systemName: nm)?.withTintColor(.lightGray, renderingMode: .alwaysOriginal) else {
            fatalError("Could not load SF Symbol: \(nm)!")
        }

        guard let imgB = UIImage(named: "imgA20x19") else {
            fatalError("Could not load imgA20x19")
        }
        
        print("imgA:", imgA.size, "imgB:", imgB.size)
        
        imgViewA.image = imgA
        imgViewB.image = imgB
    }
}

正如预期的那样,因为它现在是位图而不是矢量数据,所以它变得难以接受的模糊......而且,我们仍然没有到达边缘:

enter image description here

因此,对于第四个示例,我们将使用.cgImage支持生成的 SF 符号图像中的数据,以有效地“即时”创建位图版本:

class Example4VC: MyBaseVC {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let nm = "person.crop.circle.fill"

        // create UIImage from SF Symbol at "default" size
        guard let imgA = UIImage(systemName: nm)?.withTintColor(.lightGray, renderingMode: .alwaysOriginal) else {
            fatalError("Could not load SF Symbol: \(nm)!")
        }
        
        // get a cgRef from imgA
        guard let cgRef = imgA.cgImage else {
            fatalError("Could not get cgImage!")
        }
        // create imgB from the cgRef
        let imgB = UIImage(cgImage: cgRef, scale: imgA.scale, orientation: imgA.imageOrientation)
            .withTintColor(.lightGray, renderingMode: .alwaysOriginal)
        
        print("imgA:", imgA.size, "imgB:", imgB.size)
        
        imgViewA.image = imgA
        imgViewB.image = imgB
    }
}

enter image description here

越来越近......图像现在到达边缘,但仍然模糊。

为了解决这个问题,我们在生成初始 SF 符号图像时将使用“点”配置:

class Example5VC: MyBaseVC {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let nm = "person.crop.circle.fill"
        
        // create UIImage from SF Symbol at "160-pts" size
        let cfg = UIImage.SymbolConfiguration(pointSize: 160.0)
        guard let imgA = UIImage(systemName: nm, withConfiguration: cfg)?.withTintColor(.lightGray, renderingMode: .alwaysOriginal) else {
            fatalError("Could not load SF Symbol: \(nm)!")
        }
        
        // get a cgRef from imgA
        guard let cgRef = imgA.cgImage else {
            fatalError("Could not get cgImage!")
        }
        // create imgB from the cgRef
        let imgB = UIImage(cgImage: cgRef, scale: imgA.scale, orientation: imgA.imageOrientation)
            .withTintColor(.lightGray, renderingMode: .alwaysOriginal)
        
        print("imgA:", imgA.size, "imgB:", imgB.size)
        
        imgViewA.image = imgA
        imgViewB.image = imgB
    }
}

调试大小输出显示imgB: (159.5, 159.5)(所以,非常接近图像视图的 160x160 尺寸),它看起来像这样:

enter image description here

我们现在有了清晰的渲染,没有“填充”......我们可以添加角半径和边框:

class Example6VC: MyBaseVC {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let nm = "person.crop.circle.fill"
        
        // create UIImage from SF Symbol at "160-pts" size
        let cfg = UIImage.SymbolConfiguration(pointSize: 160.0)
        guard let imgA = UIImage(systemName: nm, withConfiguration: cfg)?.withTintColor(.lightGray, renderingMode: .alwaysOriginal) else {
            fatalError("Could not load SF Symbol: \(nm)!")
        }
        
        // get a cgRef from imgA
        guard let cgRef = imgA.cgImage else {
            fatalError("Could not get cgImage!")
        }
        // create imgB from the cgRef
        let imgB = UIImage(cgImage: cgRef, scale: imgA.scale, orientation: imgA.imageOrientation)
            .withTintColor(.lightGray, renderingMode: .alwaysOriginal)
        
        print("imgA:", imgA.size, "imgB:", imgB.size)
        
        imgViewA.image = imgA
        imgViewB.image = imgB
        
        [imgViewA, imgViewB].forEach { v in
            v.layer.cornerRadius = 80
            v.layer.borderColor = UIColor.red.cgColor
            v.layer.borderWidth = 1
        }
    }
    
}

实施例6 结果:

enter image description here

正如您在帖子中提到的,您会注意到顶部图像视图并不完全是圆形的——也就是说,它以某种方式失去了 1:1 的比例。

这是使用 SF 符号作为图像的一个奇怪的副作用,我早已放弃尝试理解它。无论约束如何,不同的符号都会导致图像视图改变大小。

您可以在这里看到一些讨论:https://stackoverflow.com/a/66293917/6257435

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

SF Symbol 与scaleAspectFill 不能很好地配合使用 的相关文章

  • iPhone:UIImageView 淡入 - 如何?

    我有一个UIImageView我想淡入 有没有办法在底层启用它UIViewController 我翻译了最简单的答案 尽管它们都有效 C NET为了MonoTouch users public override void ViewDidAp
  • 单击后如何更改回收器视图中的特定图像

    我想更改 recyclerview 中单击项目的透视图像 知道发生了什么 如果我单击项目 2 图像会在列表中的随机项目位置发生变化 public class MyRecyclerViewAdapter extends RecyclerVie
  • UIViewContentModeScaleAspectFit iphone sdk 提供质量差的图像

    希望快一点吗 我正在创建一个自定义 uitableviewcell 并添加了一个图像视图 我有一些尺寸约为 200x200 的 PNG 图像 我想创建一个缩略图以放入表格视图中 但是当我调整图像大小时 会导致图像质量较差 I use UIV
  • UIImageView触摸事件

    我想在触摸位于 uiview view1 中的名为 as image1 Imageview 的 uiimageview 时调用按钮单击事件 这是我的代码 IBAction buttonClicked id sender myTimer NS
  • 使用 UIGestureRecognizer 旋转瓶子

    我现在使用此代码在按钮点击上旋转瓶子 IBAction func spinButton sender AnyObject let rotateView CABasicAnimation let randonAngle arc4random
  • SWIFT 在 Main.storyboard 中定义的 UIImageview 中旋转图像

    我是 SWIFT 新手 正在练习学习 但在某些方面遇到了一些困难 我在 Main storyboard 定义的 UIImageview 中有一个图像 我需要旋转它 我有一个 IBOutlet 定义为 IBOutlet weak var im
  • UIImage 方面适合并对齐到顶部

    看起来像aspect fit默认情况下将图像与框架底部对齐 有没有办法override对齐同时保持aspect fit intact 编辑 这个问题早于自动布局 事实上 在提出这个问题的同一周 汽车布局就在 WWDC 2012 上公布了 简
  • 动画 gif 在使用 MKOverlayRenderer 的 MKMapView 叠加中不起作用

    我正在尝试在叠加层中显示动画 gifMKMapView 覆盖层是使用以下命令创建的MKOverlayRenderer 为了在 iOS 7 中制作 gif 动画 我使用UIImage animatedGIF已发布类别here https gi
  • 添加 UIImage 会忽略 UIImageView 框架并调整其大小

    我目前正在尝试将图像添加到一个视图的导航项中 在视图的viewDidLoad 使用以下代码调用函数 类似于这个帖子 https stackoverflow com questions 24803178 swift navigation ba
  • iOS显示tableview标题图像(视差效果)

    我正在尝试设置一个大图像 随着表格视图进一步拉低 可以显示更多信息 我知道我没有任何意义 它更容易显示我从 netbot 记录的一个例子 http vine co v bdKrALdOheD 请让我知道正确的术语是什么 我将更新标题 Upd
  • UIImageView 上的用户交互

    我有许多 UIImageView 上面有按钮 我想在这些按钮后面的 UIImageView 上启用用户交互 我在 IB 中看到了该选项 但想知道如何在实际触摸 UIImageView 时触发一些代码 如何做到这一点以及如何在代码而不是 IB
  • UIButton 与 UITableViewCell 中的 UIImages - 重叠等

    我的 UITableViewCell 有问题 我正在开发一个应用程序 其中提要中的某些帖子可能包含图像 并且单击的按钮还需要包含一个 标签 编号 具体取决于它位于表格的哪一行 因为我下载了一组图像 问题出在我滚动 正如您已经猜到的 表格时
  • 如果我使用圆形图像,图像不会显示在 imageView 中

    我有一个表视图 我需要在节标题中显示author img 在 ViewForSectionHeader 方法中 我想让图像成为圆形 但如果我这样做 无论在模拟器中还是在真实设备中 图像都根本不会显示 如果我删除代码 uiimageview
  • 如何在 iOS 4.0+ 中获取 UIImage 的大小(以字节为单位)?

    我正在尝试从照片库或相机中选取图像 委托方法 void imagePickerController UIImagePickerController picker didFinishPickingImage UIImage image edi
  • 如何获得停止/恢复 CABasicAnimation 工作的解决方案?

    我正在使用 CABasicAnimation 旋转 UIImageView 但无法恢复暂停的动画 动画在 viewDidLoad 方法中开始 UIImageView img UIImageView alloc initWithImage U
  • 在 Storyboard 中实现视频视图

    我想构建简单的视频应用程序 可以查看用户添加的 YouTube 链接中的视频 我没有找到 VideoView 我的意思是如果图像视图用于图像 那么 UIView 用于视频 原库中没有执行视频观看功能的对象 但你可以导入MediaPlayer
  • 如何以编程方式创建 UIImage 视图 - Swift

    我正在尝试以编程方式创建 UIImage 视图 我有一个新视图 我尝试这样做 let imageName yourImage png yourview backgroundColor UIColor colorWithPatternImag
  • 如果通过 Interface Builder 添加,则无法修改 UIImageView 的框架

    我遇到了这个非常奇怪的问题 我无法修改 UIImageView 的框架 我将其与这个非常简单的示例隔离开来 从默认的单视图应用程序 xcode 模板开始 我在 Interface Builder 中添加一个 UIImageView 将其链接
  • 将 UIImage 放入 UIButton 的简单方法

    我的 iPhone 应用程序中有一个 UIButton 我将其大小设置为 100x100 我有一个 400x200 的图像 我希望在按钮中显示它 按钮仍然需要保持在 100x100 并且我希望图像缩小以适应 但是 保持正确的纵横比 我想这就
  • 如何将 UIImageView 裁剪为自定义形状

    用户是否可以在该位周围画一条虚线 圆圈 UIImageView他们希望裁剪到 然后为UIImageView调整大小到这些点 这有点像 Photoshop 中的套索 选取框效果 更新 从 iOS 8 x 开始 UIImageView 提供了m

随机推荐

  • 在初始化之前从根状态调用 connectOutlets?

    http jsfiddle net pauldechov 89S5p 在 root 的 connectOutlets 中 App似乎仍然不 initialize d connectOutlets 不适合与根状态一起使用吗 为什么 如果我每次
  • 在 Swift 3 通知中心观察者中使用选择器

    NotificationCenter default addObserver self selector Selector uploaded name NSNotification Name rawValue uploaded object
  • 如何使用组合框过滤Datagridview而不更改数据源

    我正在使用 Windows 窗体编写一个程序 并且我已经构建了一些代码 如下所示 在文本框中写入站点 URL 然后单击 开始 按钮 匹配的数据将显示在 DataGridViews 中 我有 6 个 DataGridView 在第一个 Dat
  • 错误添加SceneBuilder快捷链接后如何将Scene Builder添加到Intellij

    所以我安装了Intellij第一次 我错误地链接了场景构建器快捷方式链接到FXML文件并不断收到此错误 IntelliJ failed to start scene builder 经过大量搜索后 我无法找到如何重置SceneBuilder
  • ggplot2 轴文本的奇怪理由

    我遇到了一个奇怪的轴文本对齐问题 如下图所示 您可能需要放大图像才能看到问题 正如您所看到的 x 轴文本绘制在刻度线的下方 y 轴文本绘制在刻度线的左侧 并且刻度线本身遍布各处 可能导致此行为的原因是 也许更重要的是 可以采取什么措施来避免
  • 浏览器会短暂显示没有样式的页面(视觉故障)

    我观察到 Internet Explorer 7 或 8 没关系 很少会显示我们的网页 www epsitec ch 短时间内不应用CSS 布局看起来完全被破坏了 所有内容都从上到下按顺序显示 当页面加载完成后 所有内容终于正确显示 我们的
  • Python 分割字符串并打乱中间的内容

    我在使用 python 程序时遇到问题 我需要该程序混淆单词的中间 同时保持外部两个字母完好无损 我相信我已经成功地将单词分成三个不同的部分 我只是不能弄清楚我应该如何打乱单词的中间部分 word input Enter a word fi
  • 使用 boost 函数进行 SolrNet 查询

    我正在尝试使用这个库 看起来非常好 但我很难理解如何向我的查询添加额外的参数 例如升压函数等 如何做到这一点 您可以使用 QueryOptions 的 ExtraParams 属性将任何参数添加到 Solr 查询字符串 例子 ISolrOp
  • 单击表单中的按钮会导致页面刷新

    我有一个 Angular 表单 其中有两个按钮标签 一键提交表单ng click 另一个按钮纯粹用于导航ng click 然而 当单击第二个按钮时 AngularJS 会导致页面刷新 从而触发 404 我在函数中放置了一个断点 它正在触发我
  • 如何在 stringi 包中使用反向引用?

    在 R 中我可以使用 1引用捕获组 但是 当使用 stringi 包时 这不会按预期工作 library stringi fileName lt hello you lst fileName lt stri replace first re
  • 从数据库中检索一百万条记录

    有一个数据库 它的表中大约包含 200 万条记录 我从我的java代码中运行了查询 就像这样 select from table 它将从结果集中的数据库中获取完整的数据 或不 如果是 那么它将如何工作 我想了解此检索的工作原理 请告诉我 我
  • 防止 const 成员函数更改成员数组

    显然 const 成员函数仍然允许更改类成员指向的数据 这是我的意思的一个例子 class MyClass public MyClass int getSomething const private int data data new in
  • 如何在带有子图的绘图中设置辅助x轴及其范围?

    有谁知道如何在绘图中设置辅助 x 轴及其范围 我试图在这里显示垂直直方图 但它目前仍然太小 垂直直方图 import pandas as pd import numpy as np import plotly graph objects a
  • 如何修复 PHONE GAP 中 Android 设备的粘性页脚?

    我在 Phone Gap 工作 我修复了页脚 这适用于少数设备 但不适用于少数设备 页脚的 HTML 代码 div style background image url img bottom bar png class footer div
  • 什么时候会在 C# 中使用委托? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 您在 C 中如何使用委托
  • 在 XSLT 中创建一个简单的模式弹出窗口

    我正在构建一个样式表 表中有一些成员 我想要的是 当我单击每个会员时 会打开一个弹出模式窗口 其中包含 XML 文件中的该会员数据 我可以使用会员 ID 作为参考 我尝试使用 fancybox http fancybox net 但问题是
  • 每组加权geom_密度的密度总和为1

    使用加权数据时 如何对密度图进行分组并使每组的密度总和为 1 The ggplot2帮助geom density 建议使用加权数据的技巧 除以权重之和 但是当分组时 这意味着各组的组合密度总计为 1 我希望每个组的密度总计为一个 我发现了两
  • 如何将列表嵌套到Redis中的结构中以减少顶层?

    我想在redis中维护一些元数据 meta key build key meta data user 12345 tag D12321341234123 res redis sip hmset meta key meta data 它按预期
  • 为什么我的 Cucumber 测试在使用 Selenium 运行时失败?

    我正在使用 Cucumber Capybara 组合测试 Rails 3 应用程序 我还尝试使用 Selenium 来测试一些 JavaScript 特定场景 但遇到了我不明白的奇怪困难 我对 Cucumber Capybara 的经验非常
  • SF Symbol 与scaleAspectFill 不能很好地配合使用

    我注意到 SF 符号并不能很好地与scaleAspectFill 例如 给定一个圆形方面 用细边框填充 UIImageView 将其图像设置为UIImage systemName person crop circle fill 看起来像下面