返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Swift设置UILabel内边距的实例代码
  • 901
分享到

Swift设置UILabel内边距的实例代码

2024-04-02 19:04:59 901人浏览 安东尼
摘要

目录摘要textRect 的作用drawText 的作用优化扩展新发现总结摘要 拿来即用短时间效率虽然挺高的,但是拿来的东西没有消化一次,就无法得心应手的使用它。 这次的探索思路就是

摘要

拿来即用短时间效率虽然挺高的,但是拿来的东西没有消化一次,就无法得心应手的使用它。

这次的探索思路就是,查询官方文档,设置不同的值测试单个方法中参数的变化,之后测试两个方法的执行顺序,处理的思路,最后思考总结。

在总结方法的处理逻辑时,使用伪代码的方式梳理方法的执行思路。避免解释文本太多,增加理解的成本。

最近在学习小程序开发,接触到 flex 方式布局,很喜欢这种快速和方便的方式。所以当遇到一个页面上居中显示文本的需求的时候,就想直接在 UIlabel 上处理,然后在UIlabel上设置它的内边距(类似 flex 布局)。而不是先放一个 View。然后在这个view 上放置一个 UILabel 控件,通过设置 UILabel 控件距离父 View 的距离实现。

先看代码实现,下面的代码,是搜索之后的解决方式,如果只是拿去使用,直接复制到项目中即可。需要在设置text前设置textInsets


class SHLabel: UILabel {
​
   var textInsets: UIEdgeInsets = .zero
​
   override func drawText(in rect: CGRect) {
       super.drawText(in: rect.inset(by: textInsets))
   }
   
   override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
       
       let insets = textInsets
       var rect = super.textRect(forBounds: bounds.inset(by: insets), limitedToNumberOfLines: numberOfLines)
       
       rect.origin.x -= insets.left
       rect.origin.y -= insets.top
       rect.size.width += (insets.left + insets.right)
       rect.size.height += (insets.top + insets.bottom)
       return rect
   }
}

为什么这种方式可以实现内边距?

接下来是梳理一下,为什么这样实现。首先查看开发者文档,看代码块中这两个方法是做什么的

函数 drawText(in rect: CGRect) textRect(forBounds bounds:, limitedToNumberOfLines numberOfLines) -> CGRect
标题 在rect的区域中绘制文本或者阴影 返回文本的绘制的 rect 区域
详细 如果需要修改 label 中的绘图行为,需要重写这个方法。这个方法已经配置用于绘图的默认环境和文本颜色,在重写的方法中,可以自定义绘制方法,然后调用super或者自己进行绘图。 在系统执行其他文本计算之前重写这个方法(这个太难理解),如果调用 sizeToFit()和sizeThatFits(_:)会触发这个方法
链接 https://developer.apple.com/documentation/uikit/uilabel/1620527-drawtext Https://developer.apple.com/documentation/uikit/uilabel/1620545-textrect

之后验证这两个方法的执行顺序,和各自的作用时,发现当 UILabel 的 text 赋值时,会首先调用textRect方法,之后drawText方法被调用。

textRect在当文本rect的实际宽度大于设置UILabel的实际宽度时,会再次被调用,当然drawText也是在textRect两次调用之后被调用。

textRect 的作用

看到这里,似乎可以理解开发者文档中提到的在系统执行其他文本计算之前重写这个方法了。这个方法的作用就是先获取 UILabel 的 bounds 和 text 的行数,通过调用 super 方法计算出 text 的 rect 区域,返回给系统。

经过多次测试验证发现执行逻辑(伪代码):


  // frame 是设置 UIlabel 时的 frame
  if numberOfLines == 1 {
      textRect 被调用
      return retc 的 width = text 的 widht
  } else {
      if text 文本的 width < frame 的 width {
          text Rect 被调用
          return retc 的 width = text 的 widht
      } else {
          text Rect 被调用两次后
   
          以 frame 的 wdith 为限制,计算出 text 的 height
          return rect 的 size = (frame 的 width,text 的 height)
      }
  }

drawText 的作用

看drawText中的rect参数,就是textRect方法返回的rect。text文本的实际绘制区域就通过重写drawText方法,并在其中调用它的super方法实现。

