-
-
Save watura/08b06adffd79cab32be76eb0804306c1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func rubyAnnotation(text: String, ruby: String) -> NSAttributedString { | |
| let rubyAttribute: [CFString: Any] = [ | |
| kCTRubyAnnotationSizeFactorAttributeName: 0.5 | |
| ] | |
| let rubyAnnotation = CTRubyAnnotationCreateWithAttributes( | |
| .auto, | |
| .auto, | |
| .before, | |
| ruby as CFString, | |
| rubyAttribute as CFDictionary | |
| ) | |
| return NSAttributedString( | |
| string: text, | |
| attributes: | |
| [ | |
| kCTRubyAnnotationAttributeName as NSAttributedString.Key: rubyAnnotation | |
| ] | |
| ) | |
| } | |
| var dummyAttributedString: NSAttributedString { | |
| let txt = NSMutableAttributedString(string: "だれもが") | |
| txt.append(rubyAnnotation(text: "創作", ruby: "そうさく")) | |
| txt.append(.init(string: "をはじめ、\n")) | |
| txt.append(rubyAnnotation(text: "続", ruby: "つづ")) | |
| txt.append(.init(string: "けられるようにする。")) | |
| // ルビが範囲外に表示されてしまうので行間を広げる | |
| let paragraphStyle = NSMutableParagraphStyle() | |
| paragraphStyle.lineHeightMultiple = 1.5 | |
| txt.addAttributes([ | |
| .font: UIFont.systemFont(ofSize: 16), | |
| .paragraphStyle: paragraphStyle, | |
| ], range: .init(location: 0, length: txt.length)) | |
| return txt | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public struct RubyCanvas: View { | |
| public var body: some View { | |
| Canvas { context, size in | |
| context.scaleBy(x: 1, y: -1) | |
| context.translateBy(x: 0, y: -size.height) | |
| let setter = CTFramesetterCreateWithAttributedString(dummyAttributedString) | |
| let path = CGPath(rect: CGRect(origin: .zero, size: size), transform: nil) | |
| let ct = CTFramesetterCreateFrame(setter, CFRange(), path, nil) | |
| context.withCGContext { cgContext in | |
| CTFrameDraw(ct, cgContext) | |
| } | |
| } | |
| } | |
| } | |
| #Preview { | |
| RubyCanvas() | |
| .padding() | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| struct RubyTextView: UIViewRepresentable { | |
| func makeUIView(context _: Context) -> UITextView { | |
| let view = UITextView() | |
| view.attributedText = dummyAttributedString | |
| view.isScrollEnabled = false | |
| return view | |
| } | |
| func updateUIView(_: UITextView, context _: Context) {} | |
| } | |
| #Preview { | |
| RubyTextView() | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| final class RubyViewController: UIViewController { | |
| override func viewDidLoad() { | |
| super.viewDidLoad() | |
| let textView = UITextView() | |
| textView.attributedText = dummyAttributedString | |
| textView.isScrollEnabled = true | |
| textView.translatesAutoresizingMaskIntoConstraints = false | |
| view.addSubview(textView) | |
| NSLayoutConstraint.activate([ | |
| textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0), | |
| textView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0), | |
| textView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0), | |
| textView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0), | |
| ]) | |
| } | |
| } | |
| #Preview(traits: .defaultLayout) { | |
| RubyViewController() | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment