11.%d Xcode — UITextView 的 textContainer 的 exclusionPaths
目錄
⦿ 仍然是貝茲曲線
⦿ TextView、Editable、Selectable
⦿ exclusionPaths
⦿ Debug
⦿ 文繞圖的步驟
仍然是貝茲曲線
這篇大概會是貝茲曲線的最後一篇。
在 TextView 中有個屬性叫做 textContainer
,我們先看看,如果你要客製化 TextView,在 programming init 裡會這樣寫:
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
}
frame 我們都知道是用來定義元件位置跟大小,但在 TextView 裡面還有一個 textContainer,它是用來判定 TextView 裡的 text 是否 render 的。
render 在電腦科學裡的意思是經過處理
,text 將過處理後就是顯示的文字,包括字型、字體大小、顯示範圍等等,這裡是文字處理的意思;若在 Adobe Premiere 中,render 就是影像及聲音的處理了。
而 textContainer 就是處理文字的容器,它決定你要處理的範圍等等。我們可以參照下面這篇:
接著採用之前這篇用貝茲曲線畫的的楓葉
來試試看。
繼續閱讀|回目錄
TextView、Editable、Selectable
先將 textView 加到 ViewController 裡,看看 textView 如下:
在 Attributed Inspector 中,Editable、Selectable 有勾選的話,表示使用者可以在 textView 上編輯,當然也可選取。
這兩項預設都是勾選,不過,若你的 textView 只是用來顯示資訊
的話,例如 IMDB 的 APP,可以看到一部電影的詳細內容,這個詳細內容若以 textView 呈現,我們就會取消 Editable。
如果!在顯示頁面需要加上外部連結
,一般會這麼做,第一個是取消 Ediable,第二個是勾選 Selectable 如下:
而如果容易辨識的情況下,這些文字 Data 會因為 Detectors
自動辨識出它是電話號碼、連結或是地址⋯⋯。
好了,接下來要回到 TextView 的 textContainer 的 exclusionPaths 了。
繼續閱讀|回目錄
exclusionPaths
在前面,我們已經順利在 TextView 裡加入 UIBezierPath 畫出的楓葉,我們看看什麼是 exclusionPaths,如下:
原來它是一個 path 的陣列,用來表示 text 不會出現的 path,想想在 Office 軟體中操作 Word 時,文繞圖
不就是這個意思嗎?而且,這裡的 path 指的就是 UIBezierPath,所以可以想見我們能夠精準控制 UIBezierPath 畫出的楓葉
,讓文字環繞著這個楓葉
。
那麼,先看看 exclusionPaths,程式碼的部份是這樣:
let myPath = createPath() // 楓葉路徑
myTextView.textContainer.exclusionPaths = [myPath] // text 避開路徑
makeUIView() // 楓葉
再來看看,原先的楓葉是這麼寫的:
func makeUIView() -> UIView {
let redView = UIView(frame: CGRect(x: 0, y: 0,
width: 300, height: 300))
let mapleView = UIView(frame: redView.frame)
mapleView.backgroundColor = UIColor.red let path = UIBezierPath()
path.move(to: CGPoint(x: 162.87, y: 14.05))
path.addLine(to: CGPoint(x: 150.53, y: 36.54))
path.addLine(to: CGPoint(x: 137.40, y: 29.70))
path.addLine(to: CGPoint(x: 143.47 , y: 67.85))
path.addLine(to: CGPoint(x: 126.06, y: 52.41))
path.addLine(to: CGPoint(x: 120, y: 60))
path.addLine(to: CGPoint(x: 100, y: 60))
path.addLine(to: CGPoint(x: 108.26, y: 78.65))
path.addLine(to: CGPoint(x: 100.26, y: 83.28))
path.addLine(to: CGPoint(x: 132.45, y: 110.39))
path.addLine(to: CGPoint(x: 128.48, y: 122.08))
path.addLine(to: CGPoint(x: 158.68, y: 116.79))
path.addLine(to: CGPoint(x: 158.68, y: 149.42))
path.addLine(to: CGPoint(x: 162.87, y: 149.42))
path.close() let mapleShapeLayer = CAShapeLayer()
mapleShapeLayer.path = path.cgPath
mapleView.layer.mask = mapleShapeLayer let moveDistance = path.bounds.maxX * 2
let transform =
CGAffineTransform(translationX: moveDistance, y: 0)
.scaledBy(x: -1, y: 1) mapleShapeLayer.setAffineTransform(transform) redView.addSubview(mapleView)
redView.center = CGPoint(x: fullScreenSize.width/2,
y: fullScreenSize.height/2)
self.view.addSubview(redView) return redView
}
所以前一段的 createPath 就是將這裡楓葉的 path 裝進來,並回傳 path,那麼,由於我們在 TextView 裡已裝了許多 text,這時就會自動排開。
結果阿伯出事了!阿伯!
繼續閱讀|回目錄
Debug
看到前段左圖,這位置不對呀!
因為將 Path 拆出來
給 textContainer 用,但在畫楓葉的函式中,Path 是先做為 CAShapeLayer 的 Path,最後再將 mapleView 加進 redView,最後再去校準中心點。
所以 redView(含 mapleView)的位置就會跟 Path 不一樣。
那麼,需讓路徑移動,改成如下:
path.apply(CGAffineTransform.identity.scaledBy(x: 1, y: 1).translatedBy(x: 40, y: 202))
最後結果就出現了。
文繞圖的步驟
另外,利用 exclusionPaths 製造出文繞圖
的效果,步驟如下:
- Textview 中加入 ImageView,設定 imageView 的位置。
- 宣告一個 Path 為貝茲曲線函式,大小為
imageView.frame
。 - 再讓 exclusionPaths 的陣列裝入這個路徑。
完成了!
這次就分享到這,感謝您的閱讀。
繼續閱讀|回目錄