Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
TextKitで行うテキスト装飾パターン/Text decoration pattern wi...
Search
株式会社ヌーラボ
PRO
October 30, 2019
Technology
890
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 株式会社ヌーラボ
The_Evolution_of_Bits_AI_SRE.pdf
nulabinc
PRO
0
340
進化するBits AI SREと私と組織
nulabinc
PRO
4
790
実践 Datadog MCP Server
nulabinc
PRO
4
790
全社横断PjM⽀援チーム “PEaS”の取り組みと プロジェクトマネジメント でのAI活⽤について
nulabinc
PRO
0
190
Datadog の RBAC のすべて
nulabinc
PRO
4
840
Datadog Live Tokyo 2025登壇資料
nulabinc
PRO
0
170
How to Migrate Your Backlog Free Plan
nulabinc
PRO
0
250
チームワークマネジメント Bar #5
nulabinc
PRO
0
94
Geeks Who Drink Fukuoka - 202508
nulabinc
PRO
0
72
Other Decks in Technology
See All in Technology
本当の”仕事”を手放せる未来が見えた
mu7889yoon
0
220
AIに障害切り分けを全部やってもらった。 。 。 。
estie
0
340
Text-to-SQLをAgentCoreで実現し、生成されるSQLの精度を定量的に評価する
yakumo
2
460
テスト設計の本質を改めて考えてみる~生成AIを活用する時代だからこそ、作ったテストの説明性を高めよう~
yamasaki696
1
290
打造你的 AI 工作流:Agent Skill + MCP 實戰工作坊
appleboy
0
480
技術・能力を向上する原理原則 #きのこセッションa #きのこ2026
bash0c7
0
200
From Prompt Engineering to Loop Engineering
shibuiwilliam
1
330
cccccc
moznion
0
1.6k
SRE歴2ヶ月でも開発6年の知見を活かして、チームで止まっていた環境改善を前に進めた話
a_ono
0
180
Fabricをフル活用する AI Agent Hub -製造業特化AIエージェントの設計
iotcomjpadmin
0
190
Keeping applications secure by evolving OAuth 2.0 and OpenID Connect
ahus1
PRO
1
130
Claude Codeとハーネスについて考えてみる
oikon48
15
6.9k
Featured
See All Featured
From π to Pie charts
rasagy
0
220
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
How to make the Groovebox
asonas
2
2.3k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
180
BBQ
matthewcrist
89
10k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
270
Design in an AI World
tapps
1
260
4 Signs Your Business is Dying
shpigford
187
22k
Unsuck your backbone
ammeep
672
58k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
220
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
1.9k
Color Theory Basics | Prateek | Gurzu
gurzu
0
380
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)