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
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活用術.pdf
nulabinc
PRO
0
63
Bits Agent Builder の⼊⾨と活⽤事例
nulabinc
PRO
0
2.2k
Getting Started with Bits Agent Builder: Real-World Use Cases
nulabinc
PRO
0
75
The_Evolution_of_Bits_AI_SRE.pdf
nulabinc
PRO
0
370
進化するBits AI SREと私と組織
nulabinc
PRO
4
1.1k
実践 Datadog MCP Server
nulabinc
PRO
4
920
全社横断PjM⽀援チーム “PEaS”の取り組みと プロジェクトマネジメント でのAI活⽤について
nulabinc
PRO
0
230
Datadog の RBAC のすべて
nulabinc
PRO
4
920
Datadog Live Tokyo 2025登壇資料
nulabinc
PRO
0
210
Other Decks in Technology
See All in Technology
振り返りこそエンジニアの本領
negima
0
280
Self Healing Rollouts: Automating Production Fixes with Agentic AI
kdubois
0
150
[RSJ26] Building a VLA Model Based on Self-Distilled Classification
keio_smilab
PRO
0
190
KAEN Company Deck
kaen
PRO
0
300
本番に近いテストをもっと手軽に - Postmanで広がるAPIテストの世界 / Expanding the World of API Testing with Postman
yokawasa
1
250
その指示、Bobにしっかり伝わってる?初心者でも即実践できる プロンプト/コンテキスト設計のコツ
muehara
0
110
Webとヘルスデータ
yukukotani
0
170
Tab5をRubyで動くパソコンにする
kishima
1
170
少人数データチームのDevin活用実践事例
runandy16
2
430
[RSJ26] AnoleVLA: Lightweight Vision-Language-Action Model with Deep State Space Models for Mobile Manipulation
keio_smilab
PRO
0
120
Genie Code ワークショップ 基礎編 / Genie-Code-Workshop-fundamental
databricksjapan
PRO
0
350
PfEingのアプローチで働こう
rindrics
0
170
Featured
See All Featured
Exploring anti-patterns in Rails
aemeredith
3
490
Faster Mobile Websites
deanohume
310
32k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
Rails Girls Zürich Keynote
gr2m
96
14k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.5k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
Building the Perfect Custom Keyboard
takai
2
860
4 Signs Your Business is Dying
shpigford
187
23k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Technical Leadership for Architectural Decision Making
baasie
3
550
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.5k
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)