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 株式会社ヌーラボ
FinOps in practice for growth and scale
nulabinc
PRO
0
63
成長と拡大を支える FinOps 実践記
nulabinc
PRO
1
120
製造業の設計・生産技術向け Backlog入門
nulabinc
PRO
0
41
配布資料_ヌーラボの情シスがおすすめする_問い合わせ対応を削減するBacklog活用術.pdf
nulabinc
PRO
0
130
Bits Agent Builder の⼊⾨と活⽤事例
nulabinc
PRO
0
3.3k
Getting Started with Bits Agent Builder: Real-World Use Cases
nulabinc
PRO
0
90
The_Evolution_of_Bits_AI_SRE.pdf
nulabinc
PRO
0
440
進化するBits AI SREと私と組織
nulabinc
PRO
4
1.3k
実践 Datadog MCP Server
nulabinc
PRO
4
1k
Other Decks in Technology
See All in Technology
AIエージェントの監視、思考を見るか行動を見るか / Monitoring AI Agents: Thoughts or Actions
yusukeshimizu
2
180
令和の今、あらためて IAM を考える。アクセスキーを「無くせない現実」との向き合い方
kazzpapa3
0
560
Content Mapper APIの応用例~CSS Modules、言語ファイル~
uhyo
2
630
llm-d に入門してみた / Try out llm-d
kota2and3kan
0
100
続・ソフトウェアアーキテクトのための意思決定術: Decision Readiness, Revisited — When AI Changes the Economics of Software Architecture
snoozer05
PRO
9
2.8k
AWS構成から考えるWebセキュリティ ― WordPressの構築経験から考える公開範囲と更新運用【JAWS FESTA 2026 in AKITA】
cscengineer
PRO
2
390
2026 Apache Flink Community Checkpoint
rmetzger
0
210
Claude Codeで作ったアプリを安全に公開する/Built with Claude Japan 2026
yoshidashingo
0
220
コードレビューをなくして見えたもの
henteko
0
140
AI Agent 時代のデータ基盤: ClickHouse で実現する 超高速分析とコスト削減の両立
jozono
0
220
大江戸Ruby会議でデータベース クライアントの話をするのは 間違っているだろうか
yahonda
1
110
Kiro 入門 (1 つのエージェントを、どの画面からでも) | 目指せ Kiro マスター 01
inariku
PRO
6
1.4k
Featured
See All Featured
Believing is Seeing
oripsolob
1
270
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
650
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
RailsConf 2023
tenderlove
30
1.6k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
60k
A Modern Web Designer's Workflow
chriscoyier
699
190k
How to Think Like a Performance Engineer
csswizardry
28
2.9k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
400
The Invisible Side of Design
smashingmag
301
52k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
1k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.3k
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)