经过多次验证,这里的rect并不完全是textRect方法中返回的rect。它们之间的关系是(伪代码):


  // frame 是设置 UILabel 的 frame
  // rect 是 `textRect` 返回的
  dx = frame.x
  dy = frame.y
  if frame.width 确定不变 {
      dwidth = frame.width
  } else {
      dwidth = rect.width
  }
  if frame.height 确定不变 {
      dheight = frame.height
  } else {
      dheight = rect.width
  }
   
  return drawText 中的 rect(dx,dy,dwidth,dheight)

再问:为什么用这种方式实现内边距?

耐心看完这两个方法之后,对题目中的问题,多少有些思路了。那么就理顺一下这个思路。

首先确定一个共识,就是设置UILabel的内边距,是确定UILabel的frame区域里面,调整text的显示区域。有了这个共识,接下来就好办了。

  • 第一步就要用textRect方法获取到text的显示区域,默认text的显示区域和UILabel的bounds区域是一样的
  • 那就需要和咱们自己设置的内边距值计算获取到新的text文本的rect区域。
  • 最后就用drawText方法重新绘制一下text的rect区域显示。

那么为什么要用这种方式实现呢?因为目前只有这两个方法和 text 文本直接有关系。

优化

理论搞了这么多,到了输出一些干货的时候了。

如果,UILabel的frame已经确定了,重要的是width和height确定了。那么textRect方法就可以不用重写。


class SHLabel: UILabel {
​
   var textInsets: UIEdgeInsets = .zero
   override func drawText(in rect: CGRect) {
       super.drawText(in: rect.inset(by: textInsets))
   }
}

这里就可以看出,当UILabel的height不确定时,重写textRect来帮忙确定UILabel的高度。经过验证下来,这个方法中的 x 和 y 也是不用处理的,什么时候会用到它?我目前还没有遇到。


class SHLabel: UILabel {
​
   var textInsets: UIEdgeInsets = .zero
​
   override func drawText(in rect: CGRect) {
       super.drawText(in: rect.inset(by: textInsets))
   }
   
   override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
       let insets = textInsets
       var rect = super.textRect(forBounds: bounds.inset(by: insets), limitedToNumberOfLines: numberOfLines)
​
//       rect.origin.x -= insets.left
//       rect.origin.y -= insets.top
       rect.size.width += (insets.left + insets.right)
       rect.size.height += (insets.top + insets.bottom)
       return rect
   }
}

扩展

文章到这里,就结束了。如果你是一个细节控,感觉textRect在需要还是不需要的时候都被调用。drawText方法,不管设置还是不设置内边距也总是被调用,会不会影响性能啊?

这里提供两个方法解决:

  1. 可操作性的,就是尽量考虑需求,在不得不用的时候再使用
  2. 心理安慰性质的,那就是放下。细想一下,这两个方法都是重写的方法,重写的本质是什么?那就是不执行自己的方法,执行重写的方法。换句话说,就算系统不走重写的方法,也要走自己的方法。而这些代码对性能的影响,不值一提。

新发现

突然之间,有没有发现,咱们似乎也明白了,为什么UILabel不用固定它的height,它就可以自己确定高度,完全展示 text文本?你想.你细想...

总结

到此这篇关于Swift设置UILabel内边距的文章就介绍到这了,更多相关Swift设置UILabel内边距内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Swift设置UILabel内边距的实例代码

