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
Handling rich text in Swift
Search
Kishikawa Katsumi
August 20, 2016
Programming
7.2k
17
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Handling rich text in Swift
Handling rich text
in Swift
iOSDC Japan 2016
Kishikawa Katsumi
August 20, 2016
More Decks by Kishikawa Katsumi
See All by Kishikawa Katsumi
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
250
OCRを使ってゲームのアイテムをデータ化する
kishikawakatsumi
0
190
Running Swift without an OS
kishikawakatsumi
0
1.1k
浮動小数の比較について
kishikawakatsumi
0
630
Automatic Grammar Agreementと Markdown Extended Attributes について
kishikawakatsumi
0
280
愛される翻訳の秘訣
kishikawakatsumi
3
500
Private APIの呼び出し方
kishikawakatsumi
3
1k
iOSでSVG画像を扱う
kishikawakatsumi
0
270
Build your own WebP codec in Swift
kishikawakatsumi
2
2.8k
Other Decks in Programming
See All in Programming
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
380
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
310
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
280
FreeBSDでZabbixを動かす
kenkino
0
320
iOSDC2026登壇資料.pdf
riofujimon
0
180
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
350
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
180
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
4
740
Building an Out-of-Order CPU
latte72
1
790
Heart of Swift Concurrency
koher
0
950
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
220
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
1
560
Featured
See All Featured
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
530
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
560
Discover your Explorer Soul
emna__ayadi
2
1.3k
Skip the Path - Find Your Career Trail
mkilby
1
240
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3.1k
Making Projects Easy
brettharned
120
6.8k
Being A Developer After 40
akosma
91
590k
Transcript
Handling rich text in Swift iOSDC Japan 2016 Katsumi Kishikawa
[email protected]
Katsumi Kishikawa Realm Inc.
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
Agenda ˖ J04ךذؗأزٖ؎،ؐزחאְג ˖ ة؎هؚٓؿ؍ך㛇燉 ˖ 5FYU,JUך㛇燉ה䘔欽
[email protected]
iOS 7Ҏ߱ͷςΩετϨΠΞτ
[email protected]
TextKit
[email protected]
TextKitͱ ˖ 넝鸞זٌتٝذؗأزٖ؎،ؐز٥ٖٝت ؚٔٝؒٝآٝ ˖ $PSF5FYUד⡲גְ ˖ 6*,JUהך窟さ
[email protected]
https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/CustomTextProcessing/CustomTextProcessing.html
UILabel
[email protected]
[email protected]
UILabelΛී௨ʹ͏
[email protected]
ώϥΪϊͱγεςϜϑΥϯτ UIFont(name: "HiraginoSans-W3", size: 32) UIFont.systemFontOfSize(32)
[email protected]
ώϥΪϊͱγεςϜϑΥϯτ
[email protected]
ώϥΪϊͱγεςϜϑΥϯτ
[email protected]
General Header
[email protected]
ΞϧϑΝϕοτΛؚ·ͳ͍߹
ߦͷߴ͞ԿͰܾ·Δ͔
[email protected]
[email protected]
Font metrics https://developer.apple.com/library/mac/documentation/TextFonts/Conceptual/CocoaTextArchitecture/FontHandling/FontHandling.html
[email protected]
Font metrics https://developer.apple.com/library/mac/documentation/TextFonts/Conceptual/CocoaTextArchitecture/FontHandling/FontHandling.html
[email protected]
Font metrics
[email protected]
Font metrics Baseline X-Height Cap height Ascent Descent
[email protected]
ώϥΪϊಛघͳϝτϦΫεΛ࣋ͭ
[email protected]
ʢࢀߟʣNoto Sans CJK JP
let label = UILabel(frame: view.bounds) label.backgroundColor = ... label.textColor =
... label.font = ... label.text = text ... label.sizeToFit() label.frame.size.height += ceil(abs(label.font.descender * 2))
[email protected]
্ԼʹDescentΛิ͏
[email protected]
্ԼʹDescentΛิ͏
[email protected]
্ԼʹDescentΛิ͏
[email protected]
ΦϦδφϧͱൺֱ
• ώϥΪϊΛ໌ࣔతʹࢦఆ͠ͳ͍ • γεςϜϑΥϯτΛ͏ • σβΠϯࢦࣔॻͳͲͰɺώϥΪϊ͍͍ͨͯγε ςϜϑΥϯτΛҙਤ͍ͯ͠Δͣ • தࠃޠ༻ϑΥϯτʹϑΥʔϧόοΫͨ͘͠ͳ͍Մ ೳੑ
• ώϥΪϊΛࢦఆ͢Δ߹ɺΞϧϑΝϕοτʹؾΛ ͚ͭΔ
[email protected]
ώϥΪϊͷϝτϦΫεʹҙ
[email protected]
Tips: ຊޠϑΥϯτʹϑΥʔϧόοΫͤ͞Δ let attributes = [ NSFontAttributeName: font, kCTLanguageAttributeName
as String: "ja", ... ]
αΠζͷܭࢉ
[email protected]
let size = CGSize(width: label.bounds.width, height: CGFloat.max) let boundingRect =
NSString(string: text).boundingRectWithSize(size, options: [.UsesLineFragmentOrigin], attributes: [NSFontAttributeName: font], context: nil)
[email protected]
ඳըαΠζΛಘΔ
[email protected]
ඳըαΠζΛಘΔ
UITextView
[email protected]
[email protected]
UITextViewΛී௨ʹ͏
[email protected]
UITextViewΛී௨ʹ͏ UIFont(name: "HiraginoSans-W3", size: 32) UIFont.systemFontOfSize(32)
[email protected]
ඳըαΠζ
[email protected]
ඳըαΠζ
[email protected]
σϑΥϧτͷϚʔδϯ
σϑΥϧτͷϚʔδϯ textView.textContainer.lineFragmentPadding textView.textContainerInset UIEdgeInsets(top: 8.0, left: 0.0, bottom: 8.0, right:
0.0) 5.0
[email protected]
[email protected]
ώϥΪϊΛࢦఆͨ͠߹ font.leading
σϑΥϧτͷελΠϧΛϦηοτ͢Δ
[email protected]
let textView = UITextView(frame: view.bounds) ... textView.textContainerInset = UIEdgeInsetsZero textView.sizeToFit()
[email protected]
textContainerInsetΛऔΓআ͘
let textView = UITextView(frame: view.bounds) ... textView.textContainerInset = UIEdgeInsetsZero textView.sizeToFit()
[email protected]
textContainerInsetΛऔΓআ͘
[email protected]
textContainerInsetΛऔΓআ͘
let textView = UITextView(frame: view.bounds) ... textView.textContainer.lineFragmentPadding = 0 textView.sizeToFit()
[email protected]
lineFragmentPaddingΛऔΓআ͘
let textView = UITextView(frame: view.bounds) ... textView.textContainer.lineFragmentPadding = 0 textView.sizeToFit()
[email protected]
lineFragmentPaddingΛऔΓআ͘
[email protected]
lineFragmentPaddingΛऔΓআ͘
let size = CGSize(width: textView.bounds.width, height: CGFloat.max) let boundingRect =
NSString(string: text).boundingRectWithSize(size, options: [.UsesLineFragmentOrigin], attributes: [NSFontAttributeName: font], context: nil)
[email protected]
ඳըαΠζΛಘΔ
[email protected]
ඳըαΠζΛಘΔ
let textView = UITextView(frame: view.bounds) ... textView.layoutManager.usesFontLeading = false textView.sizeToFit()
[email protected]
font.leadingΛऔΓআ͘
let textView = UITextView(frame: view.bounds) ... textView.layoutManager.usesFontLeading = false textView.sizeToFit()
[email protected]
font.leadingΛऔΓআ͘
[email protected]
font.leadingΛऔΓআ͘
let size = CGSize(width: textView.bounds.width, height: CGFloat.max) let boundingRect =
NSString(string: text).boundingRectWithSize(size, options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: [NSFontAttributeName: font], context: nil)
[email protected]
ʢผղʣfont.leadingΛؚΊͯܭࢉ͢Δ
[email protected]
ʢผղʣfont.leadingΛؚΊͯܭࢉ͢Δ
[email protected]
ʢผղʣfont.leadingΛؚΊͯܭࢉ͢Δ
[email protected]
textView.textContainerInset = UIEdgeInsetsZero textView.textContainer.lineFragmentPadding = 0 textView.layoutManager.usesFontLeading = false
σϑΥϧτελΠϧͷϦηοτ
͞·͟·ͳελΠϧʹରԠ͢Δ
[email protected]
[email protected]
ߦؒͷมߋ
NSAttributedString
[email protected]
NSParagraphStyle
[email protected]
let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.minimumLineHeight = ceil(font.lineHeight) paragraphStyle.maximumLineHeight = ceil(font.lineHeight)
paragraphStyle.lineSpacing = 8 let attributes = [ NSFontAttributeName: font, NSForegroundColorAttributeName: UIColor(...), NSParagraphStyleAttributeName: paragraphStyle, ] let attributedText = NSAttributedString(string: text, attributes: attributes) textView.attributedText = attributedText
[email protected]
NSAttributedString
let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.minimumLineHeight = ceil(font.lineHeight) paragraphStyle.maximumLineHeight = ceil(font.lineHeight)
paragraphStyle.lineSpacing = 8 let attributes = [ NSFontAttributeName: font, NSForegroundColorAttributeName: UIColor(...), NSParagraphStyleAttributeName: paragraphStyle, ] let attributedText = NSAttributedString(string: text, attributes: attributes) textView.attributedText = attributedText
[email protected]
NSAttributedString
[email protected]
ߦؒͷมߋ
[email protected]
ߦؒͷมߋ
let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.minimumLineHeight = ceil(font.lineHeight) paragraphStyle.maximumLineHeight = ceil(font.lineHeight)
paragraphStyle.lineSpacing = 8
[email protected]
min/maxLineHeight
[email protected]
min/maxLineHeight
[email protected]
minimumLineHeight
[email protected]
maximumLineHeight
NSAttributedStringΛ׆༻͢Δ
[email protected]
[email protected]
͞ΒʹߦؒΛ͘
[email protected]
͞ΒʹߦؒΛ͘
[email protected]
Օॻ͖
·ͱΊ • iOS 7Ҏ߱ͷςΩετϨΠΞτɺ͍͔ʹ ΩϨΠͳNSAttributedStringΛ࡞Δ͔ • λΠϙάϥϑΟͷجૅΛΖ͏ • ϑΥϯτʹώϥΪϊΛࢦఆ͢Δͱ͖ҙ •
Ͱ͖Δ͚ͩγεςϜϑΥϯτΛ͓͏
[email protected]
Questions? Katsuma Kishikawa
[email protected]
www.realm.io/jp @k_katsumi