Skip to content

Commit 854f185

Browse files
committed
Added Ruby sample.
1 parent 8271823 commit 854f185

File tree

9 files changed

+254
-2
lines changed

9 files changed

+254
-2
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ Example for UIBlurEffect and UIVibrancyEffect.
9494
<img src="ResourcesForREADME/visualeffect.jpg" width="200">
9595

9696

97+
###Ruby Annotation
98+
99+
Display the pronunciation of characters using CTRubyAnnotationRef.
100+
101+
<img src="ResourcesForREADME/ruby.jpg" width="200">
102+
103+
97104
###WebKit
98105

99106
Browsing example using WKWebView.

ResourcesForREADME/ruby.jpg

15.8 KB
Loading

iOS8Sampler.xcodeproj/project.pbxproj

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@
173173
8AB959AE19A38478008EE97F /* AlertViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8AB959AC19A38478008EE97F /* AlertViewController.xib */; };
174174
8AB959B219A38D83008EE97F /* UIAlertController+TTMAppearance.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AB959B119A38D83008EE97F /* UIAlertController+TTMAppearance.m */; };
175175
8AB959E819A398F4008EE97F /* AlertViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AB959E719A398F4008EE97F /* AlertViewController.m */; };
176+
8ABBB65C19CBA48800F44D89 /* RubyAnnotationLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ABBB65B19CBA48800F44D89 /* RubyAnnotationLabel.m */; };
177+
8ABBB65D19CBA48800F44D89 /* RubyAnnotationLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ABBB65B19CBA48800F44D89 /* RubyAnnotationLabel.m */; };
178+
8ABBB65E19CBA7CF00F44D89 /* RubyAnnotationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AD104BD19CB99BA00C30A3D /* RubyAnnotationViewController.m */; };
179+
8ABBB65F19CBA7D400F44D89 /* RubyAnnotationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8AD104BE19CB99BA00C30A3D /* RubyAnnotationViewController.xib */; };
180+
8AD104BF19CB99BA00C30A3D /* RubyAnnotationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AD104BD19CB99BA00C30A3D /* RubyAnnotationViewController.m */; };
181+
8AD104C019CB99BA00C30A3D /* RubyAnnotationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8AD104BE19CB99BA00C30A3D /* RubyAnnotationViewController.xib */; };
176182
8AE7B7B519A1981E00E0C6EB /* SVProgressHUD.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8AE7B7B219A1981E00E0C6EB /* SVProgressHUD.bundle */; };
177183
8AE7B7B619A1981E00E0C6EB /* SVProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AE7B7B419A1981E00E0C6EB /* SVProgressHUD.m */; };
178184
8AE7B7C519A1999600E0C6EB /* HistogramViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AE7B7BE19A1999600E0C6EB /* HistogramViewController.m */; };
@@ -330,6 +336,11 @@
330336
8AB959B619A38FB4008EE97F /* iOS8Sampler-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "iOS8Sampler-Bridging-Header.h"; sourceTree = "<group>"; };
331337
8AB959E619A398F4008EE97F /* AlertViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlertViewController.h; sourceTree = "<group>"; };
332338
8AB959E719A398F4008EE97F /* AlertViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlertViewController.m; sourceTree = "<group>"; };
339+
8ABBB65A19CBA48800F44D89 /* RubyAnnotationLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RubyAnnotationLabel.h; sourceTree = "<group>"; };
340+
8ABBB65B19CBA48800F44D89 /* RubyAnnotationLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RubyAnnotationLabel.m; sourceTree = "<group>"; };
341+
8AD104BC19CB99BA00C30A3D /* RubyAnnotationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RubyAnnotationViewController.h; sourceTree = "<group>"; };
342+
8AD104BD19CB99BA00C30A3D /* RubyAnnotationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RubyAnnotationViewController.m; sourceTree = "<group>"; };
343+
8AD104BE19CB99BA00C30A3D /* RubyAnnotationViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RubyAnnotationViewController.xib; sourceTree = "<group>"; };
333344
8AE7B7B219A1981E00E0C6EB /* SVProgressHUD.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SVProgressHUD.bundle; sourceTree = "<group>"; };
334345
8AE7B7B319A1981E00E0C6EB /* SVProgressHUD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVProgressHUD.h; sourceTree = "<group>"; };
335346
8AE7B7B419A1981E00E0C6EB /* SVProgressHUD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVProgressHUD.m; sourceTree = "<group>"; };
@@ -765,6 +776,18 @@
765776
name = UIAlertController;
766777
sourceTree = "<group>";
767778
};
779+
8AD104C119CB99BF00C30A3D /* RubyAnnotation */ = {
780+
isa = PBXGroup;
781+
children = (
782+
8AD104BC19CB99BA00C30A3D /* RubyAnnotationViewController.h */,
783+
8AD104BD19CB99BA00C30A3D /* RubyAnnotationViewController.m */,
784+
8AD104BE19CB99BA00C30A3D /* RubyAnnotationViewController.xib */,
785+
8ABBB65A19CBA48800F44D89 /* RubyAnnotationLabel.h */,
786+
8ABBB65B19CBA48800F44D89 /* RubyAnnotationLabel.m */,
787+
);
788+
name = RubyAnnotation;
789+
sourceTree = "<group>";
790+
};
768791
8AE7B7B119A1981E00E0C6EB /* SVProgressHUD */ = {
769792
isa = PBXGroup;
770793
children = (
@@ -799,6 +822,7 @@
799822
8A8D0CB719C9A5C0009E3448 /* MetalUniformStream */,
800823
8A9540F419A1C9EF008C6F07 /* AccordionFoldTransition */,
801824
8A8D0CF619C9CA49009E3448 /* SceneKit */,
825+
8AD104C119CB99BF00C30A3D /* RubyAnnotation */,
802826
);
803827
path = Samples;
804828
sourceTree = "<group>";
@@ -1043,6 +1067,7 @@
10431067
8A8D0C9E19C9A034009E3448 /* bgm8.wav in Resources */,
10441068
8A8D0C9F19C9A034009E3448 /* SwapRedAndGreen.cikernel in Resources */,
10451069
8A8D0CA019C9A034009E3448 /* SVProgressHUD.bundle in Resources */,
1070+
8ABBB65F19CBA7D400F44D89 /* RubyAnnotationViewController.xib in Resources */,
10461071
8A8D0CA119C9A034009E3448 /* mh2_09.wav in Resources */,
10471072
8A8D0CA219C9A034009E3448 /* MetalBasicViewController.xib in Resources */,
10481073
8A8D0CA319C9A034009E3448 /* VisualEffectsViewController.xib in Resources */,
@@ -1092,6 +1117,7 @@
10921117
8A9357A919B2F2ED00290399 /* bgm8.wav in Resources */,
10931118
8A8D0BF419C99A8A009E3448 /* SwapRedAndGreen.cikernel in Resources */,
10941119
8AE7B7B519A1981E00E0C6EB /* SVProgressHUD.bundle in Resources */,
1120+
8AD104C019CB99BA00C30A3D /* RubyAnnotationViewController.xib in Resources */,
10951121
8A9357AE19B2F2ED00290399 /* mh2_09.wav in Resources */,
10961122
8A9BA65D19C96F790015DEFB /* MetalBasicViewController.xib in Resources */,
10971123
8AAC233F19A230E300218191 /* VisualEffectsViewController.xib in Resources */,
@@ -1147,12 +1173,14 @@
11471173
8A8D0C7319C9A034009E3448 /* PopoverDetailViewController.m in Sources */,
11481174
8A8D0C7419C9A034009E3448 /* VisualEffectsViewController.m in Sources */,
11491175
8A8D0CEA19C9B1CF009E3448 /* AAPLTransforms.mm in Sources */,
1176+
8ABBB65D19CBA48800F44D89 /* RubyAnnotationLabel.m in Sources */,
11501177
8A8D0C7519C9A034009E3448 /* TTMAudioUnitEffectHelper.m in Sources */,
11511178
8A8D0C7619C9A034009E3448 /* SourceOver.m in Sources */,
11521179
8A8D0C7719C9A034009E3448 /* MetalBasicViewController.m in Sources */,
11531180
8A8D0C7819C9A034009E3448 /* CodeGeneratorViewController.m in Sources */,
11541181
8A8D0CF319C9CA45009E3448 /* SceneKitViewController.m in Sources */,
11551182
8A8D0C7919C9A034009E3448 /* UIAlertController+TTMAppearance.m in Sources */,
1183+
8ABBB65E19CBA7CF00F44D89 /* RubyAnnotationViewController.m in Sources */,
11561184
8A8D0C7A19C9A034009E3448 /* PedometerViewController.m in Sources */,
11571185
8A8D0C7B19C9A034009E3448 /* AudioEngineViewController.m in Sources */,
11581186
8A8D0C7C19C9A034009E3448 /* AlertViewController.m in Sources */,
@@ -1173,6 +1201,7 @@
11731201
8A8D244419BCD3020005B633 /* TTMHealthKitHelper.m in Sources */,
11741202
8A8D0CD119C9B163009E3448 /* MetalUniformStreamRenderer.mm in Sources */,
11751203
8AE7B7B619A1981E00E0C6EB /* SVProgressHUD.m in Sources */,
1204+
8ABBB65C19CBA48800F44D89 /* RubyAnnotationLabel.m in Sources */,
11761205
8A8D0D0419C9D6B8009E3448 /* BrowseCodeViewController.m in Sources */,
11771206
8A8D0CE119C9B1CF009E3448 /* AAPLCube.mm in Sources */,
11781207
8AE7B7C719A1999600E0C6EB /* ImageFiltersViewController.m in Sources */,
@@ -1189,6 +1218,7 @@
11891218
8A308E2A19BDD98A007C7315 /* PhotosViewController.m in Sources */,
11901219
8A308E3C19BDEFC2007C7315 /* AVKitViewController.m in Sources */,
11911220
8A95410E19A2074A008C6F07 /* MirrorX.m in Sources */,
1221+
8AD104BF19CB99BA00C30A3D /* RubyAnnotationViewController.m in Sources */,
11921222
8A8D0CBB19C9A91E009E3448 /* TTMMetalRenderer.mm in Sources */,
11931223
8A95411119A20CF8008C6F07 /* AnamorphicStretch.m in Sources */,
11941224
8A8D244C19BCFC7B0005B633 /* FontsViewController.m in Sources */,

iOS8Sampler/MasterViewController.m

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ - (void)viewDidLoad {
8686
kItemKeyDescription: @"Example for UIBlurEffect and UIVibrancyEffect.",
8787
kItemKeyClassPrefix: @"VisualEffects",
8888
},
89+
90+
// Ruby Annotation
91+
@{kItemKeyTitle: @"Ruby Annotation",
92+
kItemKeyDescription: @"Display the pronunciation of characters using CTRubyAnnotationRef.",
93+
kItemKeyClassPrefix: @"RubyAnnotation",
94+
},
8995

9096
// WebKit
9197
@{kItemKeyTitle: @"WebKit",
@@ -118,7 +124,7 @@ - (void)viewDidLoad {
118124
},
119125

120126
// Histogram
121-
@{kItemKeyTitle: @"Generate Histogram",
127+
@{kItemKeyTitle: @"Histogram",
122128
kItemKeyDescription: @"Generate a histogram from an image using the filters CIAreaHistogram and CIHistogramDisplayFilter.",
123129
kItemKeyClassPrefix: @"Histogram",
124130
},
@@ -128,7 +134,7 @@ - (void)viewDidLoad {
128134
kItemKeyDescription: @"Generate Aztec Code and 128 Barcord.",
129135
kItemKeyClassPrefix: @"CodeGenerator",
130136
},
131-
137+
132138
// New Fonts
133139
@{kItemKeyTitle: @"New Fonts",
134140
kItemKeyDescription: @"Gallery of new fonts.",
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// RubyAnnotationLabel.h
3+
// iOS8Sampler
4+
//
5+
// Created by Shuichi Tsutsumi on 2014/09/19.
6+
// Copyright (c) 2014 Shuichi Tsutsumi. All rights reserved.
7+
//
8+
// Thanks to:
9+
// http://nshipster.com/ios8/
10+
// http://dev.classmethod.jp/references/ios8-ctrubyannotationref/
11+
12+
13+
#import <UIKit/UIKit.h>
14+
15+
@interface RubyAnnotationLabel : UIView
16+
17+
- (void)setText:(NSString *)text withFurigana:(NSString *)furigana;
18+
19+
@end
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
//
2+
// RubyAnnotationLabel.m
3+
// iOS8Sampler
4+
//
5+
// Created by Shuichi Tsutsumi on 2014/09/19.
6+
// Copyright (c) 2014 Shuichi Tsutsumi. All rights reserved.
7+
//
8+
// Thanks to:
9+
// http://nshipster.com/ios8/
10+
// http://dev.classmethod.jp/references/ios8-ctrubyannotationref/
11+
12+
13+
#import "RubyAnnotationLabel.h"
14+
@import CoreText;
15+
16+
17+
@interface RubyAnnotationLabel ()
18+
@property (nonatomic, strong) NSString *text;
19+
@property (nonatomic, strong) NSString *furigana;
20+
@end
21+
22+
23+
@implementation RubyAnnotationLabel
24+
25+
- (void)drawRect:(CGRect)rect {
26+
27+
CGContextRef context = UIGraphicsGetCurrentContext();
28+
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
29+
30+
CGAffineTransform transform = CGAffineTransformMakeScale(1, -1);
31+
transform = CGAffineTransformTranslate(transform, 0, - self.bounds.size.height);
32+
33+
CGContextRef ctx = UIGraphicsGetCurrentContext();
34+
CGContextSetTextMatrix(ctx, CGAffineTransformIdentity);
35+
CGContextTranslateCTM(ctx, 0, ([self bounds]).size.height );
36+
CGContextScaleCTM(ctx, 1.0, -1.0);
37+
38+
CTLineRef line = CTLineCreateWithAttributedString([self attributedStringRef]);
39+
40+
// centering
41+
CGRect lineBounds = CTLineGetBoundsWithOptions(line, 0);
42+
CGContextSetTextPosition(context,
43+
self.center.x - lineBounds.size.width / 2,
44+
self.center.y - lineBounds.size.height / 2);
45+
46+
CTLineDraw(line, context);
47+
48+
CFRelease(line);
49+
}
50+
51+
52+
// =============================================================================
53+
#pragma mark - Private
54+
55+
// create CFAttributedStringRef
56+
- (CFAttributedStringRef)attributedStringRef {
57+
58+
// Ruby Annotation
59+
CFStringRef furiganaRef[kCTRubyPositionCount] = {
60+
(__bridge CFStringRef) self.furigana, NULL, NULL, NULL
61+
};
62+
CTRubyAnnotationRef ruby = CTRubyAnnotationCreate(kCTRubyAlignmentAuto, kCTRubyOverhangAuto, 0.5, furiganaRef);
63+
64+
// Font
65+
CTFontRef font = CTFontCreateWithName(CFSTR("HiraMinProN-W6"), 50, NULL);
66+
67+
68+
CFStringRef keys[] = { kCTFontAttributeName, kCTRubyAnnotationAttributeName};
69+
CFTypeRef values[] = { font, ruby};
70+
71+
CFDictionaryRef attr = CFDictionaryCreate(NULL,
72+
(const void **)&keys,
73+
(const void **)&values,
74+
sizeof(keys) / sizeof(keys[0]),
75+
&kCFTypeDictionaryKeyCallBacks,
76+
&kCFTypeDictionaryValueCallBacks);
77+
78+
CFAttributedStringRef attributes = CFAttributedStringCreate(NULL, (__bridge CFStringRef)self.text, attr);
79+
CFRelease(attr);
80+
81+
return attributes;
82+
}
83+
84+
85+
// =============================================================================
86+
#pragma mark - Public
87+
88+
- (void)setText:(NSString *)text withFurigana:(NSString *)furigana {
89+
90+
self.text = text;
91+
self.furigana = furigana;
92+
93+
[self setNeedsDisplay];
94+
}
95+
96+
@end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// RubyAnnotationViewController.h
3+
// iOS8Sampler
4+
//
5+
// Created by Shuichi Tsutsumi on 2014/09/19.
6+
// Copyright (c) 2014 Shuichi Tsutsumi. All rights reserved.
7+
//
8+
// Thanks to:
9+
// http://nshipster.com/ios8/
10+
// http://dev.classmethod.jp/references/ios8-ctrubyannotationref/
11+
12+
13+
#import <UIKit/UIKit.h>
14+
15+
@interface RubyAnnotationViewController : UIViewController
16+
17+
@end
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// RubyAnnotationViewController.m
3+
// iOS8Sampler
4+
//
5+
// Created by Shuichi Tsutsumi on 2014/09/19.
6+
// Copyright (c) 2014 Shuichi Tsutsumi. All rights reserved.
7+
//
8+
// Thanks to:
9+
// http://nshipster.com/ios8/
10+
// http://dev.classmethod.jp/references/ios8-ctrubyannotationref/
11+
12+
13+
#import "RubyAnnotationViewController.h"
14+
#import "RubyAnnotationLabel.h"
15+
16+
17+
@interface RubyAnnotationViewController ()
18+
@property (nonatomic, weak) IBOutlet RubyAnnotationLabel *label;
19+
@end
20+
21+
22+
@implementation RubyAnnotationViewController
23+
24+
- (void)viewDidLoad {
25+
26+
[super viewDidLoad];
27+
28+
29+
[self.label setText:@"林檎" withFurigana:@"りんご"];
30+
}
31+
32+
- (void)didReceiveMemoryWarning {
33+
[super didReceiveMemoryWarning];
34+
// Dispose of any resources that can be recreated.
35+
}
36+
37+
38+
/*
39+
#pragma mark - Navigation
40+
41+
// In a storyboard-based application, you will often want to do a little preparation before navigation
42+
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
43+
// Get the new view controller using [segue destinationViewController].
44+
// Pass the selected object to the new view controller.
45+
}
46+
*/
47+
48+
@end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6245" systemVersion="13E28" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
3+
<dependencies>
4+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6238"/>
5+
</dependencies>
6+
<objects>
7+
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RubyAnnotationViewController">
8+
<connections>
9+
<outlet property="label" destination="9jC-EE-UPY" id="MzM-Sd-G33"/>
10+
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
11+
</connections>
12+
</placeholder>
13+
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
14+
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
15+
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
16+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
17+
<subviews>
18+
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9jC-EE-UPY" customClass="RubyAnnotationLabel">
19+
<rect key="frame" x="0.0" y="64" width="320" height="500"/>
20+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
21+
</view>
22+
</subviews>
23+
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
24+
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
25+
<simulatedOrientationMetrics key="simulatedOrientationMetrics"/>
26+
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
27+
</view>
28+
</objects>
29+
</document>

0 commit comments

Comments
 (0)