一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Swift - Swift設置UILabel內邊距的實例代碼

Swift設置UILabel內邊距的實例代碼

2021-12-24 14:14我為雙魚狂 Swift

有時候,我們需要一個顯示文字,又想這些文字與邊界之間有自定義的邊距,所以下面這篇文章主要給大家介紹了關于Swift設置UILabel內邊距的相關資料,需要的朋友可以參考下

摘要

拿來即用短時間效率雖然挺高的,但是拿來的東西沒有消化一次,就無法得心應手的使用它。

這次的探索思路就是,查詢官方文檔,設置不同的值測試單個方法中參數的變化,之后測試兩個方法的執行順序,處理的思路,最后思考總結。

在總結方法的處理邏輯時,使用偽代碼的方式梳理方法的執行思路。避免解釋文本太多,增加理解的成本。

最近在學習小程序開發,接觸到 flex 方式布局,很喜歡這種快速和方便的方式。所以當遇到一個頁面上居中顯示文本的需求的時候,就想直接在 UIlabel 上處理,然后在UIlabel上設置它的內邊距(類似 flex 布局)。而不是先放一個 View。然后在這個view 上放置一個 UILabel 控件,通過設置 UILabel 控件距離父 View 的距離實現。

先看代碼實現,下面的代碼,是搜索之后的解決方式,如果只是拿去使用,直接復制到項目中即可。需要在設置text前設置textInsets

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 區域,返回給系統。

經過多次測試驗證發現執行邏輯(偽代碼):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 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。它們之間的關系是(偽代碼):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 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方法就可以不用重寫。

?
1
2
3
4
5
6
7
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 也是不用處理的,什么時候會用到它?我目前還沒有遇到。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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內邊距內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/shsuper/p/15212298.html

延伸 · 閱讀

精彩推薦
  • SwiftSwift實現多個TableView側滑與切換效果

    Swift實現多個TableView側滑與切換效果

    這篇文章主要為大家詳細介紹了Swift實現多個TableView側滑與切換效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    乞力馬扎羅的雪雪5822021-01-08
  • SwiftSwift中轉義閉包示例詳解

    Swift中轉義閉包示例詳解

    在Swift 中的閉包類似于結構塊,并可以在任何地方調用,下面這篇文章主要給大家介紹了關于Swift中轉義閉包的相關資料,需要的朋友可以參考下...

    小小小_小朋友11412021-12-26
  • SwiftSwift的74個常用內置函數介紹

    Swift的74個常用內置函數介紹

    這篇文章主要介紹了Swift的74個常用內置函數介紹,這篇文章列舉出了所有的Swift庫函數,內置函數是指無需引入任何模塊即可以直接使用的函數,需要的朋友可...

    Swift教程網5802020-12-19
  • SwiftSwift使用CollectionView實現廣告欄滑動效果

    Swift使用CollectionView實現廣告欄滑動效果

    這篇文章主要為大家詳細介紹了Swift使用CollectionView實現廣告欄滑動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Stevin的技術博客12372021-01-13
  • Swiftmac git xcrun error active developer path 錯誤

    mac git xcrun error active developer path 錯誤

    本文主要是講訴了如何解決在mac下使用git;xcode4.6的環境時,出現了錯誤(mac git xcrun error active developer path)的解決辦法,希望對大家有所幫助...

    Swift教程網2232020-12-16
  • Swiftswift where與匹配模式的實例詳解

    swift where與匹配模式的實例詳解

    這篇文章主要介紹了swift where與匹配模式的實例詳解的相關資料,這里附有簡單的示例代碼,講的比較清楚,需要的朋友可以參考下...

    追到夢的魔術師14382021-01-06
  • SwiftSwift能代替Objective-C嗎?

    Swift能代替Objective-C嗎?

    這是我在網上上看到的答案,復制粘貼過來和大家分享一下,因為我和很多人一樣很關心Swift的出現對Mac開發的影響和對Objective-C的影響。...

    Swift教程網4412020-12-16
  • SwiftSwift教程之基礎數據類型詳解

    Swift教程之基礎數據類型詳解

    這篇文章主要介紹了Swift教程之基礎數據類型詳解,本文詳細講解了Swift中的基本數據類型和基本語法,例如常量和變量、注釋、分號、整數、數值類型轉換等...

    Swift教程網5162020-12-18
主站蜘蛛池模板: 99久9在线视频 | 亚洲日韩欧美一区二区在线 | 亚洲精品永久免费 | 80日本xxxxxxxxx| 亚洲日本va午夜中文字幕 | 好男人影视社区www在线观看 | 成人私人影院在线版 | 国产精品青青青高清在线 | 国产精品免费aⅴ片在线观看 | 2021国产麻豆剧传媒新片 | 国产最新进精品视频 | 热辣小秘书办公室 | 欧美色影视 | 每天都要睡男人(nph) | 91桃色污 | 精品午夜寂寞黄网站在线 | 青青草原手机在线视频 | 美女扒开胸罩露出奶了无遮挡免费 | 四虎影院久久久 | 国产精品视频第一区二区 | 美女被视频网站看免费入口 | 四虎永久免费地址 | 性鸥美| 性欧美金发洋妞xxxxbbbb | 九九九九在线精品免费视频 | 免费真实播放国产乱子伦 | 久久青青草原 | 色哟呦 | 99热这里只有精品在线观看 | 日本理论片中文在线观看2828 | 2020最新韩国理论三级0k | 国产精品视频一区二区三区 | 欧美最猛性xxxxx动态图 | 国产久视频 | www青青草原| 99在线观看视频免费 | 国产全部理论片线观看 | 日本黄大片影院一区二区 | 免费观看在线观看 | 香港三级浴室女警官 | 国产成+人+综合+亚洲不卡 |