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
Handling rich text in Swift
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Kishikawa Katsumi
August 20, 2016
Programming
7.1k
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
OCRを使ってゲームのアイテムをデータ化する
kishikawakatsumi
0
150
Running Swift without an OS
kishikawakatsumi
0
960
浮動小数の比較について
kishikawakatsumi
0
580
Automatic Grammar Agreementと Markdown Extended Attributes について
kishikawakatsumi
0
260
愛される翻訳の秘訣
kishikawakatsumi
3
460
Private APIの呼び出し方
kishikawakatsumi
3
1k
iOSでSVG画像を扱う
kishikawakatsumi
0
250
Build your own WebP codec in Swift
kishikawakatsumi
2
2.4k
iOSDC 2024 SMBファイル共有をSwiftで実装する
kishikawakatsumi
1
330
Other Decks in Programming
See All in Programming
OSINT for SRE: 学術論文とポストモーテムから探る システム障害の共通パターン / SRE NEXT 2026
tomoyk
1
3.5k
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
170
「正の参照」と 「負の導出」で組む ハーネスエンジニアリング
cottpan
1
140
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
5.7k
【やさしく解説 設計編 #1】「ドメイン駆動」と「実装駆動」ってなに? 〜設計の考え方を、たとえ話で学ぼう〜
panda728
PRO
1
110
act1-costs.pdf
sumedhbala
0
210
はてなアカウント基盤 State of the Union
cockscomb
1
1.3k
20260623_Loop Engineeringで自分の分身の問い合わせBotを作る
ryugen04
0
200
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
symfony/aiとlaravel/boost
77web
0
120
Go1.27で導入されるジェネリクスメソッドでできること
mackee
0
280
ローカルLLMでどこまでコードが書けるか -縮小版 / How much code can be written on a local LLM Shortened
kishida
2
190
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
350
AI: The stuff that nobody shows you
jnunemaker
PRO
8
820
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
490
How to Ace a Technical Interview
jacobian
281
24k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
Automating Front-end Workflow
addyosmani
1370
210k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Writing Fast Ruby
sferik
630
63k
Music & Morning Musume
bryan
47
7.3k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.8k
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