Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
TextKitで行うテキスト装飾パターン/Text decoration pattern wi...
Search
株式会社ヌーラボ
PRO
October 30, 2019
Technology
900
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
TextKitで行うテキスト装飾パターン/Text decoration pattern with TextKit
株式会社ヌーラボ
PRO
October 30, 2019
More Decks by 株式会社ヌーラボ
See All by 株式会社ヌーラボ
製造業の設計・生産技術向け Backlog入門
nulabinc
PRO
0
19
配布資料_ヌーラボの情シスがおすすめする_問い合わせ対応を削減するBacklog活用術.pdf
nulabinc
PRO
0
120
Bits Agent Builder の⼊⾨と活⽤事例
nulabinc
PRO
0
3.2k
Getting Started with Bits Agent Builder: Real-World Use Cases
nulabinc
PRO
0
83
The_Evolution_of_Bits_AI_SRE.pdf
nulabinc
PRO
0
420
進化するBits AI SREと私と組織
nulabinc
PRO
4
1.3k
実践 Datadog MCP Server
nulabinc
PRO
4
1k
全社横断PjM⽀援チーム “PEaS”の取り組みと プロジェクトマネジメント でのAI活⽤について
nulabinc
PRO
0
260
Datadog の RBAC のすべて
nulabinc
PRO
4
1k
Other Decks in Technology
See All in Technology
LambdaWebFunctionsを試してみた / exploring-lambda-web-functions
koukihosaka
1
340
フロントエンドカンファレンス関西2026 - 速すぎるUIに、待ち時間を
teamlab
PRO
0
130
Conditional PED-ANOVA: Hyperparameter Importance in Hierarchical & Dynamic Search Spaces
pfn
PRO
0
130
エンタメ企業のM&Aを支えるデータ基盤 ― 統合から店舗のリアルタイム分析まで / Data Engineering Summit 2026
genda
0
180
ソフトウェア ファクトリー - 再現性のあるソフトウェアの工場づくり / Software factory
iktakahiro
6
4.9k
QA4AI 2026-Oct 生成AI時代の品質保証
tokuty
1
860
その Valkey 使いこなしていますか?
onk
PRO
5
1.5k
Code for Security プロジェクト紹介 2026年10月
yu23ki14
0
110
WasmをRustにする
sansantech
PRO
0
250
脆弱性診断って、何をしているの? 〜弱点を見つけて、会社の改善につなげるまで〜
keeg
0
920
AI駆動で「他アプリの音を加工できる」アプリを作った
satomasahiro2005
0
150
Refining Active Record
shugo
0
160
Featured
See All Featured
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
890
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3.2k
Color Theory Basics | Prateek | Gurzu
gurzu
1
490
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
2
950
YesSQL, Process and Tooling at Scale
rocio
174
15k
Discover your Explorer Soul
emna__ayadi
2
1.3k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
600
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Bash Introduction
62gerente
615
220k
Statistics for Hackers
jakevdp
799
230k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.7k
Transcript
TextKitͰߦ͏ςΩετ ০ύλʔϯ at ୈ10ճ HAKATA.swift ~ԬͰSwiftͷษڧձ~ 1 By Taichiro Yoshida
(@dataich)
ϓϩϑΟʔϧ • ٢ాଠҰ @dataich • Swift/Scala • גࣜձࣾψʔϥϘॴଐ • WebαʔϏε
TypetalkΛ։ൃɾӡ༻த • ΠΠϨ 2 By Taichiro Yoshida (@dataich)
એ ! 3 By Taichiro Yoshida (@dataich)
Backlog 4 By Taichiro Yoshida (@dataich)
Cacoo 5 By Taichiro Yoshida (@dataich)
Typetalk 6 By Taichiro Yoshida (@dataich)
ࠓ͓͢Δ͜ͱ • TextKitͰߦ͏ςΩετ০ύλʔϯ • TextKitͱ • ඪ४Ͱఏڙ͞Ε͍ͯΔ০ • ຊ •
ඪ४Ͱఏڙ͞Ε͍ͯͳ͍০ • ࣮ύλʔϯ • ·ͱΊ 7 By Taichiro Yoshida (@dataich)
ιʔείʔυ dataich/TextKitSample 8 By Taichiro Yoshida (@dataich)
TextKitͱ TextKit | Apple Developer Documentation • ςΩετͷϨΠΞτΛίϯτϩʔϧ͢Δ༷ʑͳΫϥεͷू·Γ • NSAttributedString
• NSTextStorage (NSMutableAttributedString) • NSLayoutManager • NSTextContainer • UILabelɺUITextViewͳͲΛ͍ͬͯΕࣗવͱͦͷҰ෦Λ͍ͬͯΔ 9 By Taichiro Yoshida (@dataich)
ग़య - Text Programming Guide for iOS 10 By Taichiro
Yoshida (@dataich)
NSAttributedString • จࣈྻ • จࣈྻͷൣғͱͦͷଐੑใʢݟͨϦϯΫͳͲʣͷϦετ Λ࣋ͭ 11 By Taichiro Yoshida
(@dataich)
NSTextStorage (NSMutableAttributedString) • TextKitͰͷॏཁͳετϨʔδϝΧχζϜ • NSMutableAttributedStringͷαϒΫϥεʹͳ͍ͬͯΔ • ςΩετଐੑใʹมߋ͕Ճ͑ΒΕΔͱޙड़͢Δ NSLayoutManagerʹ௨͢Δ 12
By Taichiro Yoshida (@dataich)
NSTextContainer • ςΩετΛදࣔ͢ΔίϯςφͷใΛ࣋ͭ • ࠲ඪͱܗঢ়Λ࣋ͪɺͲ͜ʹςΩετΛͲ͏ද͖͔ࣔ͢Λఆٛ ͢Δ • Ͳ͜Ͱվߦ͖͢ͳͷ͔ͳͲ • αϒΫϥεΛఆٛͯ͠ɺಠࣗͷίϯςφΛ࣮Մೳ
• ྫʣ ପԁܗͷςΩετίϯςφ 13 By Taichiro Yoshida (@dataich)
NSLayoutManager • NSTextStorage͕࣋ͭจࣈྻΛϨΠΞτ͠දࣔ͢Δ • NSTextStorageͷมߋ௨Λड͚औΓඳը • UnicodeͷจࣈΛάϦϑʹϚοϓ͠ɺͦΕΛNSTextContainerʹ ηοτ • ߋʹͦͷNSTextContainerΛUITextViewͳͲʹηοτ
• ඳը͞Ε͍ͯΔάϦϑͷ࠲ඪΛ͍ͬͯΔ 14 By Taichiro Yoshida (@dataich)
ඪ४Ͱఏڙ͞Ε͍ͯΔ ০ 15 By Taichiro Yoshida (@dataich)
ྫ let text = """ ԬͷiOSΤϯδχΞୡ͕ओ࠵͢Δɺ ϓϩάϥϛϯάݴޠ Swift ͱͦͷपลٕज़ͷษڧձͰ͢ɻ ൃలΛଓ͚Δ
Swift ͱͦͷपลٕज़ͷಈΛ͍ɺ ॳ৺ऀ/্ڃऀ/एஉঁΛΘͣɺใަͷͱͯ͠ ػೳ͢Δ͜ͱΛతͱ͍ͯ͠·͢ɻ """ 16 By Taichiro Yoshida (@dataich)
NSAttributedString.Key .foregroundColor - จࣈ৭ 17 By Taichiro Yoshida (@dataich)
NSAttributedString.Key .foregroundColor - จࣈ৭ let attributedString = NSMutableAttributedString(string: text) attributedString.setAttributes(
[NSAttributedString.Key.foregroundColor : UIColor.blue], range: NSRange(location: 18, length: 15)) 18 By Taichiro Yoshida (@dataich)
NSAttributedString.Key .backgroundColor - എܠ৭ 19 By Taichiro Yoshida (@dataich)
NSAttributedString.Key .backgroundColor - എܠ৭ let attributedString = NSMutableAttributedString(string: text) attributedString.setAttributes(
[NSAttributedString.Key.backgroundColor : UIColor.lightGray], range: NSRange(location: 18, length: 15)) 20 By Taichiro Yoshida (@dataich)
NSAttributedString.Key .font - ϑΥϯτ 21 By Taichiro Yoshida (@dataich)
NSAttributedString.Key .font - ϑΥϯτ let attributedString = NSMutableAttributedString(string: text) attributedString.setAttributes(
[NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14)], range: NSRange(location: 0, length: text.count)) attributedString.setAttributes( [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 14)], range: NSRange(location: 18, length: 15)) 22 By Taichiro Yoshida (@dataich)
ͦͷଞ • NSAttributedString.Key.paragraphStyle • NSAttributedString.Key.underlineStyle • NSAttributedString.Key.shadow NSAttributedString.Key - NSAttributedString
| Apple Developer Documentation 23 By Taichiro Yoshida (@dataich)
ඪ४Ͱఏڙ͞Ε͍ͯͳ ͍০ 24 By Taichiro Yoshida (@dataich)
ྫ: ΠϯϥΠϯίʔυ • എܠΛؙ֯ʹ͍ͨ͠ • എܠʹϘʔμʔΛ͚͍ͨ 25 By Taichiro Yoshida
(@dataich)
ྫ: ίʔυ • จࣈྻ͚ͩ͡Όͳ͘ෳߦશମͷഎܠΛΧελϜ͍ͨ͠ 26 By Taichiro Yoshida (@dataich)
ྫ: Ҿ༻ • ߦ಄ʹॎઢΛҾ͖͍ͨ 27 By Taichiro Yoshida (@dataich)
࣮ྫ 28 By Taichiro Yoshida (@dataich)
ΠϯϥΠϯίʔυ 29 By Taichiro Yoshida (@dataich)
1. NSAttributedStringʹΧελϜଐੑΛՃ͢Δ struct InlineCodeSample { // 1. ΧελϜଐੑͷΩʔΛఆٛ static let
key = NSAttributedString.Key(rawValue: "InlineCode") var attributedString: NSAttributedString { ... let attributedString = NSMutableAttributedString(string: text) // 2. ൣғΛࢦఆͯ͠ΧελϜଐੑΛઃఆ attributedString.setAttributes([Self.key : UIColor.lightGray], range: NSRange(location: 18, length: 23)) return attributedString } } 30 By Taichiro Yoshida (@dataich)
2. NSLayoutManagerΛܧঝͨ͠ΫϥεΛ࡞Δ class CustomLayoutManager: NSLayoutManager { //ɹϨΠΞτʹؔΘΔॲཧΛ࣮͢Δ } ... let
textStorage = NSTextStorage() let layoutManager = CustomLayoutManager() let textContainer = NSTextContainer() layoutManager.addTextContainer(textContainer) textStorage.addLayoutManager(layoutManager) textView = UITextView(frame: .zero, textContainer: textContainer) 31 By Taichiro Yoshida (@dataich)
3. CustomLayoutManagerͰඞཁͳඳըϝιουΛΦʔόʔϥΠυ ͢Δ class CustomLayoutManager: NSLayoutManager { // എܠͷඳըΛߦ͏ॲཧ override
func drawBackground(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) { super.drawBackground(forGlyphRange: glyphsToShow, at: origin) drawInlineCode(forGlyphRange: glyphsToShow, at: origin) } func drawInlineCode(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) { // ΠϯϥΠϯίʔυʹؔΘΔॲཧΛ࣮͢Δ } } 32 By Taichiro Yoshida (@dataich)
4. ΧελϜଐੑΛ࣋ͭจࣈྻͷൣғΛ୳͢ func drawInlineCode(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
let range = characterRange( forGlyphRange: glyphsToShow, actualGlyphRange: nil) textStorage?.enumerateAttribute( InlineCodeSample.key, in: range, options: []) { (color, range, _) in // ΧελϜଐੑInlineCodeʹؔΘΔॲཧΛ࣮͢Δ }) } 33 By Taichiro Yoshida (@dataich)
5. ΧελϜଐੑΛ࣋ͭจࣈྻͷάϦϑ͕දࣔ͞ΕΔCGRectΛऔಘ ͯ͠ඳըॲཧΛߦ͏ • enumerateEnclosingRectsΛ͏ 34 By Taichiro Yoshida (@dataich)
5. ΧελϜଐੑΛ࣋ͭจࣈྻͷάϦϑ͕දࣔ͞ΕΔCGRectΛऔಘ ͯ͠ඳըॲཧΛߦ͏ let glyphRange = self.glyphRange(forCharacterRange: range, actualCharacterRange: nil)
self.enumerateEnclosingRects( forGlyphRange: glyphRange, withinSelectedGlyphRange: glyphRange, in: container) { (rect, _) in // άϦϑ͕ඳը͞Ε͍ͯΔCGRect͕औಘͰ͖ΔͷͰ // UIBezierPathͳͲΛͬͯഎܠϘʔμʔΛඳը͢Δ } 35 By Taichiro Yoshida (@dataich)
ίʔυ • جຊతʹΠϯϥΠϯίʔυͱಉ͡ 36 By Taichiro Yoshida (@dataich)
• enumerateEnclosingRectsͰͳ͘enumerateLineFragments Λ͏ 37 By Taichiro Yoshida (@dataich)
enumerateLineFragmentsͰߦྖҬͷCGRectΛऔಘ self.enumerateLineFragments( forGlyphRange: glyphRange) { (rect, usedRect, textContainer, glyphRange, stop)
in // άϦϑ͕ඳը͞Ε͍ͯΔߦͷCGRect͕औಘͰ͖ΔͷͰ // ෳߦͷߴ͞Λܭࢉ͢ΔͳͲ͢Δ } • enumerateEnclosingRectsάϦϑ͕දࣔ͞Ε͍ͯΔ֤ྖҬͷCGRectΛྻ ڍ • enumerateLineFragmentsάϦϑ͕දࣔ͞Ε͍ͯΔߦྖҬͷCGRectΛྻڍ • boundingRectશͯͷάϦϑ͕ऩ·ΔྖҬͷCGRect1ͭ 38 By Taichiro Yoshida (@dataich)
boundingRect 39 By Taichiro Yoshida (@dataich)
Ҿ༻ • ίʔυͱ΄΅ಉ͡ͰඳըͷίʔυΛม͑ΔͷΈ 40 By Taichiro Yoshida (@dataich)
ͦͷଞ • എܠҎ֎ͷ߹ΦʔόϥΠυ͖͢ϝιου͕͋ΔΈ͍ͨ ʢࢼͯ͠ͳ͍ʣ • drawGlyphs • drawStrikethrough • drawUnderline
41 By Taichiro Yoshida (@dataich)
·ͱΊ • NSAttributedStringʹΧελϜଐੑΛՃ͢Δ • NSLayoutManagerΛܧঝͨ͠ΫϥεΛ࡞Δ • CustomLayoutManagerͰඞཁͳඳըϝιουΛΦʔόʔϥΠυ͢Δ • ΧελϜଐੑΛ࣋ͭจࣈྻͷൣғΛ୳͢ •
ΧελϜଐੑΛ࣋ͭจࣈྻͷάϦϑ͕දࣔ͞ΕΔCGRectΛऔಘͯ͠ඳ ըॲཧΛߦ͏ • TextKitཧղ͢Δͱָ͍͠ʂ 42 By Taichiro Yoshida (@dataich)
ࢀߟ • TextKitΛϚελʔ͠ɺࢥ͍௨ΓʹจࣈΛϨΠΞτ͢Δ • TextKitʹΑΔςΩετϨΠΞτ 43 By Taichiro Yoshida (@dataich)
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ 44 By Taichiro Yoshida (@dataich)