本文链接: https://lsjlt.com/news/154386.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Swift设置UILabel内边距的实例代码
    目录摘要textRect 的作用drawText 的作用优化扩展新发现总结摘要 拿来即用短时间效率虽然挺高的,但是拿来的东西没有消化一次,就无法得心应手的使用它。 这次的探索思路就是...
    99+
    2024-04-02
  • css设置内边距的方法
    今天小编给大家分享的是css设置内边距的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。在css中,可以使用padding属性设置内边距,只需要给元素设置“padding:数值+单...
    99+
    2023-06-14
  • CSS段落的内边距怎么设置
    本文小编为大家详细介绍“CSS段落的内边距怎么设置”,内容详细,步骤清晰,细节处理妥当,希望这篇“CSS段落的内边距怎么设置”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。 下面...
    99+
    2024-04-02
  • html设置div边距的方法示例
    这篇文章主要介绍了html设置div边距的方法示例,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。方法:1、使用margin相关属性给div设置外边距(div盒子外围四周的距离...
    99+
    2023-06-06
  • html内容左右边距的设置方法
    这篇文章主要介绍了html内容左右边距的设置方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。html有什么特点1、简易性:超级文本标记语言版本升级采用超集方式,从而更加灵活...
    99+
    2023-06-14
  • Swift 中的 async/await ——代码实例详解
    前言 async-await 是在 WWDC 2021 期间的 Swift 5.5 中的结构化并发变化的一部分。Swift 中的并发性意味着允许多段代码同时运行。这是一个非常简化的描述,但它应该让你知道 Swift 中的并发性对你的应用程序...
    99+
    2023-08-17
    swift ios 开发语言
  • Python实现边缘提取的示例代码
    目录复习一、边缘提取1、什么是边缘2、什么是边缘提取二、Sobel算子三、Canny边缘检测算法1、算法步骤2、高斯平滑3、非极大值抑制4、双阈值检测四、相关代码复习 (1)梯度: ...
    99+
    2024-04-02
  • 通过Java实现设置Word文档页边距的方法详解
    目录程序环境设置 Word 文档页边距完整代码效果图页边距是指页面的边线到文字的距离。通常可在页边距内部的可打印区域中插入文字和图形,也可以将某些项目放置在页边距区域中(如页眉、页脚...
    99+
    2023-02-23
    Java设置Word页边距 Java设置页边距 Java Word
  • php头编码实例设置方法及代码
    在PHP中可以通过在PHP文件头部添加“header("Content-type: text/html; charset=utf-8");”语句来设置编码。 设置utf编码的代码如下...
    99+
    2024-04-02
  • Qt实现边加载数据边显示页面的示例代码
    目录1.定义显示定时器1:定义定时器2:定时器调用3:定时器加载数据2.线程加载数据3.实时呈现加载进度做过C++开发的人们都知道,无论是MFC框架还是QT框架,实现加载数据的等待效...
    99+
    2024-04-02
  • padding盒子内部文字跟盒子之间的距离代码示例
    这篇文章主要介绍“padding盒子内部文字跟盒子之间的距离代码示例”,在日常操作中,相信很多人在padding盒子内部文字跟盒子之间的距离代码示例问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方...
    99+
    2024-04-02
  • Android ListView 滚动条的设置详解及实例代码
    Android ListView 滚动条的设置详解 1.滚动条的属性 android:scrollbarAlwaysDrawHorizontalTrack 设置是否始终显示水...
    99+
    2022-06-06
    listview 滚动条 Android
  • centos7 设置grub密码及单用户登录实例代码
    centos7与centos6在设置grub密码的操作步骤上有很大的差别,特此记录供以后查用 grub加密的目的: 防止不法分子利用单用户模式修改root密码 给grub加密可以采用明文或者加密的密文两种,建议使用加密的...
    99+
    2022-06-04
    centos7 设置grub密码 centos grub centos7 单用户登录
  • Android中设置RadioButton在文字右边的方法实例
    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro...
    99+
    2022-06-06
    radiobutton 方法 Android
  • WPF实现文本描边+外发光效果的示例代码
    解决思路: (1)描边效果可以将文本字符串用GDI+生成Bitmap,然后转成BitmapImage,再用WPF的Image控件显示。 (2)外发光效果用WPF自带的Effect实现...
    99+
    2024-04-02
  • JavaScript内置日期、时间格式化时间实例代码
    一、基础知识(date对象的方法) 😜 getFullYear( ) 用于返回一个表示年份的4位数 🤣 getMonth( ) 返回表示月份的数字,...
    99+
    2024-04-02
  • Python实现绘制Matlab格式的地图边框的示例代码
    目录1、Python绘制色斑图2、Python绘制比例尺、指南针3、Python绘制Matlab格式的地图边框1、Python绘制色斑图 import matplotlib.pyp...
    99+
    2024-04-02
  • Java设置Excel数据验证的示例代码
    数据验证是Excel 2013版本中,数据功能组下面的一个功能,在Excel2013之前的版本,包含Excel2010 Excel2007称为数据有效性。通过在excel表格中设置数...
    99+
    2024-04-02
  • Eclipse代码格式化设置的示例分析
    这篇文章给大家分享的是有关Eclipse代码格式化设置的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。自用项目中统一Eclipse格式化Java、JavaScript、JSP、HTML代码设置1.Wind...
    99+
    2023-05-30
    eclipse
  • vue内嵌iframe跨域通信的实例代码
    目录vue内嵌iframe跨域通信1、Vue组件中如何引入iframe?2、vue如何获取iframe对象以及iframe内的window对象?3、vue如何向iframe内传送信息...
    99+
    2022-11-13
    vue内嵌iframe跨域通信 vue内嵌iframe vue内嵌 vue跨域
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作