├── .gitignore
├── Documents
├── Images
│ ├── Attachment.png
│ ├── Basic.png
│ ├── Image.png
│ └── Link.png
└── README.md
├── LICENSE
├── M80AttributedLabel.podspec
├── M80AttributedLabel
├── M80AttributedLabel.h
├── M80AttributedLabel.m
├── M80AttributedLabelAttachment.h
├── M80AttributedLabelAttachment.m
├── M80AttributedLabelDefines.h
├── M80AttributedLabelURL.h
├── M80AttributedLabelURL.m
├── M80AttributedLabelURLDetector.h
├── M80AttributedLabelURLDetector.m
├── NSMutableAttributedString+M80.h
└── NSMutableAttributedString+M80.m
├── OCDemo
├── Classes
│ ├── AttachmentViewController.h
│ ├── AttachmentViewController.m
│ ├── AutoLayoutTableViewCell.h
│ ├── AutoLayoutTableViewCell.m
│ ├── AutoLayoutTableViewCell.xib
│ ├── BaseLabelViewController.h
│ ├── BaseLabelViewController.m
│ ├── BasicAttributedLabelViewController.h
│ ├── BasicAttributedLabelViewController.m
│ ├── CustomTextViewController.h
│ ├── CustomTextViewController.m
│ ├── DemoTableViewController.h
│ ├── DemoTableViewController.m
│ ├── DemoTableViewController.xib
│ ├── ImagesViewController.h
│ ├── ImagesViewController.m
│ ├── LineBreakModeViewController.h
│ ├── LineBreakModeViewController.m
│ ├── LinksViewController.h
│ ├── LinksViewController.m
│ ├── LongTextViewController.h
│ ├── LongTextViewController.m
│ ├── TextAlignmentViewController.h
│ ├── TextAlignmentViewController.m
│ ├── TextTableViewController.h
│ └── TextTableViewController.m
├── OCDemo.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
├── OCDemo.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── OCDemo
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ ├── OCDemo.pch
│ └── main.m
├── Podfile
├── Podfile.lock
└── Pods
│ ├── Headers
│ ├── Private
│ │ └── M80AttributedLabel
│ │ │ ├── M80AttributedLabel.h
│ │ │ ├── M80AttributedLabelAttachment.h
│ │ │ ├── M80AttributedLabelDefines.h
│ │ │ ├── M80AttributedLabelURL.h
│ │ │ ├── M80AttributedLabelURLDetector.h
│ │ │ └── NSMutableAttributedString+M80.h
│ └── Public
│ │ └── M80AttributedLabel
│ │ ├── M80AttributedLabel.h
│ │ ├── M80AttributedLabelAttachment.h
│ │ ├── M80AttributedLabelDefines.h
│ │ ├── M80AttributedLabelURL.h
│ │ ├── M80AttributedLabelURLDetector.h
│ │ └── NSMutableAttributedString+M80.h
│ ├── Local Podspecs
│ └── M80AttributedLabel.podspec.json
│ ├── Manifest.lock
│ ├── Pods.xcodeproj
│ └── project.pbxproj
│ └── Target Support Files
│ ├── M80AttributedLabel
│ ├── M80AttributedLabel-dummy.m
│ ├── M80AttributedLabel-prefix.pch
│ └── M80AttributedLabel.xcconfig
│ └── Pods-OCDemo
│ ├── Pods-OCDemo-acknowledgements.markdown
│ ├── Pods-OCDemo-acknowledgements.plist
│ ├── Pods-OCDemo-dummy.m
│ ├── Pods-OCDemo-frameworks.sh
│ ├── Pods-OCDemo-resources.sh
│ ├── Pods-OCDemo.debug.xcconfig
│ └── Pods-OCDemo.release.xcconfig
├── README.md
├── Resource
├── avatar.png
├── haha.png
├── play@2x.png
└── test.txt
├── SwiftDemo
├── Classes
│ ├── AttachmentViewController.swift
│ ├── BaseViewController.swift
│ ├── BasicAttributedLabelViewController.swift
│ ├── CustomTextViewController.swift
│ ├── DemoTableViewController.swift
│ ├── ImagesViewController.swift
│ ├── LineBreakModeViewController.swift
│ ├── LinksViewController.swift
│ ├── LongTextViewController.swift
│ ├── SwiftDemo-Bridging-Header.h
│ ├── TextAlignmentViewController.swift
│ └── Util
│ │ └── Util.swift
├── Podfile
├── Podfile.lock
├── Pods
│ ├── Headers
│ │ ├── Private
│ │ │ └── M80AttributedLabel
│ │ │ │ ├── M80AttributedLabel.h
│ │ │ │ ├── M80AttributedLabelAttachment.h
│ │ │ │ ├── M80AttributedLabelDefines.h
│ │ │ │ ├── M80AttributedLabelURL.h
│ │ │ │ ├── M80AttributedLabelURLDetector.h
│ │ │ │ └── NSMutableAttributedString+M80.h
│ │ └── Public
│ │ │ └── M80AttributedLabel
│ │ │ ├── M80AttributedLabel.h
│ │ │ ├── M80AttributedLabelAttachment.h
│ │ │ ├── M80AttributedLabelDefines.h
│ │ │ ├── M80AttributedLabelURL.h
│ │ │ ├── M80AttributedLabelURLDetector.h
│ │ │ └── NSMutableAttributedString+M80.h
│ ├── Local Podspecs
│ │ └── M80AttributedLabel.podspec.json
│ ├── Manifest.lock
│ ├── Pods.xcodeproj
│ │ └── project.pbxproj
│ └── Target Support Files
│ │ ├── M80AttributedLabel
│ │ ├── M80AttributedLabel-dummy.m
│ │ ├── M80AttributedLabel-prefix.pch
│ │ └── M80AttributedLabel.xcconfig
│ │ └── Pods-SwiftDemo
│ │ ├── Pods-SwiftDemo-acknowledgements.markdown
│ │ ├── Pods-SwiftDemo-acknowledgements.plist
│ │ ├── Pods-SwiftDemo-dummy.m
│ │ ├── Pods-SwiftDemo-frameworks.sh
│ │ ├── Pods-SwiftDemo-resources.sh
│ │ ├── Pods-SwiftDemo.debug.xcconfig
│ │ └── Pods-SwiftDemo.release.xcconfig
├── SwiftDemo.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
├── SwiftDemo.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── SwiftDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── ViewController.swift
└── pod_push.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
--------------------------------------------------------------------------------
/Documents/Images/Attachment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangwangfeng/M80AttributedLabel/9b3431f1094f48b77e505697fb31e714fa99b830/Documents/Images/Attachment.png
--------------------------------------------------------------------------------
/Documents/Images/Basic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangwangfeng/M80AttributedLabel/9b3431f1094f48b77e505697fb31e714fa99b830/Documents/Images/Basic.png
--------------------------------------------------------------------------------
/Documents/Images/Image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangwangfeng/M80AttributedLabel/9b3431f1094f48b77e505697fb31e714fa99b830/Documents/Images/Image.png
--------------------------------------------------------------------------------
/Documents/Images/Link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangwangfeng/M80AttributedLabel/9b3431f1094f48b77e505697fb31e714fa99b830/Documents/Images/Link.png
--------------------------------------------------------------------------------
/Documents/README.md:
--------------------------------------------------------------------------------
1 | M80AttributedLabel
2 | ==================
3 |
4 |
5 | 富文本显示组件 [English Version](./../README.md)
6 |
7 |
8 | # 特性
9 | * 支持多行富文本显示
10 | * 支持链接自动检测和自定义链接添加
11 | * 支持内嵌图片和控件
12 | * 支持如下属性
13 | * `字体`
14 | * `文本颜色`
15 | * `高亮颜色`
16 | * `链接颜色`
17 | * `链接下划线`
18 | * `多行显示` (支持最后行尾部省略)
19 | * `文字对齐`
20 | * `换行模式`
21 | * `行间距`
22 | * `段落间距`
23 | * `阴影色`
24 | * `阴影偏移`
25 | * `阴影半径`
26 |
27 |
28 |
29 | # 系统要求
30 | * iOS 7.0 及以上
31 | * 需要 ARC
32 |
33 | # 集成
34 |
35 | ### Podfile
36 |
37 | ```ruby
38 | pod 'M80AttributedLabel'
39 | ```
40 |
41 | ### 手动集成
42 |
43 | * `git clone https://github.com/xiangwangfeng/M80AttributedLabel.git`
44 | * 拷贝 `Class/M80AttributedLabel` 中的源代码到你的工程中
45 | * 添加 `CoreText.framework`
46 |
47 | # 使用方法
48 |
49 | ## 基本使用
50 |
51 | ```objc
52 |
53 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
54 |
55 | label.text = @"Hello M80AttributedLabel";
56 | label.font = [UIFont fontWithName:@"Zapfino" size:25];
57 | label.textColor = M80RGB(0xFF9F00);
58 | label.shadowColor = [UIColor grayColor];
59 | label.shadowOffset= CGSizeMake(1, 1);
60 | label.shadowBlur = 1;
61 |
62 | label.frame = CGRectInset(self.view.bounds,20,20);
63 |
64 | [self.view addSubview:label];
65 |
66 | ```
67 |
68 |
69 |
70 | ## 链接
71 |
72 | ```objc
73 |
74 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
75 |
76 | NSString *text = @"The game which I current play is hearthstone,and its website is www.hearthstone.com.cn";
77 | NSRange range = [text rangeOfString:@"hearthstone"];
78 | label.text = text;
79 | [label addCustomLink:[NSValue valueWithRange:range]
80 | forRange:range];
81 | label.delegate = self;
82 |
83 | label.frame = CGRectInset(self.view.bounds,20,20);
84 |
85 | [self.view addSubview:label];
86 |
87 |
88 | ```
89 |
90 |
91 |
92 |
93 | ## 图片
94 |
95 | ```objc
96 |
97 |
98 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
99 | label.lineSpacing = 5.0;
100 |
101 | [label appendImage:[UIImage imageNamed:@"avatar"]
102 | maxSize:CGSizeMake(40, 40)
103 | margin:UIEdgeInsetsZero
104 | alignment:M80ImageAlignmentBottom];
105 |
106 | NSString *text = @"say:\n有人问一位登山家为什么要去登山——谁都知道登山这件事既危险,又没什么实际的好处。[haha][haha][haha][haha]他回答道:“因为那座山峰在那里。”我喜欢这个答案,因为里面包含着幽默感——明明是自己想要登山,偏说是山在那里使他心里痒痒。除此之外,我还喜欢这位登山家干的事,没来由地往悬崖上爬。[haha][haha][haha]它会导致肌肉疼痛,还要冒摔出脑子的危险,所以一般人尽量避免爬山。[haha][haha][haha]用热力学的角度来看,这是个反熵的现象,所发趋害避利肯定反熵。";
107 |
108 | //replace [haha] by image
109 | NSArray *components = [text componentsSeparatedByString:@"[haha]"];
110 | NSUInteger count = [components count];
111 | for (NSUInteger i = 0; i < count; i++)
112 | {
113 | [label appendText:[components objectAtIndex:i]];
114 | if (i != count - 1)
115 | {
116 | [label appendImage:[UIImage imageNamed:@"haha"]
117 | maxSize:CGSizeMake(15, 15)
118 | margin:UIEdgeInsetsZero
119 | alignment:M80ImageAlignmentCenter];
120 | }
121 | }
122 |
123 | label.frame = CGRectInset(self.view.bounds,20,20);
124 | [self.view addSubview:label];
125 |
126 |
127 | ```
128 |
129 |
130 |
131 | ## 附件
132 |
133 | ```objc
134 |
135 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
136 |
137 | for (NSInteger i = 0; i < 3; i++)
138 | {
139 | [label appendText:@"Click the icon to fire event"];
140 |
141 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
142 | button setBackgroundImage:[UIImage imageNamed:@"play"] forState:UIControlStateNormal];
143 | [button addTarget:self
144 | action:@selector(buttonClicked:)
145 | forControlEvents:UIControlEventTouchUpInside];
146 | [button setBounds:CGRectMake(0, 0, 30, 30)];
147 | [button setTag:i];
148 | [label appendView:button];
149 |
150 | [label appendText:@"\n\n\n"];
151 | }
152 |
153 |
154 | label.frame = CGRectInset(self.view.bounds,20,20);
155 | [self.view addSubview:label];
156 |
157 | ```
158 |
159 |
160 |
161 | # 联系我
162 | * https://github.com/xiangwangfeng
163 | * http://www.xiangwangfeng.com
164 | * xiangwangfeng@gmail.com
165 | * http://weibo.com/epmao
166 |
167 | [Apache]: http://www.apache.org/licenses/LICENSE-2.0
168 | [MIT]: http://www.opensource.org/licenses/mit-license.php
169 | [GPL]: http://www.gnu.org/licenses/gpl.html
170 | [BSD]: http://opensource.org/licenses/bsd-license.php
171 |
172 | # 许可证
173 |
174 | M80AttributedLabel 使用 [MIT license][MIT] 许可证,详情见 LICENSE 文件。
175 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Xiang Wangfeng (http://xiangwangfeng.com)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/M80AttributedLabel.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'M80AttributedLabel'
3 | s.version = '1.9.9'
4 | s.authors = {'Xiang Wangfeng' => 'xiangwangfeng@gmail.com'}
5 | s.homepage = 'https://github.com/xiangwangfeng/M80AttributedLabel/'
6 | s.summary = 'Another attributed label using CoreText'
7 | s.source = {:git => 'https://github.com/xiangwangfeng/M80AttributedLabel.git', :tag => s.version.to_s}
8 | s.license = 'MIT'
9 |
10 | s.requires_arc = true
11 |
12 | s.platform = :ios
13 | s.ios.deployment_target = '7.0'
14 |
15 | s.frameworks = 'CoreText', 'CoreGraphics', 'QuartzCore'
16 | s.source_files = 'M80AttributedLabel/*.{h,m}'
17 | end
18 |
--------------------------------------------------------------------------------
/M80AttributedLabel/M80AttributedLabel.h:
--------------------------------------------------------------------------------
1 | //
2 | // M80AttributedLabel.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 13-9-1.
6 | // Copyright (c) 2013年 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "M80AttributedLabelDefines.h"
10 | #import "M80AttributedLabelAttachment.h"
11 | #import "M80AttributedLabelURL.h"
12 | #import "M80AttributedLabelURLDetector.h"
13 | #import "NSMutableAttributedString+M80.h"
14 |
15 | NS_ASSUME_NONNULL_BEGIN
16 |
17 | @class M80AttributedLabelURL;
18 |
19 | @interface M80AttributedLabel : UIView
20 | @property (nonatomic,weak,nullable) id delegate;
21 | @property (nonatomic,strong,nullable) UIFont *font; //字体
22 | @property (nonatomic,strong,nullable) UIColor *textColor; //文字颜色
23 | @property (nonatomic,strong,nullable) UIColor *highlightColor; //链接点击时背景高亮色
24 | @property (nonatomic,strong,nullable) UIColor *linkColor; //链接色
25 | @property (nonatomic,strong,nullable) UIColor *shadowColor; //阴影颜色
26 | @property (nonatomic,assign) CGSize shadowOffset; //阴影offset
27 | @property (nonatomic,assign) CGFloat shadowBlur; //阴影半径
28 | @property (nonatomic,assign) BOOL underLineForLink; //链接是否带下划线
29 | @property (nonatomic,assign) BOOL autoDetectLinks; //自动检测
30 | @property (nonatomic,assign) NSInteger numberOfLines; //行数
31 | @property (nonatomic,assign) CTTextAlignment textAlignment; //文字排版样式
32 | @property (nonatomic,assign) CTLineBreakMode lineBreakMode; //LineBreakMode
33 | @property (nonatomic,assign) CGFloat lineSpacing; //行间距
34 | @property (nonatomic,assign) CGFloat paragraphSpacing; //段间距
35 | @property (nonatomic,copy,nullable) NSString *text; //普通文本
36 | @property (nonatomic,copy,nullable) NSAttributedString *attributedText; //属性文本
37 |
38 |
39 | //添加文本
40 | - (void)appendText:(NSString *)text;
41 | - (void)appendAttributedText:(NSAttributedString *)attributedText;
42 |
43 | //图片
44 | - (void)appendImage:(UIImage *)image;
45 | - (void)appendImage:(UIImage *)image
46 | maxSize:(CGSize)maxSize;
47 | - (void)appendImage:(UIImage *)image
48 | maxSize:(CGSize)maxSize
49 | margin:(UIEdgeInsets)margin;
50 | - (void)appendImage:(UIImage *)image
51 | maxSize:(CGSize)maxSize
52 | margin:(UIEdgeInsets)margin
53 | alignment:(M80ImageAlignment)alignment;
54 |
55 | //UI控件
56 | - (void)appendView:(UIView *)view;
57 | - (void)appendView:(UIView *)view
58 | margin:(UIEdgeInsets)margin;
59 | - (void)appendView:(UIView *)view
60 | margin:(UIEdgeInsets)margin
61 | alignment:(M80ImageAlignment)alignment;
62 |
63 |
64 | //添加自定义链接
65 | - (void)addCustomLink:(id)linkData
66 | forRange:(NSRange)range;
67 |
68 | - (void)addCustomLink:(id)linkData
69 | forRange:(NSRange)range
70 | linkColor:(UIColor *)color;
71 |
72 |
73 | //大小
74 | - (CGSize)sizeThatFits:(CGSize)size;
75 |
76 | @end
77 |
78 | NS_ASSUME_NONNULL_END
79 |
--------------------------------------------------------------------------------
/M80AttributedLabel/M80AttributedLabelAttachment.h:
--------------------------------------------------------------------------------
1 | //
2 | // M80AttributedLabelAttachment.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 13-8-31.
6 | // Copyright (c) 2013年 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "M80AttributedLabelDefines.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | void deallocCallback(void* ref);
14 | CGFloat ascentCallback(void *ref);
15 | CGFloat descentCallback(void *ref);
16 | CGFloat widthCallback(void* ref);
17 |
18 | @interface M80AttributedLabelAttachment : NSObject
19 | @property (nonatomic,strong) id content;
20 | @property (nonatomic,assign) UIEdgeInsets margin;
21 | @property (nonatomic,assign) M80ImageAlignment alignment;
22 | @property (nonatomic,assign) CGFloat fontAscent;
23 | @property (nonatomic,assign) CGFloat fontDescent;
24 | @property (nonatomic,assign) CGSize maxSize;
25 |
26 |
27 | + (M80AttributedLabelAttachment *)attachmentWith:(id)content
28 | margin:(UIEdgeInsets)margin
29 | alignment:(M80ImageAlignment)alignment
30 | maxSize:(CGSize)maxSize;
31 |
32 | - (CGSize)boxSize;
33 |
34 | @end
35 |
36 |
37 | NS_ASSUME_NONNULL_END
38 |
--------------------------------------------------------------------------------
/M80AttributedLabel/M80AttributedLabelAttachment.m:
--------------------------------------------------------------------------------
1 | //
2 | // M80AttributedLabelAttachment.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 13-8-31.
6 | // Copyright (c) 2013年 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "M80AttributedLabelAttachment.h"
10 |
11 | void deallocCallback(void* ref)
12 | {
13 |
14 | }
15 |
16 | CGFloat ascentCallback(void *ref)
17 | {
18 | M80AttributedLabelAttachment *image = (__bridge M80AttributedLabelAttachment *)ref;
19 | CGFloat ascent = 0;
20 | CGFloat height = [image boxSize].height;
21 | switch (image.alignment)
22 | {
23 | case M80ImageAlignmentTop:
24 | ascent = image.fontAscent;
25 | break;
26 | case M80ImageAlignmentCenter:
27 | {
28 | CGFloat fontAscent = image.fontAscent;
29 | CGFloat fontDescent = image.fontDescent;
30 | CGFloat baseLine = (fontAscent + fontDescent) / 2 - fontDescent;
31 | ascent = height / 2 + baseLine;
32 | }
33 | break;
34 | case M80ImageAlignmentBottom:
35 | ascent = height - image.fontDescent;
36 | break;
37 | default:
38 | break;
39 | }
40 | return ascent;
41 | }
42 |
43 | CGFloat descentCallback(void *ref)
44 | {
45 | M80AttributedLabelAttachment *image = (__bridge M80AttributedLabelAttachment *)ref;
46 | CGFloat descent = 0;
47 | CGFloat height = [image boxSize].height;
48 | switch (image.alignment)
49 | {
50 | case M80ImageAlignmentTop:
51 | {
52 | descent = height - image.fontAscent;
53 | break;
54 | }
55 | case M80ImageAlignmentCenter:
56 | {
57 | CGFloat fontAscent = image.fontAscent;
58 | CGFloat fontDescent = image.fontDescent;
59 | CGFloat baseLine = (fontAscent + fontDescent) / 2 - fontDescent;
60 | descent = height / 2 - baseLine;
61 | }
62 | break;
63 | case M80ImageAlignmentBottom:
64 | {
65 | descent = image.fontDescent;
66 | break;
67 | }
68 | default:
69 | break;
70 | }
71 |
72 | return descent;
73 |
74 | }
75 |
76 | CGFloat widthCallback(void* ref)
77 | {
78 | M80AttributedLabelAttachment *image = (__bridge M80AttributedLabelAttachment *)ref;
79 | return [image boxSize].width;
80 | }
81 |
82 | #pragma mark - M80AttributedLabelImage
83 | @interface M80AttributedLabelAttachment ()
84 | - (CGSize)calculateContentSize;
85 | - (CGSize)attachmentSize;
86 | @end
87 |
88 | @implementation M80AttributedLabelAttachment
89 |
90 |
91 |
92 |
93 | + (M80AttributedLabelAttachment *)attachmentWith:(id)content
94 | margin:(UIEdgeInsets)margin
95 | alignment:(M80ImageAlignment)alignment
96 | maxSize:(CGSize)maxSize
97 | {
98 | M80AttributedLabelAttachment *attachment = [[M80AttributedLabelAttachment alloc]init];
99 | attachment.content = content;
100 | attachment.margin = margin;
101 | attachment.alignment = alignment;
102 | attachment.maxSize = maxSize;
103 | return attachment;
104 | }
105 |
106 |
107 | - (CGSize)boxSize
108 | {
109 | CGSize contentSize = [self attachmentSize];
110 | if (_maxSize.width > 0 &&_maxSize.height > 0 &&
111 | contentSize.width > 0 && contentSize.height > 0)
112 | {
113 | contentSize = [self calculateContentSize];
114 | }
115 | return CGSizeMake(contentSize.width + _margin.left + _margin.right,
116 | contentSize.height+ _margin.top + _margin.bottom);
117 | }
118 |
119 |
120 | #pragma mark - 辅助方法
121 | - (CGSize)calculateContentSize
122 | {
123 | CGSize attachmentSize = [self attachmentSize];
124 | CGFloat width = attachmentSize.width;
125 | CGFloat height = attachmentSize.height;
126 | CGFloat newWidth = _maxSize.width;
127 | CGFloat newHeight = _maxSize.height;
128 | if (width <= newWidth &&
129 | height<= newHeight)
130 | {
131 | return attachmentSize;
132 | }
133 | CGSize size;
134 | if (width / height > newWidth / newHeight)
135 | {
136 | size = CGSizeMake(newWidth, newWidth * height / width);
137 | }
138 | else
139 | {
140 | size = CGSizeMake(newHeight * width / height, newHeight);
141 | }
142 | return size;
143 | }
144 |
145 | - (CGSize)attachmentSize
146 | {
147 | CGSize size = CGSizeZero;
148 | if ([_content isKindOfClass:[UIImage class]])
149 | {
150 | size = [((UIImage *)_content) size];
151 | }
152 | else if ([_content isKindOfClass:[UIView class]])
153 | {
154 | size = [((UIView *)_content) bounds].size;
155 | }
156 | return size;
157 | }
158 | @end
159 |
--------------------------------------------------------------------------------
/M80AttributedLabel/M80AttributedLabelDefines.h:
--------------------------------------------------------------------------------
1 | //
2 | // M80AttributedLabelDefines.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 13-8-31.
6 | // Copyright (c) 2013年 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #ifndef M80AttributedLabel_M80AttributedLabelDefines_h
10 | #define M80AttributedLabel_M80AttributedLabelDefines_h
11 |
12 | #import
13 | #import
14 | #import
15 |
16 | NS_ASSUME_NONNULL_BEGIN
17 |
18 | typedef NS_OPTIONS(NSUInteger, M80ImageAlignment) {
19 | M80ImageAlignmentTop,
20 | M80ImageAlignmentCenter,
21 | M80ImageAlignmentBottom
22 | };
23 |
24 | @class M80AttributedLabel;
25 |
26 | @protocol M80AttributedLabelDelegate
27 | - (void)m80AttributedLabel:(M80AttributedLabel *)label
28 | clickedOnLink:(id)linkData;
29 |
30 | @end
31 |
32 | NS_ASSUME_NONNULL_END
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/M80AttributedLabel/M80AttributedLabelURL.h:
--------------------------------------------------------------------------------
1 | //
2 | // M80AttributedLabelURL.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 13-8-31.
6 | // Copyright (c) 2013年 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "M80AttributedLabelDefines.h"
10 |
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @class M80AttributedLabelURL;
15 |
16 | @interface M80AttributedLabelURL : NSObject
17 | @property (nonatomic,strong) id linkData;
18 | @property (nonatomic,assign) NSRange range;
19 | @property (nonatomic,strong,nullable) UIColor *color;
20 |
21 | + (M80AttributedLabelURL *)urlWithLinkData:(id)linkData
22 | range:(NSRange)range
23 | color:(nullable UIColor *)color;
24 |
25 |
26 |
27 | @end
28 |
29 |
30 | NS_ASSUME_NONNULL_END
31 |
--------------------------------------------------------------------------------
/M80AttributedLabel/M80AttributedLabelURL.m:
--------------------------------------------------------------------------------
1 | //
2 | // M80AttributedLabelURL.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 13-8-31.
6 | // Copyright (c) 2013年 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "M80AttributedLabelURL.h"
10 |
11 |
12 | @implementation M80AttributedLabelURL
13 |
14 | + (M80AttributedLabelURL *)urlWithLinkData:(id)linkData
15 | range:(NSRange)range
16 | color:(UIColor *)color
17 | {
18 | M80AttributedLabelURL *url = [[M80AttributedLabelURL alloc]init];
19 | url.linkData = linkData;
20 | url.range = range;
21 | url.color = color;
22 | return url;
23 |
24 | }
25 |
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/M80AttributedLabel/M80AttributedLabelURLDetector.h:
--------------------------------------------------------------------------------
1 | //
2 | // M80AttributedLabelURLDetector.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 2019/4/2.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 | @class M80AttributedLabelURL;
12 |
13 | typedef void(^M80LinkDetectCompletion)(NSArray * _Nullable links);
14 |
15 | @protocol M80AttributedLabelCustomURLDetector
16 | - (void)detectLinks:(nullable NSString *)plainText
17 | completion:(M80LinkDetectCompletion)completion;
18 | @end
19 |
20 | @interface M80AttributedLabelURLDetector : NSObject
21 | @property (nonatomic,strong) id detector;
22 |
23 | + (instancetype)shared;
24 |
25 | - (void)detectLinks:(nullable NSString *)plainText
26 | completion:(M80LinkDetectCompletion)completion;
27 | @end
28 |
29 | NS_ASSUME_NONNULL_END
30 |
--------------------------------------------------------------------------------
/M80AttributedLabel/M80AttributedLabelURLDetector.m:
--------------------------------------------------------------------------------
1 | //
2 | // M80AttributedLabelURLDetector.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 2019/4/2.
6 | //
7 |
8 | #import "M80AttributedLabelURLDetector.h"
9 | #import "M80AttributedLabelURL.h"
10 |
11 | @implementation M80AttributedLabelURLDetector
12 | + (instancetype)shared
13 | {
14 | static M80AttributedLabelURLDetector *instance = nil;
15 | static dispatch_once_t onceToken;
16 | dispatch_once(&onceToken, ^{
17 | instance = [M80AttributedLabelURLDetector new];
18 | });
19 | return instance;
20 | }
21 |
22 | - (void)detectLinks:(nullable NSString *)plainText
23 | completion:(M80LinkDetectCompletion)completion
24 | {
25 | if (completion == nil)
26 | {
27 | return;
28 | }
29 |
30 | if (self.detector)
31 | {
32 | [self.detector detectLinks:plainText
33 | completion:completion];
34 | }
35 | else
36 | {
37 | NSMutableArray *links = nil;
38 | if ([plainText length])
39 | {
40 | links = [NSMutableArray array];
41 | NSDataDetector *detector = [self linkDetector];
42 | [detector enumerateMatchesInString:plainText
43 | options:0
44 | range:NSMakeRange(0, [plainText length])
45 | usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) {
46 | NSRange range = result.range;
47 | NSString *text = [plainText substringWithRange:range];
48 | M80AttributedLabelURL *link = [M80AttributedLabelURL urlWithLinkData:text
49 | range:range
50 | color:nil];
51 | [links addObject:link];
52 | }];
53 | }
54 | completion(links);
55 | }
56 | }
57 |
58 | - (NSDataDetector *)linkDetector
59 | {
60 | static NSString *M80LinkDetectorKey = @"M80LinkDetectorKey";
61 |
62 | NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
63 | NSDataDetector *detector = dict[M80LinkDetectorKey];
64 | if (detector == nil)
65 | {
66 | detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink | NSTextCheckingTypePhoneNumber
67 | error:nil];
68 | if (detector)
69 | {
70 | dict[M80LinkDetectorKey] = detector;
71 | }
72 | }
73 | return detector;
74 | }
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/M80AttributedLabel/NSMutableAttributedString+M80.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSMutableAttributedString+M80.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 13-8-31.
6 | // Copyright (c) 2013年 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "M80AttributedLabelDefines.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface NSMutableAttributedString (M80)
14 |
15 | - (void)m80_setTextColor:(UIColor*)color;
16 | - (void)m80_setTextColor:(UIColor*)color range:(NSRange)range;
17 |
18 | - (void)m80_setFont:(UIFont*)font;
19 | - (void)m80_setFont:(UIFont*)font range:(NSRange)range;
20 |
21 | - (void)m80_setUnderlineStyle:(CTUnderlineStyle)style
22 | modifier:(CTUnderlineStyleModifiers)modifier;
23 | - (void)m80_setUnderlineStyle:(CTUnderlineStyle)style
24 | modifier:(CTUnderlineStyleModifiers)modifier
25 | range:(NSRange)range;
26 |
27 | @end
28 |
29 | NS_ASSUME_NONNULL_END
30 |
--------------------------------------------------------------------------------
/M80AttributedLabel/NSMutableAttributedString+M80.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSMutableAttributedString+M80.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 13-8-31.
6 | // Copyright (c) 2013年 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "NSMutableAttributedString+M80.h"
10 |
11 | @implementation NSMutableAttributedString (M80)
12 |
13 | - (void)m80_setTextColor:(UIColor*)color
14 | {
15 | [self m80_setTextColor:color range:NSMakeRange(0, [self length])];
16 | }
17 |
18 | - (void)m80_setTextColor:(UIColor*)color range:(NSRange)range
19 | {
20 | [self removeAttribute:(NSString *)kCTForegroundColorAttributeName range:range];
21 | if (color.CGColor)
22 | {
23 |
24 |
25 | [self addAttribute:(NSString *)kCTForegroundColorAttributeName
26 | value:(id)color.CGColor
27 | range:range];
28 | }
29 | }
30 |
31 |
32 | - (void)m80_setFont:(UIFont*)font
33 | {
34 | [self m80_setFont:font range:NSMakeRange(0, [self length])];
35 | }
36 |
37 | - (void)m80_setFont:(UIFont*)font range:(NSRange)range
38 | {
39 | if (font)
40 | {
41 | [self removeAttribute:(NSString*)kCTFontAttributeName range:range];
42 |
43 | CTFontRef fontRef = CTFontCreateWithFontDescriptor((__bridge CTFontDescriptorRef)font.fontDescriptor, font.pointSize, nil);
44 | if (nil != fontRef)
45 | {
46 | [self addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)fontRef range:range];
47 | CFRelease(fontRef);
48 | }
49 | }
50 | }
51 |
52 | - (void)m80_setUnderlineStyle:(CTUnderlineStyle)style
53 | modifier:(CTUnderlineStyleModifiers)modifier
54 | {
55 | [self m80_setUnderlineStyle:style
56 | modifier:modifier
57 | range:NSMakeRange(0, self.length)];
58 | }
59 |
60 | - (void)m80_setUnderlineStyle:(CTUnderlineStyle)style
61 | modifier:(CTUnderlineStyleModifiers)modifier
62 | range:(NSRange)range
63 | {
64 | [self removeAttribute:(NSString *)kCTUnderlineColorAttributeName range:range];
65 | [self addAttribute:(NSString *)kCTUnderlineStyleAttributeName
66 | value:[NSNumber numberWithInt:(style|modifier)]
67 | range:range];
68 |
69 | }
70 |
71 | @end
72 |
--------------------------------------------------------------------------------
/OCDemo/Classes/AttachmentViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // AttachmentViewController.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "BaseLabelViewController.h"
10 |
11 | @interface AttachmentViewController : BaseLabelViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/OCDemo/Classes/AttachmentViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // AttachmentViewController.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "AttachmentViewController.h"
10 | #import "M80AttributedLabel.h"
11 |
12 | @interface AttachmentViewController ()
13 | @end
14 |
15 | @implementation AttachmentViewController
16 |
17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
18 | {
19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
20 | if (self) {
21 | // Custom initialization
22 | }
23 | return self;
24 | }
25 |
26 | - (void)viewDidLoad
27 | {
28 | [super viewDidLoad];
29 |
30 | self.title = @"Attachment";
31 |
32 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
33 |
34 | for (NSInteger i = 0; i < 3; i++)
35 | {
36 | [label appendText:@"Click the icon to fire event"];
37 |
38 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
39 | [button setBackgroundImage:[UIImage imageNamed:@"play"] forState:UIControlStateNormal];
40 | [button addTarget:self
41 | action:@selector(buttonClicked:)
42 | forControlEvents:UIControlEventTouchUpInside];
43 | [button setBounds:CGRectMake(0, 0, 30, 30)];
44 | [button setTag:i];
45 | [label appendView:button];
46 |
47 | [label appendText:@"\n\n\n"];
48 | }
49 |
50 |
51 |
52 | label.frame = CGRectInset(self.view.bounds,20,20);
53 | [self.view addSubview:label];
54 |
55 |
56 | }
57 |
58 | - (void)didReceiveMemoryWarning
59 | {
60 | [super didReceiveMemoryWarning];
61 | }
62 |
63 | - (void)buttonClicked:(id)sender
64 | {
65 | NSString *message = [NSString stringWithFormat:@"button tag is %zd",[(UIButton *)sender tag]];
66 |
67 | UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"you click a button"
68 | message:message
69 | preferredStyle:UIAlertControllerStyleAlert];
70 | UIAlertAction *action = [UIAlertAction actionWithTitle:@"Cancel"
71 | style:UIAlertActionStyleCancel
72 | handler:nil];
73 | [controller addAction:action];
74 | [self presentViewController:controller
75 | animated:YES
76 | completion:nil];
77 |
78 | }
79 |
80 |
81 |
82 | @end
83 |
--------------------------------------------------------------------------------
/OCDemo/Classes/AutoLayoutTableViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // AutoLayoutTableViewCell.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 9/17/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "M80AttributedLabel.h"
11 |
12 | @interface AutoLayoutTableViewCell : UITableViewCell
13 | @property (strong, nonatomic) IBOutlet M80AttributedLabel *autoLayoutLabel;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/OCDemo/Classes/AutoLayoutTableViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // AutoLayoutTableViewCell.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 9/17/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "AutoLayoutTableViewCell.h"
10 |
11 | @implementation AutoLayoutTableViewCell
12 |
13 | - (void)awakeFromNib {
14 | [super awakeFromNib];
15 | }
16 |
17 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
18 | [super setSelected:selected animated:animated];
19 |
20 | // Configure the view for the selected state
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/OCDemo/Classes/AutoLayoutTableViewCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/OCDemo/Classes/BaseLabelViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // BaseLabelViewController.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface BaseLabelViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/OCDemo/Classes/BaseLabelViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // BaseLabelViewController.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "BaseLabelViewController.h"
10 |
11 | @interface BaseLabelViewController ()
12 |
13 | @end
14 |
15 | @implementation BaseLabelViewController
16 |
17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
18 | {
19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
20 | if (self) {
21 | // Custom initialization
22 | }
23 | return self;
24 | }
25 |
26 | - (void)viewDidLoad
27 | {
28 | [super viewDidLoad];
29 |
30 | if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {
31 | self.edgesForExtendedLayout = UIRectEdgeNone;
32 | }
33 | self.view.backgroundColor = [UIColor whiteColor];
34 | }
35 |
36 | - (void)didReceiveMemoryWarning
37 | {
38 | [super didReceiveMemoryWarning];
39 | // Dispose of any resources that can be recreated.
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/OCDemo/Classes/BasicAttributedLabelViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // BasicAttributedLabelViewController.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "BaseLabelViewController.h"
11 |
12 | @interface BasicAttributedLabelViewController : BaseLabelViewController
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/OCDemo/Classes/BasicAttributedLabelViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // BasicAttributedLabelViewController.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "BasicAttributedLabelViewController.h"
10 | #import "M80AttributedLabel.h"
11 |
12 | @interface BasicAttributedLabelViewController ()
13 |
14 | @end
15 |
16 | @implementation BasicAttributedLabelViewController
17 |
18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
19 | {
20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
21 | if (self) {
22 |
23 | }
24 | return self;
25 | }
26 |
27 | - (void)viewDidLoad
28 | {
29 | [super viewDidLoad];
30 |
31 | self.title = @"Basic";
32 |
33 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
34 |
35 | label.text = @"Hello M80AttributedLabel";
36 | label.font = [UIFont fontWithName:@"Zapfino" size:25];
37 | label.textColor = M80RGB(0xFF9F00);
38 | label.shadowColor = [UIColor grayColor];
39 | label.shadowOffset= CGSizeMake(1, 1);
40 | label.shadowBlur = 1;
41 |
42 | label.frame = CGRectInset(self.view.bounds,20,20);
43 |
44 | [self.view addSubview:label];
45 | }
46 |
47 | - (void)didReceiveMemoryWarning
48 | {
49 | [super didReceiveMemoryWarning];
50 | }
51 |
52 |
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/OCDemo/Classes/CustomTextViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CustomTextViewController.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "BaseLabelViewController.h"
10 |
11 | @interface CustomTextViewController : BaseLabelViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/OCDemo/Classes/CustomTextViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CustomTextViewController.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "CustomTextViewController.h"
10 | #import "M80AttributedLabel.h"
11 |
12 | @interface CustomTextViewController ()
13 |
14 | @end
15 |
16 | @implementation CustomTextViewController
17 |
18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
19 | {
20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
21 | if (self) {
22 | // Custom initialization
23 | }
24 | return self;
25 | }
26 |
27 | - (void)viewDidLoad
28 | {
29 | [super viewDidLoad];
30 |
31 | self.title = @"Custom Text";
32 |
33 | NSArray *fonts = @[[UIFont systemFontOfSize:12],[UIFont systemFontOfSize:13],[UIFont systemFontOfSize:17],[UIFont systemFontOfSize:25]];
34 | NSArray *colors= @[M80RGB(0x000000),M80RGB(0x0000FF),M80RGB(0x00FF00),M80RGB(0xFF0000)];
35 |
36 |
37 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
38 |
39 | NSString *plainText = @"The release of iOS 7 brings a lot of new tools to the table for developers.";
40 | NSArray *components = [plainText componentsSeparatedByString:@" "];
41 | for (NSString *text in components)
42 | {
43 | NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc]initWithString:text];
44 | NSInteger index = arc4random() % 4;
45 | [attributedText m80_setFont:[fonts objectAtIndex:index]];
46 | [attributedText m80_setTextColor:[colors objectAtIndex:index]];
47 |
48 | [label appendAttributedText:attributedText];
49 | [label appendText:@" "];
50 | }
51 | label.frame = CGRectInset(self.view.bounds,20,20);
52 |
53 | [self.view addSubview:label];
54 |
55 | }
56 |
57 | - (void)didReceiveMemoryWarning
58 | {
59 | [super didReceiveMemoryWarning];
60 | // Dispose of any resources that can be recreated.
61 | }
62 |
63 | @end
64 |
--------------------------------------------------------------------------------
/OCDemo/Classes/DemoTableViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoTableViewController.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 4/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DemoTableViewController : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/OCDemo/Classes/DemoTableViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoTableViewController.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 4/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "DemoTableViewController.h"
10 |
11 | @interface TableItem : NSObject
12 | @property (nonatomic,strong) NSString *title;
13 | @property (nonatomic,strong) NSString *subTitle;
14 | @property (nonatomic,strong) NSString *vcName;
15 | @end
16 |
17 | @implementation TableItem
18 | + (TableItem *)itemWithTitle:(NSString *)title
19 | subTitle:(NSString *)subTitle
20 | vcName:(NSString *)vcName
21 | {
22 | TableItem *instance = [[TableItem alloc]init];
23 | instance.title = title;
24 | instance.subTitle = subTitle;
25 | instance.vcName= vcName;
26 | return instance;
27 | }
28 | @end
29 |
30 | @interface DemoTableViewController ()
31 | @property (nonatomic,strong) NSArray *items;
32 | @end
33 |
34 | @implementation DemoTableViewController
35 |
36 | - (void)viewDidLoad
37 | {
38 | [super viewDidLoad];
39 |
40 | self.title = @"Demo";
41 | self.navigationController.view.backgroundColor = [UIColor whiteColor];
42 |
43 | _items = @[[TableItem itemWithTitle:@"Basic"
44 | subTitle:@"How to create a simple M80AttributedLabel"
45 | vcName:@"BasicAttributedLabelViewController"],
46 |
47 |
48 | [TableItem itemWithTitle:@"Customizing Text"
49 | subTitle:@"How to use NSAttributedString"
50 | vcName:@"CustomTextViewController"],
51 |
52 | [TableItem itemWithTitle:@"Links"
53 | subTitle:@"Automatic and explicit Links"
54 | vcName:@"LinksViewController"],
55 |
56 | [TableItem itemWithTitle:@"Images"
57 | subTitle:@"How to display images using M80AttributedLabel"
58 | vcName:@"ImagesViewController"],
59 |
60 | [TableItem itemWithTitle:@"LongText"
61 | subTitle:@"Performance for displaying long text"
62 | vcName:@"LongTextViewController"],
63 |
64 | [TableItem itemWithTitle:@"Attachment"
65 | subTitle:@"Add UIView as attachment instead of UIImage"
66 | vcName:@"AttachmentViewController"],
67 |
68 | [TableItem itemWithTitle:@"LineBreakMode"
69 | subTitle:@"Different line break modes"
70 | vcName:@"LineBreakModeViewController"],
71 |
72 | [TableItem itemWithTitle:@"TextAlignment"
73 | subTitle:@"Different test alignments"
74 | vcName:@"TextAlignmentViewController"],
75 |
76 | [TableItem itemWithTitle:@"TableViewCell"
77 | subTitle:@"AttributedLabel in tableviewcell"
78 | vcName:@"TextTableViewController"],
79 |
80 | ];
81 | }
82 |
83 | - (void)didReceiveMemoryWarning
84 | {
85 | [super didReceiveMemoryWarning];
86 | }
87 |
88 | #pragma mark - Table view data source
89 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
90 | {
91 | return 1;
92 | }
93 |
94 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
95 | {
96 | return [_items count];
97 | }
98 |
99 |
100 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
101 | {
102 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"test_demo_cell"];
103 | if (cell == nil)
104 | {
105 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle
106 | reuseIdentifier:@"test_demo_cell"];
107 | }
108 | TableItem *item = [_items objectAtIndex:[indexPath row]];
109 | cell.textLabel.text = item.title;
110 | cell.detailTextLabel.text = item.subTitle;
111 | return cell;
112 | }
113 |
114 |
115 |
116 | #pragma mark - Table view delegate
117 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
118 | {
119 |
120 | TableItem *item = [_items objectAtIndex:[indexPath row]];
121 | NSString *vcName= [item vcName];
122 | UIViewController *controller = [[NSClassFromString(vcName) alloc] init];
123 | controller.title = [item title];
124 | [self.navigationController pushViewController:controller animated:YES];
125 | }
126 |
127 |
128 | @end
129 |
--------------------------------------------------------------------------------
/OCDemo/Classes/DemoTableViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/OCDemo/Classes/ImagesViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ImagesViewController.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "BaseLabelViewController.h"
10 |
11 | @interface ImagesViewController : BaseLabelViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/OCDemo/Classes/ImagesViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImagesViewController.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "ImagesViewController.h"
10 | #import "M80AttributedLabel.h"
11 |
12 | @interface ImagesViewController ()
13 |
14 | @end
15 |
16 | @implementation ImagesViewController
17 |
18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
19 | {
20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
21 | if (self) {
22 | // Custom initialization
23 | }
24 | return self;
25 | }
26 |
27 | - (void)viewDidLoad
28 | {
29 | [super viewDidLoad];
30 |
31 | self.title = @"Images";
32 |
33 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
34 | label.lineSpacing = 5.0;
35 |
36 | [label appendImage:[UIImage imageNamed:@"avatar"
37 | ] maxSize:CGSizeMake(40, 40)
38 | margin:UIEdgeInsetsZero
39 | alignment:M80ImageAlignmentBottom];
40 |
41 | NSString *text = @"say:\n有人问一位登山家为什么要去登山——谁都知道登山这件事既危险,又没什么实际的好处。[haha][haha][haha][haha]他回答道:“因为那座山峰在那里。”我喜欢这个答案,因为里面包含着幽默感——明明是自己想要登山,偏说是山在那里使他心里痒痒。除此之外,我还喜欢这位登山家干的事,没来由地往悬崖上爬。[haha][haha][haha]它会导致肌肉疼痛,还要冒摔出脑子的危险,所以一般人尽量避免爬山。[haha][haha][haha]用热力学的角度来看,这是个反熵的现象,所发趋害避利肯定反熵。";
42 |
43 | //replace [haha] by image
44 | NSArray *components = [text componentsSeparatedByString:@"[haha]"];
45 | NSUInteger count = [components count];
46 | for (NSUInteger i = 0; i < count; i++)
47 | {
48 | [label appendText:[components objectAtIndex:i]];
49 | if (i != count - 1)
50 | {
51 | [label appendImage:[UIImage imageNamed:@"haha"]
52 | maxSize:CGSizeMake(15, 15)
53 | margin:UIEdgeInsetsZero
54 | alignment:M80ImageAlignmentCenter];
55 | }
56 | }
57 |
58 |
59 | label.frame = CGRectInset(self.view.bounds,20,20);
60 |
61 | [self.view addSubview:label];
62 | }
63 |
64 | - (void)didReceiveMemoryWarning
65 | {
66 | [super didReceiveMemoryWarning];
67 | // Dispose of any resources that can be recreated.
68 | }
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/OCDemo/Classes/LineBreakModeViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LineBreakModeViewController.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "BaseLabelViewController.h"
10 |
11 | @interface LineBreakModeViewController : BaseLabelViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/OCDemo/Classes/LineBreakModeViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LineBreakModeViewController.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "LineBreakModeViewController.h"
10 | #import "M80AttributedLabel.h"
11 |
12 | @interface LineBreakModeViewController ()
13 |
14 | @end
15 |
16 | @implementation LineBreakModeViewController
17 |
18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
19 | {
20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
21 | if (self) {
22 | // Custom initialization
23 | }
24 | return self;
25 | }
26 |
27 | - (void)viewDidLoad
28 | {
29 | [super viewDidLoad];
30 |
31 | /*
32 | kCTLineBreakByWordWrapping = 0,
33 | kCTLineBreakByCharWrapping = 1,
34 | kCTLineBreakByClipping = 2,
35 | kCTLineBreakByTruncatingHead = 3,
36 | kCTLineBreakByTruncatingTail = 4,
37 | kCTLineBreakByTruncatingMiddle = 5*/
38 |
39 | self.title = @"LineBreakMode";
40 |
41 | NSString *textMoreThanTwoLines = @"有关美国的一切,可以用一句话来描述:“Americans business is business”,这句话的意思就是说,那个国家永远是在经商热中,而且永远是一千度的白热。所以你要是看了前文之后以为那里有某种气氛会有助于人立志写作就错了。连我哥哥到了那里都后悔了,觉得不该学逻辑,应当学商科或者计算机。虽然他依旧未证出的逻辑定理,但是看到有钱人豪华的住房,也免不了唠叨几句他对妻儿的责任。";
42 |
43 | for (NSUInteger i = kCTLineBreakByWordWrapping;
44 | i <= kCTLineBreakByTruncatingMiddle;i++)
45 | {
46 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
47 | label.text = textMoreThanTwoLines;
48 | [label setLineBreakMode:i];
49 | [label setNumberOfLines:2];
50 | [label setFrame:CGRectMake(20, 20 + i * 60, self.view.bounds.size.width - 20 * 2, 50)];
51 |
52 | [label.layer setBorderColor:[UIColor orangeColor].CGColor];
53 | [label.layer setBorderWidth:1];
54 |
55 | [self.view addSubview:label];
56 |
57 |
58 | }
59 | }
60 |
61 | - (void)didReceiveMemoryWarning
62 | {
63 | [super didReceiveMemoryWarning];
64 | // Dispose of any resources that can be recreated.
65 | }
66 |
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/OCDemo/Classes/LinksViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LinksViewController.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "BaseLabelViewController.h"
10 |
11 | @interface LinksViewController : BaseLabelViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/OCDemo/Classes/LinksViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LinksViewController.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "LinksViewController.h"
10 | #import "M80AttributedLabel.h"
11 |
12 |
13 | @interface LinksViewController ()
14 |
15 | @end
16 |
17 | @implementation LinksViewController
18 |
19 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
20 | {
21 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
22 | if (self) {
23 | // Custom initialization
24 | }
25 | return self;
26 | }
27 |
28 | - (void)viewDidLoad
29 | {
30 | [super viewDidLoad];
31 |
32 | self.title = @"Links";
33 |
34 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
35 |
36 | NSString *text = @"The game which I current play is hearthstone,and its website is www.hearthstone.com.cn";
37 | NSRange range = [text rangeOfString:@"hearthstone"];
38 | label.text = text;
39 | [label addCustomLink:[NSValue valueWithRange:range]
40 | forRange:range];
41 | label.delegate = self;
42 |
43 |
44 | label.frame = CGRectInset(self.view.bounds,20,20);
45 |
46 | [self.view addSubview:label];
47 |
48 | }
49 |
50 | - (void)m80AttributedLabel:(M80AttributedLabel *)label
51 | clickedOnLink:(id)linkData
52 | {
53 | NSString *message = [NSString stringWithFormat:@"link data is %@:%@",[[linkData class] description],linkData];
54 |
55 | UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"you click a link"
56 | message:message
57 | preferredStyle:UIAlertControllerStyleAlert];
58 | UIAlertAction *action = [UIAlertAction actionWithTitle:@"Cancel"
59 | style:UIAlertActionStyleCancel
60 | handler:nil];
61 | [controller addAction:action];
62 | [self presentViewController:controller
63 | animated:YES
64 | completion:nil];
65 | }
66 |
67 | - (void)didReceiveMemoryWarning
68 | {
69 | [super didReceiveMemoryWarning];
70 | // Dispose of any resources that can be recreated.
71 | }
72 |
73 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
74 | {
75 | NSLog(@"touch view controller");
76 | }
77 | @end
78 |
--------------------------------------------------------------------------------
/OCDemo/Classes/LongTextViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LongTextViewController.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "BaseLabelViewController.h"
10 |
11 | @interface LongTextViewController : BaseLabelViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/OCDemo/Classes/LongTextViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LongTextViewController.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "LongTextViewController.h"
10 | #import "M80AttributedLabel.h"
11 |
12 |
13 |
14 | @interface LongTextViewController ()
15 |
16 | @end
17 |
18 | @implementation LongTextViewController
19 |
20 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
21 | {
22 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
23 | if (self) {
24 | // Custom initialization
25 | }
26 | return self;
27 | }
28 |
29 | - (void)viewDidLoad
30 | {
31 | [super viewDidLoad];
32 |
33 | self.title = @"LongText";
34 |
35 | NSString *path = [[NSBundle mainBundle] pathForResource:@"test"
36 | ofType:@"txt"];
37 | NSString *content = [NSString stringWithContentsOfFile:path
38 | encoding:NSUTF8StringEncoding
39 | error:nil];
40 |
41 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
42 | label.lineSpacing = 5.0;
43 | label.paragraphSpacing = 10.0;
44 | label.text = content;
45 |
46 | UIScrollView *scrollView = [[UIScrollView alloc]initWithFrame:self.view.bounds];
47 | scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
48 |
49 | [scrollView addSubview:label];
50 | [self.view addSubview:scrollView];
51 |
52 | CGSize labelSize = [label sizeThatFits:CGSizeMake(CGRectGetWidth(self.view.bounds) - 40, CGFLOAT_MAX)];
53 | [label setFrame:CGRectMake(20, 10, labelSize.width, labelSize.height)];
54 | scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.view.bounds), labelSize.height + 20);
55 |
56 | }
57 |
58 | - (void)didReceiveMemoryWarning
59 | {
60 | [super didReceiveMemoryWarning];
61 |
62 | }
63 |
64 | /*
65 | #pragma mark - Navigation
66 |
67 | // In a storyboard-based application, you will often want to do a little preparation before navigation
68 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
69 | {
70 | // Get the new view controller using [segue destinationViewController].
71 | // Pass the selected object to the new view controller.
72 | }
73 | */
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/OCDemo/Classes/TextAlignmentViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TextAlignmentViewController.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "BaseLabelViewController.h"
10 |
11 | @interface TextAlignmentViewController : BaseLabelViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/OCDemo/Classes/TextAlignmentViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TextAlignmentViewController.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 5/21/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "TextAlignmentViewController.h"
10 | #import "M80AttributedLabel.h"
11 |
12 | @interface TextAlignmentViewController ()
13 |
14 | @end
15 |
16 | @implementation TextAlignmentViewController
17 |
18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
19 | {
20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
21 | if (self) {
22 | // Custom initialization
23 | }
24 | return self;
25 | }
26 |
27 | - (void)viewDidLoad
28 | {
29 | [super viewDidLoad];
30 |
31 | /*
32 | kCTTextAlignmentLeft = 0,
33 | kCTTextAlignmentRight = 1,
34 | kCTTextAlignmentCenter = 2,
35 | kCTTextAlignmentJustified = 3,
36 | kCTTextAlignmentNatural = 4,*/
37 |
38 | self.title = @"TextAlignment";
39 |
40 |
41 | NSString *text = @"Hello M80AttributedLabel";
42 |
43 | for (NSUInteger i = kCTTextAlignmentLeft;
44 | i <= kCTTextAlignmentNatural;i++)
45 | {
46 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
47 | label.text = text;
48 | [label setTextAlignment:i];
49 | [label setFrame:CGRectMake(20, 20 + i * 60, 280, 25)];
50 |
51 | [label.layer setBorderColor:[UIColor orangeColor].CGColor];
52 | [label.layer setBorderWidth:1];
53 |
54 | [self.view addSubview:label];
55 |
56 |
57 | }
58 |
59 | }
60 |
61 | - (void)didReceiveMemoryWarning
62 | {
63 | [super didReceiveMemoryWarning];
64 | // Dispose of any resources that can be recreated.
65 | }
66 |
67 | /*
68 | #pragma mark - Navigation
69 |
70 | // In a storyboard-based application, you will often want to do a little preparation before navigation
71 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
72 | {
73 | // Get the new view controller using [segue destinationViewController].
74 | // Pass the selected object to the new view controller.
75 | }
76 | */
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/OCDemo/Classes/TextTableViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TextTableViewController.h
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 7/10/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TextTableViewController : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/OCDemo/Classes/TextTableViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TextTableViewController.m
3 | // M80AttributedLabel
4 | //
5 | // Created by amao on 7/10/14.
6 | // Copyright (c) 2014 www.xiangwangfeng.com. All rights reserved.
7 | //
8 |
9 | #import "TextTableViewController.h"
10 | #import "M80AttributedLabel.h"
11 | #import "AutoLayoutTableViewCell.h"
12 |
13 | static dispatch_queue_t shared_queue()
14 | {
15 | static dispatch_queue_t queue = NULL;
16 | if (queue == NULL)
17 | {
18 | queue = dispatch_queue_create("data_source_queue", 0);
19 | }
20 | return queue;
21 | }
22 |
23 |
24 |
25 | @interface Messsage : NSObject
26 | @property (nonatomic,strong) NSString *messageID;
27 | @property (nonatomic,strong) NSString *text;
28 | @property (nonatomic,assign) BOOL autoLayout;
29 | @end
30 |
31 | @implementation Messsage
32 | + (Messsage *)message
33 | {
34 | Messsage *message = [[Messsage alloc]init];
35 | message.messageID = [[NSUUID UUID] UUIDString];
36 | message.text = [Messsage ramdomText];
37 | message.autoLayout= arc4random() % 2 == 0;
38 | return message;
39 | }
40 |
41 | + (NSString *)ramdomText
42 | {
43 | static NSArray *messages = nil;
44 |
45 | if (messages == nil)
46 | {
47 | NSString *path = [[NSBundle mainBundle] pathForResource:@"test"
48 | ofType:@"txt"];
49 | NSString *content = [[NSString alloc] initWithContentsOfFile:path
50 | encoding:NSUTF8StringEncoding
51 | error:nil];
52 | NSArray *contentLines = [content componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
53 |
54 |
55 | NSMutableArray *tempMessages = [NSMutableArray array];
56 | for (NSInteger i = 0; i < 100; i++)
57 | {
58 | NSMutableString *str = [[NSMutableString alloc]init];
59 | [str appendString:@"M80 says:[haha] [haha] Your magic is Mine.[haha] [haha]"];
60 | NSInteger line = random() % [contentLines count];
61 | for (NSInteger j = 0; j < random() % 3; j++)
62 | {
63 | [str appendString:[contentLines objectAtIndex:line]];
64 | }
65 | [tempMessages addObject:str];
66 | messages = tempMessages;
67 | }
68 | }
69 | NSInteger count = arc4random() % 100;
70 | return [messages objectAtIndex:count];
71 | }
72 | @end
73 |
74 |
75 | @interface TextTableViewController ()
76 | @property (nonatomic,strong) NSMutableArray *messages;
77 | @property (nonatomic,strong) NSMutableDictionary *cellHeights;
78 | @end
79 |
80 | @implementation TextTableViewController
81 |
82 | - (id)initWithStyle:(UITableViewStyle)style
83 | {
84 | self = [super initWithStyle:style];
85 | if (self) {
86 | // Custom initialization
87 | }
88 | return self;
89 | }
90 |
91 | - (void)viewDidLoad
92 | {
93 | [super viewDidLoad];
94 |
95 | self.refreshControl = [[UIRefreshControl alloc]init];
96 | [self.tableView addSubview:self.refreshControl];
97 | [self.refreshControl addTarget:self
98 | action:@selector(onRefresh:)
99 | forControlEvents:UIControlEventValueChanged];
100 |
101 | _messages = [NSMutableArray array];
102 | _cellHeights = [NSMutableDictionary dictionary];
103 |
104 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"Reload"
105 | style:UIBarButtonItemStyleDone
106 | target:self
107 | action:@selector(onReload:)];
108 | }
109 |
110 | - (void)didReceiveMemoryWarning
111 | {
112 | [super didReceiveMemoryWarning];
113 | // Dispose of any resources that can be recreated.
114 | }
115 |
116 | - (void)onRefresh:(id)sender
117 | {
118 | dispatch_async(shared_queue(), ^{
119 | NSMutableArray *messages = [NSMutableArray array];
120 | for (NSInteger i = 0; i < 200; i++)
121 | {
122 | Messsage *message = [Messsage message];
123 | [messages addObject:message];
124 | }
125 | dispatch_async(dispatch_get_main_queue(), ^{
126 | [self.messages insertObjects:messages
127 | atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [messages count])]];
128 | [self.refreshControl endRefreshing];
129 | [self.tableView reloadData];
130 | });
131 | });
132 | }
133 |
134 | - (void)onReload:(id)sender
135 | {
136 | NSLog(@"begin reload");
137 | [self.tableView reloadData];
138 | NSLog(@"end reload %lu",(unsigned long)[_messages count]);
139 | }
140 |
141 | #pragma mark - Table view Helper
142 | - (CGFloat)cellHeight:(Messsage *)message
143 | {
144 | NSString *messageID = message.messageID;
145 | CGFloat height = [[_cellHeights objectForKey:messageID] floatValue];
146 | if (height == 0)
147 | {
148 | if (message.autoLayout)
149 | {
150 | AutoLayoutTableViewCell *cell = [[[NSBundle mainBundle] loadNibNamed:@"AutoLayoutTableViewCell"
151 | owner:nil
152 | options:nil] lastObject];
153 | [self updateLabel:cell.autoLayoutLabel
154 | text:message.text];
155 | CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
156 | height = size.height + 1;
157 | }
158 | else
159 | {
160 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
161 | [self updateLabel:label
162 | text:message.text];
163 | CGSize size = [label sizeThatFits:CGSizeMake(self.view.bounds.size.width, CGFLOAT_MAX)];
164 | height = size.height + 20 + 20;
165 | }
166 | [_cellHeights setObject:@(height)
167 | forKey:messageID];
168 | }
169 | return height;
170 | }
171 |
172 |
173 | - (void)updateLabel:(M80AttributedLabel *)label
174 | text:(NSString *)text
175 | {
176 | [label setText:@""];
177 |
178 | NSArray *components = [text componentsSeparatedByString:@"[haha]"];
179 | NSUInteger count = [components count];
180 | for (NSUInteger i = 0; i < count; i++)
181 | {
182 | [label appendText:[components objectAtIndex:i]];
183 | if (i != count - 1)
184 | {
185 | [label appendImage:[UIImage imageNamed:@"haha"]
186 | maxSize:CGSizeMake(13, 13)
187 | margin:UIEdgeInsetsZero
188 | alignment:M80ImageAlignmentCenter];
189 | }
190 | }
191 |
192 |
193 | }
194 |
195 | #pragma mark - Table view data source
196 |
197 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
198 | {
199 | return 1;
200 | }
201 |
202 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
203 | {
204 | return [_messages count];
205 | }
206 |
207 | static const NSInteger labelTag = 10;
208 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
209 | {
210 | Messsage *message = [_messages objectAtIndex:[indexPath row]];
211 | if (message.autoLayout)
212 | {
213 | AutoLayoutTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"auto_message_cell"];
214 | if (cell == nil)
215 | {
216 | cell = [[[NSBundle mainBundle] loadNibNamed:@"AutoLayoutTableViewCell"
217 | owner:nil
218 | options:nil] lastObject];
219 | }
220 | [self updateLabel:cell.autoLayoutLabel
221 | text:message.text];
222 | return cell;
223 | }
224 | else
225 | {
226 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"message_cell"];
227 | if (cell == nil)
228 | {
229 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
230 | reuseIdentifier:@"message_cell"];
231 | M80AttributedLabel *label = [[M80AttributedLabel alloc] initWithFrame:CGRectZero];
232 | [cell.contentView addSubview:label];
233 | [label setTag:labelTag];
234 | }
235 | M80AttributedLabel *label = (M80AttributedLabel *)[cell viewWithTag:labelTag];
236 | [self updateLabel:label
237 | text:message.text];
238 | return cell;
239 | }
240 | }
241 |
242 | - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
243 | {
244 | Messsage *message = [_messages objectAtIndex:[indexPath row]];
245 | if (!message.autoLayout)
246 | {
247 | M80AttributedLabel *label = (M80AttributedLabel *)[cell viewWithTag:labelTag];
248 | [label setFrame:CGRectMake(25, 20, cell.bounds.size.width - 25 * 2, cell.bounds.size.height - 20 * 2)];
249 | }
250 | }
251 |
252 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
253 | {
254 | Messsage *message = [_messages objectAtIndex:[indexPath row]];
255 | return [self cellHeight:message];
256 | }
257 |
258 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
259 | {
260 | Messsage *message = [_messages objectAtIndex:[indexPath row]];
261 |
262 | UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"what you select is "
263 | message:message.text
264 | preferredStyle:UIAlertControllerStyleAlert];
265 | UIAlertAction *action = [UIAlertAction actionWithTitle:@"Cancel"
266 | style:UIAlertActionStyleCancel
267 | handler:nil];
268 | [controller addAction:action];
269 | [self presentViewController:controller
270 | animated:YES
271 | completion:nil];
272 | }
273 |
274 |
275 |
276 | @end
277 |
--------------------------------------------------------------------------------
/OCDemo/OCDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/OCDemo/OCDemo.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/OCDemo/OCDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/OCDemo/OCDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // OCDemo
4 | //
5 | // Created by amao on 2016/10/12.
6 | // Copyright © 2016年 NetEase. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/OCDemo/OCDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // OCDemo
4 | //
5 | // Created by amao on 2016/10/12.
6 | // Copyright © 2016年 NetEase. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "DemoTableViewController.h"
11 |
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 |
19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
20 |
21 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
22 | DemoTableViewController *demoVC = [[DemoTableViewController alloc]init];
23 | UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:demoVC];
24 | self.window.rootViewController = nav;
25 | [self.window makeKeyAndVisible];
26 |
27 | return YES;
28 | }
29 |
30 |
31 | - (void)applicationWillResignActive:(UIApplication *)application {
32 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
33 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
34 | }
35 |
36 |
37 | - (void)applicationDidEnterBackground:(UIApplication *)application {
38 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
39 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
40 | }
41 |
42 |
43 | - (void)applicationWillEnterForeground:(UIApplication *)application {
44 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
45 | }
46 |
47 |
48 | - (void)applicationDidBecomeActive:(UIApplication *)application {
49 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
50 | }
51 |
52 |
53 | - (void)applicationWillTerminate:(UIApplication *)application {
54 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
55 | }
56 |
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/OCDemo/OCDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | }
43 | ],
44 | "info" : {
45 | "version" : 1,
46 | "author" : "xcode"
47 | }
48 | }
--------------------------------------------------------------------------------
/OCDemo/OCDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/OCDemo/OCDemo/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/OCDemo/OCDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/OCDemo/OCDemo/OCDemo.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'M80AttributedLabel' target in the 'M80AttributedLabel' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_4_0
8 | #warning "This project uses features only available in iOS SDK 4.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
16 |
17 | #define M80RGB(rgbValue) [UIColor \
18 | colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
19 | green:((float)((rgbValue & 0x00FF00) >> 8))/255.0 \
20 | blue:((float)(rgbValue & 0x0000FF))/255.0 \
21 | alpha:1.0]
22 |
--------------------------------------------------------------------------------
/OCDemo/OCDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // OCDemo
4 | //
5 | // Created by amao on 2016/10/12.
6 | // Copyright © 2016年 NetEase. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/OCDemo/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | target 'OCDemo' do
5 | pod 'M80AttributedLabel', :path => '../'
6 |
7 | end
8 |
--------------------------------------------------------------------------------
/OCDemo/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - M80AttributedLabel (1.9.3)
3 |
4 | DEPENDENCIES:
5 | - M80AttributedLabel (from `../`)
6 |
7 | EXTERNAL SOURCES:
8 | M80AttributedLabel:
9 | :path: "../"
10 |
11 | SPEC CHECKSUMS:
12 | M80AttributedLabel: 362643e3ed8d4c53d779eb8fe74f0ee70432c948
13 |
14 | PODFILE CHECKSUM: c204fac8364187b2bd67bb03850fcbcaad8bfd33
15 |
16 | COCOAPODS: 1.7.0.beta.2
17 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Private/M80AttributedLabel/M80AttributedLabel.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabel.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Private/M80AttributedLabel/M80AttributedLabelAttachment.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelAttachment.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Private/M80AttributedLabel/M80AttributedLabelDefines.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelDefines.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Private/M80AttributedLabel/M80AttributedLabelURL.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelURL.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Private/M80AttributedLabel/M80AttributedLabelURLDetector.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelURLDetector.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Private/M80AttributedLabel/NSMutableAttributedString+M80.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/NSMutableAttributedString+M80.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Public/M80AttributedLabel/M80AttributedLabel.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabel.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Public/M80AttributedLabel/M80AttributedLabelAttachment.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelAttachment.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Public/M80AttributedLabel/M80AttributedLabelDefines.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelDefines.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Public/M80AttributedLabel/M80AttributedLabelURL.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelURL.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Public/M80AttributedLabel/M80AttributedLabelURLDetector.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelURLDetector.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Headers/Public/M80AttributedLabel/NSMutableAttributedString+M80.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/NSMutableAttributedString+M80.h
--------------------------------------------------------------------------------
/OCDemo/Pods/Local Podspecs/M80AttributedLabel.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "M80AttributedLabel",
3 | "version": "1.9.3",
4 | "authors": {
5 | "Xiang Wangfeng": "xiangwangfeng@gmail.com"
6 | },
7 | "homepage": "https://github.com/xiangwangfeng/M80AttributedLabel/",
8 | "summary": "Another attributed label using CoreText",
9 | "source": {
10 | "git": "https://github.com/xiangwangfeng/M80AttributedLabel.git",
11 | "tag": "1.9.3"
12 | },
13 | "license": "MIT",
14 | "requires_arc": true,
15 | "platforms": {
16 | "ios": "7.0"
17 | },
18 | "frameworks": [
19 | "CoreText",
20 | "CoreGraphics",
21 | "QuartzCore"
22 | ],
23 | "source_files": "M80AttributedLabel/*.{h,m}"
24 | }
25 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - M80AttributedLabel (1.9.3)
3 |
4 | DEPENDENCIES:
5 | - M80AttributedLabel (from `../`)
6 |
7 | EXTERNAL SOURCES:
8 | M80AttributedLabel:
9 | :path: "../"
10 |
11 | SPEC CHECKSUMS:
12 | M80AttributedLabel: 362643e3ed8d4c53d779eb8fe74f0ee70432c948
13 |
14 | PODFILE CHECKSUM: c204fac8364187b2bd67bb03850fcbcaad8bfd33
15 |
16 | COCOAPODS: 1.7.0.beta.2
17 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Target Support Files/M80AttributedLabel/M80AttributedLabel-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_M80AttributedLabel : NSObject
3 | @end
4 | @implementation PodsDummy_M80AttributedLabel
5 | @end
6 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Target Support Files/M80AttributedLabel/M80AttributedLabel-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Target Support Files/M80AttributedLabel/M80AttributedLabel.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/M80AttributedLabel
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/M80AttributedLabel" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/M80AttributedLabel"
4 | PODS_BUILD_DIR = ${BUILD_DIR}
5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
6 | PODS_ROOT = ${SRCROOT}
7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Target Support Files/Pods-OCDemo/Pods-OCDemo-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## M80AttributedLabel
5 |
6 | Copyright (c) 2014 Xiang Wangfeng (http://xiangwangfeng.com)
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
26 | Generated by CocoaPods - https://cocoapods.org
27 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Target Support Files/Pods-OCDemo/Pods-OCDemo-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | Copyright (c) 2014 Xiang Wangfeng (http://xiangwangfeng.com)
18 |
19 | Permission is hereby granted, free of charge, to any person obtaining a copy
20 | of this software and associated documentation files (the "Software"), to deal
21 | in the Software without restriction, including without limitation the rights
22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23 | copies of the Software, and to permit persons to whom the Software is
24 | furnished to do so, subject to the following conditions:
25 |
26 | The above copyright notice and this permission notice shall be included in
27 | all copies or substantial portions of the Software.
28 |
29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
35 | THE SOFTWARE.
36 |
37 | License
38 | MIT
39 | Title
40 | M80AttributedLabel
41 | Type
42 | PSGroupSpecifier
43 |
44 |
45 | FooterText
46 | Generated by CocoaPods - https://cocoapods.org
47 | Title
48 |
49 | Type
50 | PSGroupSpecifier
51 |
52 |
53 | StringsTable
54 | Acknowledgements
55 | Title
56 | Acknowledgements
57 |
58 |
59 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Target Support Files/Pods-OCDemo/Pods-OCDemo-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_OCDemo : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_OCDemo
5 | @end
6 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Target Support Files/Pods-OCDemo/Pods-OCDemo-frameworks.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -u
4 | set -o pipefail
5 |
6 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
7 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
8 | # frameworks to, so exit 0 (signalling the script phase was successful).
9 | exit 0
10 | fi
11 |
12 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
13 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
14 |
15 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
16 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
17 |
18 | # Used as a return value for each invocation of `strip_invalid_archs` function.
19 | STRIP_BINARY_RETVAL=0
20 |
21 | # This protects against multiple targets copying the same framework dependency at the same time. The solution
22 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
23 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
24 |
25 | # Copies and strips a vendored framework
26 | install_framework()
27 | {
28 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
29 | local source="${BUILT_PRODUCTS_DIR}/$1"
30 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
31 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
32 | elif [ -r "$1" ]; then
33 | local source="$1"
34 | fi
35 |
36 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
37 |
38 | if [ -L "${source}" ]; then
39 | echo "Symlinked..."
40 | source="$(readlink "${source}")"
41 | fi
42 |
43 | # Use filter instead of exclude so missing patterns don't throw errors.
44 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
45 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
46 |
47 | local basename
48 | basename="$(basename -s .framework "$1")"
49 | binary="${destination}/${basename}.framework/${basename}"
50 | if ! [ -r "$binary" ]; then
51 | binary="${destination}/${basename}"
52 | fi
53 |
54 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
55 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
56 | strip_invalid_archs "$binary"
57 | fi
58 |
59 | # Resign the code if required by the build settings to avoid unstable apps
60 | code_sign_if_enabled "${destination}/$(basename "$1")"
61 |
62 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
63 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
64 | local swift_runtime_libs
65 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
66 | for lib in $swift_runtime_libs; do
67 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
68 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
69 | code_sign_if_enabled "${destination}/${lib}"
70 | done
71 | fi
72 | }
73 |
74 | # Copies and strips a vendored dSYM
75 | install_dsym() {
76 | local source="$1"
77 | if [ -r "$source" ]; then
78 | # Copy the dSYM into a the targets temp dir.
79 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
80 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
81 |
82 | local basename
83 | basename="$(basename -s .framework.dSYM "$source")"
84 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
85 |
86 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
87 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then
88 | strip_invalid_archs "$binary"
89 | fi
90 |
91 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
92 | # Move the stripped file into its final destination.
93 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
94 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
95 | else
96 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
97 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
98 | fi
99 | fi
100 | }
101 |
102 | # Signs a framework with the provided identity
103 | code_sign_if_enabled() {
104 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
105 | # Use the current code_sign_identitiy
106 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
107 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
108 |
109 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
110 | code_sign_cmd="$code_sign_cmd &"
111 | fi
112 | echo "$code_sign_cmd"
113 | eval "$code_sign_cmd"
114 | fi
115 | }
116 |
117 | # Strip invalid architectures
118 | strip_invalid_archs() {
119 | binary="$1"
120 | # Get architectures for current target binary
121 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
122 | # Intersect them with the architectures we are building for
123 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
124 | # If there are no archs supported by this binary then warn the user
125 | if [[ -z "$intersected_archs" ]]; then
126 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
127 | STRIP_BINARY_RETVAL=0
128 | return
129 | fi
130 | stripped=""
131 | for arch in $binary_archs; do
132 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then
133 | # Strip non-valid architectures in-place
134 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1
135 | stripped="$stripped $arch"
136 | fi
137 | done
138 | if [[ "$stripped" ]]; then
139 | echo "Stripped $binary of architectures:$stripped"
140 | fi
141 | STRIP_BINARY_RETVAL=1
142 | }
143 |
144 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
145 | wait
146 | fi
147 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Target Support Files/Pods-OCDemo/Pods-OCDemo-resources.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -u
4 | set -o pipefail
5 |
6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
8 | # resources to, so exit 0 (signalling the script phase was successful).
9 | exit 0
10 | fi
11 |
12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
13 |
14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
15 | > "$RESOURCES_TO_COPY"
16 |
17 | XCASSET_FILES=()
18 |
19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution
20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
22 |
23 | case "${TARGETED_DEVICE_FAMILY:-}" in
24 | 1,2)
25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
26 | ;;
27 | 1)
28 | TARGET_DEVICE_ARGS="--target-device iphone"
29 | ;;
30 | 2)
31 | TARGET_DEVICE_ARGS="--target-device ipad"
32 | ;;
33 | 3)
34 | TARGET_DEVICE_ARGS="--target-device tv"
35 | ;;
36 | 4)
37 | TARGET_DEVICE_ARGS="--target-device watch"
38 | ;;
39 | *)
40 | TARGET_DEVICE_ARGS="--target-device mac"
41 | ;;
42 | esac
43 |
44 | install_resource()
45 | {
46 | if [[ "$1" = /* ]] ; then
47 | RESOURCE_PATH="$1"
48 | else
49 | RESOURCE_PATH="${PODS_ROOT}/$1"
50 | fi
51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then
52 | cat << EOM
53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script.
54 | EOM
55 | exit 1
56 | fi
57 | case $RESOURCE_PATH in
58 | *.storyboard)
59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
61 | ;;
62 | *.xib)
63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
65 | ;;
66 | *.framework)
67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
71 | ;;
72 | *.xcdatamodel)
73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
75 | ;;
76 | *.xcdatamodeld)
77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
79 | ;;
80 | *.xcmappingmodel)
81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
83 | ;;
84 | *.xcassets)
85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
87 | ;;
88 | *)
89 | echo "$RESOURCE_PATH" || true
90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
91 | ;;
92 | esac
93 | }
94 |
95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
100 | fi
101 | rm -f "$RESOURCES_TO_COPY"
102 |
103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ]
104 | then
105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets).
106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
107 | while read line; do
108 | if [[ $line != "${PODS_ROOT}*" ]]; then
109 | XCASSET_FILES+=("$line")
110 | fi
111 | done <<<"$OTHER_XCASSETS"
112 |
113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then
114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
115 | else
116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist"
117 | fi
118 | fi
119 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Target Support Files/Pods-OCDemo/Pods-OCDemo.debug.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/M80AttributedLabel"
3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/M80AttributedLabel"
4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"M80AttributedLabel" -framework "CoreGraphics" -framework "CoreText" -framework "QuartzCore"
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
8 | PODS_ROOT = ${SRCROOT}/Pods
9 |
--------------------------------------------------------------------------------
/OCDemo/Pods/Target Support Files/Pods-OCDemo/Pods-OCDemo.release.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/M80AttributedLabel"
3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/M80AttributedLabel"
4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"M80AttributedLabel" -framework "CoreGraphics" -framework "CoreText" -framework "QuartzCore"
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
8 | PODS_ROOT = ${SRCROOT}/Pods
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | M80AttributedLabel
2 | ==================
3 |
4 |
5 | Another attributed label using CoreText [中文版本](./Documents/README.md)
6 |
7 |
8 | # Features
9 | * Multi-line Rich Text Display
10 | * Auto Link Detection and Custom Links Supported
11 | * Embedding Image and Custom Views
12 | * Following Properties Supported:
13 | * `font`
14 | * `textColor`
15 | * `highlightColor`
16 | * `linkColor`
17 | * `underLineForLink`
18 | * `numbersOfLines` (Truncates Last Line Supported)
19 | * `textAlignment`
20 | * `lineBreakMode`
21 | * `lineSpacing`
22 | * `paragraphSpacing`
23 | * `shadowColor`
24 | * `shadowOffset`
25 | * `shadowBlur`
26 |
27 |
28 |
29 | # System Requirement
30 | * iOS 7.0 or later
31 | * ARC required
32 |
33 | # Installation
34 | ### Podfile
35 | ```ruby
36 | pod 'M80AttributedLabel'
37 | ```
38 | ### Manually
39 | * `git clone https://github.com/xiangwangfeng/M80AttributedLabel.git`
40 | * Copy files in `Class/M80AttributedLabel` to your project
41 | * Add `CoreText.framework` to your target
42 |
43 | # Usage
44 |
45 | ## Basic
46 |
47 | ```objc
48 |
49 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
50 |
51 | label.text = @"Hello M80AttributedLabel";
52 | label.font = [UIFont fontWithName:@"Zapfino" size:25];
53 | label.textColor = M80RGB(0xFF9F00);
54 | label.shadowColor = [UIColor grayColor];
55 | label.shadowOffset= CGSizeMake(1, 1);
56 | label.shadowBlur = 1;
57 |
58 | label.frame = CGRectInset(self.view.bounds,20,20);
59 |
60 | [self.view addSubview:label];
61 |
62 | ```
63 |
64 |
65 |
66 | ## Link
67 |
68 | ```objc
69 |
70 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
71 |
72 | NSString *text = @"The game which I current play is hearthstone,and its website is www.hearthstone.com.cn";
73 | NSRange range = [text rangeOfString:@"hearthstone"];
74 | label.text = text;
75 | [label addCustomLink:[NSValue valueWithRange:range]
76 | forRange:range];
77 | label.delegate = self;
78 |
79 | label.frame = CGRectInset(self.view.bounds,20,20);
80 |
81 | [self.view addSubview:label];
82 |
83 |
84 | ```
85 |
86 |
87 |
88 |
89 | ## Image
90 |
91 | ```objc
92 |
93 |
94 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
95 | label.lineSpacing = 5.0;
96 |
97 | [label appendImage:[UIImage imageNamed:@"avatar"]
98 | maxSize:CGSizeMake(40, 40)
99 | margin:UIEdgeInsetsZero
100 | alignment:M80ImageAlignmentBottom];
101 |
102 | NSString *text = @"say:\n有人问一位登山家为什么要去登山——谁都知道登山这件事既危险,又没什么实际的好处。[haha][haha][haha][haha]他回答道:“因为那座山峰在那里。”我喜欢这个答案,因为里面包含着幽默感——明明是自己想要登山,偏说是山在那里使他心里痒痒。除此之外,我还喜欢这位登山家干的事,没来由地往悬崖上爬。[haha][haha][haha]它会导致肌肉疼痛,还要冒摔出脑子的危险,所以一般人尽量避免爬山。[haha][haha][haha]用热力学的角度来看,这是个反熵的现象,所发趋害避利肯定反熵。";
103 |
104 | //replace [haha] by image
105 | NSArray *components = [text componentsSeparatedByString:@"[haha]"];
106 | NSUInteger count = [components count];
107 | for (NSUInteger i = 0; i < count; i++)
108 | {
109 | [label appendText:[components objectAtIndex:i]];
110 | if (i != count - 1)
111 | {
112 | [label appendImage:[UIImage imageNamed:@"haha"]
113 | maxSize:CGSizeMake(15, 15)
114 | margin:UIEdgeInsetsZero
115 | alignment:M80ImageAlignmentCenter];
116 | }
117 | }
118 |
119 | label.frame = CGRectInset(self.view.bounds,20,20);
120 | [self.view addSubview:label];
121 |
122 |
123 | ```
124 |
125 |
126 |
127 | ## Attachemnt
128 |
129 | ```objc
130 |
131 | M80AttributedLabel *label = [[M80AttributedLabel alloc]initWithFrame:CGRectZero];
132 |
133 | for (NSInteger i = 0; i < 3; i++)
134 | {
135 | [label appendText:@"Click the icon to fire event"];
136 |
137 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
138 | button setBackgroundImage:[UIImage imageNamed:@"play"] forState:UIControlStateNormal];
139 | [button addTarget:self
140 | action:@selector(buttonClicked:)
141 | forControlEvents:UIControlEventTouchUpInside];
142 | [button setBounds:CGRectMake(0, 0, 30, 30)];
143 | [button setTag:i];
144 | [label appendView:button];
145 |
146 | [label appendText:@"\n\n\n"];
147 | }
148 |
149 |
150 | label.frame = CGRectInset(self.view.bounds,20,20);
151 | [self.view addSubview:label];
152 |
153 | ```
154 |
155 |
156 |
157 | # Contact
158 | * https://github.com/xiangwangfeng
159 | * xiangwangfeng@gmail.com
160 | * http://weibo.com/epmao
161 |
162 | [Apache]: http://www.apache.org/licenses/LICENSE-2.0
163 | [MIT]: http://www.opensource.org/licenses/mit-license.php
164 | [GPL]: http://www.gnu.org/licenses/gpl.html
165 | [BSD]: http://opensource.org/licenses/bsd-license.php
166 |
167 | # License
168 |
169 | M80AttributedLabel is available under the [MIT license][MIT]. See the LICENSE file for more info.
170 |
--------------------------------------------------------------------------------
/Resource/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangwangfeng/M80AttributedLabel/9b3431f1094f48b77e505697fb31e714fa99b830/Resource/avatar.png
--------------------------------------------------------------------------------
/Resource/haha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangwangfeng/M80AttributedLabel/9b3431f1094f48b77e505697fb31e714fa99b830/Resource/haha.png
--------------------------------------------------------------------------------
/Resource/play@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangwangfeng/M80AttributedLabel/9b3431f1094f48b77e505697fb31e714fa99b830/Resource/play@2x.png
--------------------------------------------------------------------------------
/Resource/test.txt:
--------------------------------------------------------------------------------
1 | 有人问一位登山家为什么要去登山——谁都知道登山这件事既危险,又没什么实际的好处,他回答道:“因为那座山峰在那里。”我喜欢这个答案,因为里面包含着幽默感——明明是自己想要登山,偏说是山在那里使他心里痒痒。除此之外,我还喜欢这位登山家干的事,没来由地往悬崖上爬。它会导致肌肉疼痛,还要冒摔出脑子的危险,所以一般人尽量避免爬山。用热力学的角度来看,这是个反熵的现象,所发趋害避利肯定反熵。","
2 |
3 | 现在把登山和写作相提并论,势必要招致反对。这是因为最近十年来中国有过小说热、诗歌热、文化热,无论哪一种热都会导致大量的人投身写作,别人常把我看成此类人士中的一个,并且告诫我说,现在都是什么年月了,你还写小说(言下之意是眼下是经商热,我该下海去经商了)?但是我的情形不一样。前三种热发生时,我正在美国念书,丝毫没有受到感染。我们家的家训是不准孩子学文科,一律去学理工。因为这些缘故,立志写作在我身上是个不折不扣的反熵过程。我到现在也弄不明白自己为什么要干这件事,除了它是个反熵过程这一点。
4 |
5 | 有关我立志写作是个反熵过程,还有进一步解释的必要。写作是个笼统的字眼,还要看写什么东西。写畅销小说、爱情小诗等等热门东西,应该列入熵增过程之列。我写的东西一点不热门,不但挣不了钱,有时还要倒贴一些。严肃作家的“严肃”二字,就该做如此理解。据我所知,这世界上有名的严肃作家,大多是凑合也算不上。这样说明了以后,大家都能明白我确实在一个反熵过程中。
6 |
7 | 我父亲不让我们学文科,理由显而易见。在我们成长的时代里,老舍跳了太平湖,胡风关了临狱,王实味被枪毙了。以前还有金圣叹砍脑壳等等实例。当然,他老人家也是屋内饮酒,门外劝水的人,自己也是个文科的教授,但是他坦白地承认自己择术不正,不足为训。我们兄弟姐妹五个就范此全学了理工科,只我哥哥例外。考虑到我父母脾气暴躁、吼声如雷,你得说这种选择是个熵增过程。而我哥哥那个例外是这么发生的:七八年考大学时,我哥哥是北京木城漳煤矿最强壮的青年矿工,吼起来比我爸爸音量还要大。无论是动手揍他,还是朝他吼叫,我爸爸自己都挺不好意思,所以就任凭他去学了哲学:在罗辑学界的泰斗沈有鼎先生的门下当了研究生。考虑到符号逻辑是个极专门的学科(这是从外行人看不懂得逻辑文章来说),它和理工科差不太多的。从以上的叙述,你可以弄明白我父亲的意思。他希望我们每个人都学一种外行人弄不懂而又是有功世道的专业,平平安安地度过一生。我父亲一生坎坷,他又最爱我们,这样的安排在他看来最自然不过。
8 |
9 | 我自己的情形是这样的:从小到大,身体不算强壮,吼起来音量也不够大,所以一直本分为人。尽管如此,我身上总有一股要写小说的危险情绪。插队的时候,我遇上一个很坏的家伙(他还是我们的领导,属于在我国这个社会里少数坏干部之列),我就编了一个故事,描写他从尾骨开始一寸寸变成了一条驴,并且把它写出来,以泄心头之愤。后来读了一些书,我现卡夫卡也写了个类似的故事,搞得我很不好意思。还有一个故事,女主人公长了蝙蝠的翅膀,并且头发是绿色的,生活在水下。这些二十岁前的作品我都烧掉了。在此一提是要说明这种危险倾向的由来。后来我一直抑制着这种倾向,念完了本科,到美国去留学。我哥哥也念完了硕士,也到美国去留学。我在那边又开始写小说,这种危险的倾向再也不能抑制了。
10 |
11 | 在美国时,我父亲去世了。回想他让我们读理科的事,觉得和美国发生的事不是一个逻辑。这让我想起了前苏联元帅图哈切夫斯基对大音乐家萧斯塔科奇说的话来:“我小的时候,很有音乐天才。只可惜我父亲没钱给我买把小提琴!假如有了那把小提琴,我现在就坐在你的乐池里。”这段话乍看不明其意,需要我提示一句:这次对话发生在苏联的三年代,说宛了没多久,图元帅就一命呜呼。那年头专毙元帅将军,不大毙小提琴手。文化革命里跳楼下吊的却是文人居多。我父亲在世时,一心一意地要给我们每人都弄把小提琴。这把小提琴就是理工农医任一门,只有文科不在其内,这和美国发生的事不一样,但是结论还是同一个——我该去干点别的,不该写小说。
12 |
13 | 有关美国的一切,可以用一句话来描述:“Americans business is business”,这句话的意思就是说,那个国家永远是在经商热中,而且永远是一千度的白热。所以你要是看了前文之后以为那里有某种气氛会有助于人立志写作就错了。连我哥哥到了那里都后悔了,觉得不该学逻辑,应当学商科或者计算机。虽然他依旧未证出的逻辑定理,但是看到有钱人豪华的住房,也免不了唠叨几句他对妻儿的责任。
14 |
15 | 在美国有很强大的力是促使人去挣钱,比方说洋房,有些只有一片小草坪,有的有几百亩草坪,有的有几千亩草坪,所以仅就住房一项,就能产生无穷无尽的挣钱的动力。再比方说汽车,有无穷的档次和价格。你要是真有钱,可以考虑把肯尼边遇刺时坐的汽车买来坐。还有人买下了前苏联的战斗机,驾着飞上天。在那个社会里,没有人受得了自己的孩子对同伴说:我爸爸穷。我要是有孩子,现在也准在那里挣钱。而写书在那里也不是个挣钱的行当,不信你到美国书店里看看,各种各样的书涨了架子,和超级市场里陈列的卫生纸一样多——假如有人出售苦心积虑一页页写出的卫生纸,肯定不是好行当。除此之外,还有好多人的书没有上架,窝在他自己的家里。我没有孩子,也不准备要。作为中国人,我是个极少见的现象。但是人有一张脸,树有一张皮,别人都有钱挣,自己却在干可疑的勾当,脸面上也过不去。
16 |
17 | 在美国时,有一次和一位华人教授聊天,他说他女儿很有出息,放着哈佛大学人类学系奖学金不要,自费去念一般的大学的lawschool如此反潮流,真不愧是书香门第。其实这是舍小利而趋大利,受小害而避大害。不信你去问问律师挣多少钱,人类学家又挣多少钱。和我聊天的这位教授是个大学问家,特立独行之辈。一谈到了儿女,好像也不大特立独行了。
18 |
19 | 说完了美国、苏联,就该谈谈自己。到现在为止,我写了八年小说,也出了几本书,但是大家没怎么看到。除此之外,我还常收到谩骂性的退稿信,这时我总善意地想:写信的人准是领导那里挨了骂,找我撒气。提起王小波,大家准会想到宋朝的四川拉杆子的那一位,想不起我身上。我还在反熵过程中。顺便说一句,人类的存在,文明的发展就是个反熵过程,但是这是说人类。具体说到自己,我的行为依旧无法解释。再顺便说一句,处于反熵过程中,绝不只是我一个人。在美国,我遇上过支起摊来卖托洛斯基、格瓦拉、毛主席等人的书的家伙,我要和他说话,他先问我怕不怕联帮调查局——别的例子还很多。在这些人身上,你就看不到水往低处流、苹果掉下地,狼把兔子吃掉的宏大的过程,看到的现象,相当于水往山上流,苹果飞上天,兔子吃掉狼。我还可以说,光有熵增现象不成。举例言之,大家都顺着一个自然的方向往下溜,最后准会在个低洼的地方汇齐,挤在一起像粪缸里的蛆。但是这也不能解释我的行为。我的行为是不能解释的,假如你把熵增现象看成金科玉律的话。
20 |
21 | 当然,如果硬要我用一句话直截了当地回答这个问题,那就是:我相信我自己有文学才能,我应该做这件事。但是这句话正如一个嫌疑犯说自己没杀人一样不可信。所以信不信由你罢
22 |
23 | PS:为了测试,加个链接进去:http://www.xiangwangfeng.com
--------------------------------------------------------------------------------
/SwiftDemo/Classes/AttachmentViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AttachmentViewController.swift
3 | // SwiftDemo
4 | //
5 | // Created by amao on 2016/10/12.
6 | // Copyright © 2016年 amao. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class AttachmentViewController: BaseViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | self.title = "Attachment"
17 |
18 | let label = M80AttributedLabel()
19 |
20 | for i in 0..<3 {
21 | label.appendText("Click the icon to fire event")
22 |
23 | let button = UIButton(type: .custom)
24 | button.setBackgroundImage(UIImage(named:"play"), for: .normal)
25 | button.addTarget(self, action: #selector(buttonClicked(_:)), for: .touchUpInside)
26 | button.bounds = CGRect.init(x: 0, y: 0, width: 30, height: 30)
27 | button.tag = i
28 | label.append(button)
29 | label.appendText("\n\n\n")
30 | }
31 |
32 | label.frame = self.view.bounds.insetBy(dx: 20, dy: 20)
33 | self.view.addSubview(label)
34 | }
35 |
36 | override func didReceiveMemoryWarning() {
37 | super.didReceiveMemoryWarning()
38 | }
39 |
40 | @objc func buttonClicked(_ sender : AnyObject) {
41 | if let button = sender as? UIButton {
42 | let message = "button tag is \(button.tag)"
43 | let controller = UIAlertController(title: "you click a button", message: message, preferredStyle: .alert)
44 | let action = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
45 | controller.addAction(action)
46 | self.present(controller, animated: true, completion: nil)
47 |
48 | }
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/SwiftDemo/Classes/BaseViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseViewController.swift
3 | // SwiftDemo
4 | //
5 | // Created by amao on 2016/10/12.
6 | // Copyright © 2016年 amao. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class BaseViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | self.edgesForExtendedLayout = UIRectEdge.init(rawValue: 0)
16 | self.view?.backgroundColor = UIColor.white
17 | }
18 |
19 | override func didReceiveMemoryWarning() {
20 | super.didReceiveMemoryWarning()
21 | // Dispose of any resources that can be recreated.
22 | }
23 |
24 |
25 | /*
26 | // MARK: - Navigation
27 |
28 | // In a storyboard-based application, you will often want to do a little preparation before navigation
29 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
30 | // Get the new view controller using segue.destinationViewController.
31 | // Pass the selected object to the new view controller.
32 | }
33 | */
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/SwiftDemo/Classes/BasicAttributedLabelViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BasicAttributedLabelViewController.swift
3 | // SwiftDemo
4 | //
5 | // Created by amao on 2016/10/12.
6 | // Copyright © 2016年 amao. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class BasicAttributedLabelViewController: BaseViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | self.title = "Basic"
17 |
18 | let label = M80AttributedLabel()
19 | label.text = "Hello M80AttribtuedLabel"
20 | label.font = UIFont(name: "Zapfino", size: 25)
21 | label.textColor = RGB(0xFF9F00)
22 | label.shadowColor = UIColor.gray
23 | label.shadowBlur = 1
24 | label.frame = self.view.bounds.insetBy(dx: 20, dy: 20)
25 |
26 | self.view.addSubview(label)
27 | }
28 |
29 | override func didReceiveMemoryWarning() {
30 | super.didReceiveMemoryWarning()
31 | // Dispose of any resources that can be recreated.
32 | }
33 |
34 |
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/SwiftDemo/Classes/CustomTextViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CustomTextViewController.swift
3 | // SwiftDemo
4 | //
5 | // Created by amao on 2016/10/12.
6 | // Copyright © 2016年 amao. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CustomTextViewController: BaseViewController {
12 |
13 | let fontSize : [CGFloat] = [12,13,17,25]
14 | let colors = [RGB(0x000000),RGB(0x0000ff),RGB(0x00ff00),RGB(0xff0000)]
15 |
16 |
17 |
18 | override func viewDidLoad() {
19 | super.viewDidLoad()
20 |
21 | self.title = "Custom Text"
22 |
23 | let label = M80AttributedLabel()
24 | let text = "The release of iOS 7 brings a lot of new tools to the table for developers."
25 | let components = text.components(separatedBy: " ")
26 | for component in components {
27 | let index = Int(arc4random() % 4)
28 | let attributedText = NSMutableAttributedString(string: component)
29 | attributedText.m80_setFont(UIFont.systemFont(ofSize: fontSize[index]))
30 | attributedText.m80_setTextColor(colors[index])
31 |
32 | label.appendAttributedText(attributedText)
33 | label.appendText(" ")
34 | }
35 |
36 | label.frame = self.view.bounds.insetBy(dx: 20, dy: 20)
37 | self.view.addSubview(label)
38 |
39 | }
40 |
41 | override func didReceiveMemoryWarning() {
42 | super.didReceiveMemoryWarning()
43 |
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/SwiftDemo/Classes/DemoTableViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DemoTableViewController.swift
3 | // SwiftDemo
4 | //
5 | // Created by amao on 2016/10/12.
6 | // Copyright © 2016年 amao. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | struct Item {
12 | let title : String
13 | let subTitle : String
14 | let vcName : String
15 |
16 | init(_ title : String, _ subTitle : String, _ vcName : String) {
17 | self.title = title
18 | self.subTitle = subTitle
19 | self.vcName = vcName
20 | }
21 | }
22 |
23 |
24 |
25 |
26 | class DemoTableViewController: UITableViewController {
27 |
28 | let items : [Item] = [Item("Basic","How to create a simple M80AttributedLabel","BasicAttributedLabelViewController"),
29 | Item("Customizing Text","How to use NSAttributedString","CustomTextViewController"),
30 | Item("Links","Automatic and explicit Links","LinksViewController"),
31 | Item("Images","How to display images using M80AttributedLabel","ImagesViewController"),
32 | Item("LongText","Performance for displaying long text","LongTextViewController"),
33 | Item("Attachment","Add UIView as attachment instead of UIImag","AttachmentViewController"),
34 | Item("LineBreakMode","Different line break modes","LineBreakModeViewController"),
35 | Item("TextAlignment","Different test alignments","TextAlignmentViewController")]
36 |
37 | override func viewDidLoad() {
38 | super.viewDidLoad()
39 | self.title = "Demo"
40 | self.navigationController?.view.backgroundColor = UIColor.white
41 | }
42 |
43 | override func didReceiveMemoryWarning() {
44 | super.didReceiveMemoryWarning()
45 | }
46 |
47 | // MARK: - Table view data source
48 | override func numberOfSections(in tableView: UITableView) -> Int {
49 | return 1
50 | }
51 |
52 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
53 | return self.items.count
54 | }
55 |
56 |
57 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
58 |
59 | let identifier = "demo_identifier"
60 | let item = self.items[indexPath.row]
61 | var cell = tableView.dequeueReusableCell(withIdentifier:identifier)
62 | if cell == nil {
63 | cell = UITableViewCell(style: .subtitle, reuseIdentifier: identifier)
64 | }
65 | cell?.textLabel?.text = item.title
66 | cell?.detailTextLabel?.text = item.subTitle
67 |
68 | return cell!
69 | }
70 |
71 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
72 | let item = self.items[indexPath.row]
73 | let name = item.vcName
74 | if let vcClass = ClassByName(name: name) as? UIViewController.Type {
75 | let vc = vcClass.init()
76 | self.navigationController?.pushViewController(vc, animated: true)
77 | }
78 |
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/SwiftDemo/Classes/ImagesViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImagesViewController.swift
3 | // SwiftDemo
4 | //
5 | // Created by amao on 2016/10/12.
6 | // Copyright © 2016年 amao. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ImagesViewController: BaseViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | self.title = "Images"
17 |
18 | let label = M80AttributedLabel()
19 | label.lineSpacing = 5.0
20 |
21 |
22 | if let image = UIImage(named: "avatar") {
23 | label.append(image, maxSize: CGSize.init(width: 40, height: 40), margin:.zero)
24 | }
25 |
26 | let text = "say:\n有人问一位登山家为什么要去登山——谁都知道登山这件事既危险,又没什么实际的好处。[haha][haha][haha][haha]他回答道:“因为那座山峰在那里。”我喜欢这个答案,因为里面包含着幽默感——明明是自己想要登山,偏说是山在那里使他心里痒痒。除此之外,我还喜欢这位登山家干的事,没来由地往悬崖上爬。[haha][haha][haha]它会导致肌肉疼痛,还要冒摔出脑子的危险,所以一般人尽量避免爬山。[haha][haha][haha]用热力学的角度来看,这是个反熵的现象,所发趋害避利肯定反熵。"
27 | let components = text.components(separatedBy: "[haha]")
28 | let count = components.count
29 | for i in 0.. UIColor {
12 | let r = CGFloat((value & 0xFF0000) >> 16) / 255.0
13 | let g = CGFloat((value & 0x00FF00) >> 8 ) / 255.0
14 | let b = CGFloat((value & 0x0000FF) ) / 255.0
15 | return UIColor(red: r, green: g, blue: b, alpha: 1.0)
16 | }
17 |
18 | func ClassByName(name : String) -> AnyClass? {
19 |
20 | var result : AnyClass? = nil
21 | if let bundle = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String {
22 | let className = bundle + "." + name
23 | result = NSClassFromString(className)
24 | }
25 | return result
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/SwiftDemo/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | target 'SwiftDemo' do
5 | pod ‘M80AttributedLabel’, :path => ‘../’
6 |
7 | end
8 |
--------------------------------------------------------------------------------
/SwiftDemo/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - M80AttributedLabel (1.9.3)
3 |
4 | DEPENDENCIES:
5 | - M80AttributedLabel (from `../`)
6 |
7 | EXTERNAL SOURCES:
8 | M80AttributedLabel:
9 | :path: "../"
10 |
11 | SPEC CHECKSUMS:
12 | M80AttributedLabel: 362643e3ed8d4c53d779eb8fe74f0ee70432c948
13 |
14 | PODFILE CHECKSUM: 6bec8775bfed9535c4243f6946f719b518dd40e7
15 |
16 | COCOAPODS: 1.7.0.beta.2
17 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Private/M80AttributedLabel/M80AttributedLabel.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabel.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Private/M80AttributedLabel/M80AttributedLabelAttachment.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelAttachment.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Private/M80AttributedLabel/M80AttributedLabelDefines.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelDefines.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Private/M80AttributedLabel/M80AttributedLabelURL.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelURL.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Private/M80AttributedLabel/M80AttributedLabelURLDetector.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelURLDetector.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Private/M80AttributedLabel/NSMutableAttributedString+M80.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/NSMutableAttributedString+M80.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Public/M80AttributedLabel/M80AttributedLabel.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabel.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Public/M80AttributedLabel/M80AttributedLabelAttachment.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelAttachment.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Public/M80AttributedLabel/M80AttributedLabelDefines.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelDefines.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Public/M80AttributedLabel/M80AttributedLabelURL.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelURL.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Public/M80AttributedLabel/M80AttributedLabelURLDetector.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/M80AttributedLabelURLDetector.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Headers/Public/M80AttributedLabel/NSMutableAttributedString+M80.h:
--------------------------------------------------------------------------------
1 | ../../../../../M80AttributedLabel/NSMutableAttributedString+M80.h
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Local Podspecs/M80AttributedLabel.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "M80AttributedLabel",
3 | "version": "1.9.3",
4 | "authors": {
5 | "Xiang Wangfeng": "xiangwangfeng@gmail.com"
6 | },
7 | "homepage": "https://github.com/xiangwangfeng/M80AttributedLabel/",
8 | "summary": "Another attributed label using CoreText",
9 | "source": {
10 | "git": "https://github.com/xiangwangfeng/M80AttributedLabel.git",
11 | "tag": "1.9.3"
12 | },
13 | "license": "MIT",
14 | "requires_arc": true,
15 | "platforms": {
16 | "ios": "7.0"
17 | },
18 | "frameworks": [
19 | "CoreText",
20 | "CoreGraphics",
21 | "QuartzCore"
22 | ],
23 | "source_files": "M80AttributedLabel/*.{h,m}"
24 | }
25 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - M80AttributedLabel (1.9.3)
3 |
4 | DEPENDENCIES:
5 | - M80AttributedLabel (from `../`)
6 |
7 | EXTERNAL SOURCES:
8 | M80AttributedLabel:
9 | :path: "../"
10 |
11 | SPEC CHECKSUMS:
12 | M80AttributedLabel: 362643e3ed8d4c53d779eb8fe74f0ee70432c948
13 |
14 | PODFILE CHECKSUM: 6bec8775bfed9535c4243f6946f719b518dd40e7
15 |
16 | COCOAPODS: 1.7.0.beta.2
17 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Target Support Files/M80AttributedLabel/M80AttributedLabel-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_M80AttributedLabel : NSObject
3 | @end
4 | @implementation PodsDummy_M80AttributedLabel
5 | @end
6 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Target Support Files/M80AttributedLabel/M80AttributedLabel-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Target Support Files/M80AttributedLabel/M80AttributedLabel.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/M80AttributedLabel
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/M80AttributedLabel" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/M80AttributedLabel"
4 | PODS_BUILD_DIR = ${BUILD_DIR}
5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
6 | PODS_ROOT = ${SRCROOT}
7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## M80AttributedLabel
5 |
6 | Copyright (c) 2014 Xiang Wangfeng (http://xiangwangfeng.com)
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
26 | Generated by CocoaPods - https://cocoapods.org
27 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | Copyright (c) 2014 Xiang Wangfeng (http://xiangwangfeng.com)
18 |
19 | Permission is hereby granted, free of charge, to any person obtaining a copy
20 | of this software and associated documentation files (the "Software"), to deal
21 | in the Software without restriction, including without limitation the rights
22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23 | copies of the Software, and to permit persons to whom the Software is
24 | furnished to do so, subject to the following conditions:
25 |
26 | The above copyright notice and this permission notice shall be included in
27 | all copies or substantial portions of the Software.
28 |
29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
35 | THE SOFTWARE.
36 |
37 | License
38 | MIT
39 | Title
40 | M80AttributedLabel
41 | Type
42 | PSGroupSpecifier
43 |
44 |
45 | FooterText
46 | Generated by CocoaPods - https://cocoapods.org
47 | Title
48 |
49 | Type
50 | PSGroupSpecifier
51 |
52 |
53 | StringsTable
54 | Acknowledgements
55 | Title
56 | Acknowledgements
57 |
58 |
59 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_SwiftDemo : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_SwiftDemo
5 | @end
6 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo-frameworks.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -u
4 | set -o pipefail
5 |
6 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
7 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
8 | # frameworks to, so exit 0 (signalling the script phase was successful).
9 | exit 0
10 | fi
11 |
12 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
13 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
14 |
15 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
16 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
17 |
18 | # Used as a return value for each invocation of `strip_invalid_archs` function.
19 | STRIP_BINARY_RETVAL=0
20 |
21 | # This protects against multiple targets copying the same framework dependency at the same time. The solution
22 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
23 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
24 |
25 | # Copies and strips a vendored framework
26 | install_framework()
27 | {
28 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
29 | local source="${BUILT_PRODUCTS_DIR}/$1"
30 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
31 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
32 | elif [ -r "$1" ]; then
33 | local source="$1"
34 | fi
35 |
36 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
37 |
38 | if [ -L "${source}" ]; then
39 | echo "Symlinked..."
40 | source="$(readlink "${source}")"
41 | fi
42 |
43 | # Use filter instead of exclude so missing patterns don't throw errors.
44 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
45 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
46 |
47 | local basename
48 | basename="$(basename -s .framework "$1")"
49 | binary="${destination}/${basename}.framework/${basename}"
50 | if ! [ -r "$binary" ]; then
51 | binary="${destination}/${basename}"
52 | fi
53 |
54 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
55 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
56 | strip_invalid_archs "$binary"
57 | fi
58 |
59 | # Resign the code if required by the build settings to avoid unstable apps
60 | code_sign_if_enabled "${destination}/$(basename "$1")"
61 |
62 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
63 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
64 | local swift_runtime_libs
65 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
66 | for lib in $swift_runtime_libs; do
67 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
68 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
69 | code_sign_if_enabled "${destination}/${lib}"
70 | done
71 | fi
72 | }
73 |
74 | # Copies and strips a vendored dSYM
75 | install_dsym() {
76 | local source="$1"
77 | if [ -r "$source" ]; then
78 | # Copy the dSYM into a the targets temp dir.
79 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
80 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
81 |
82 | local basename
83 | basename="$(basename -s .framework.dSYM "$source")"
84 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
85 |
86 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
87 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then
88 | strip_invalid_archs "$binary"
89 | fi
90 |
91 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
92 | # Move the stripped file into its final destination.
93 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
94 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
95 | else
96 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
97 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
98 | fi
99 | fi
100 | }
101 |
102 | # Signs a framework with the provided identity
103 | code_sign_if_enabled() {
104 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
105 | # Use the current code_sign_identitiy
106 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
107 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
108 |
109 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
110 | code_sign_cmd="$code_sign_cmd &"
111 | fi
112 | echo "$code_sign_cmd"
113 | eval "$code_sign_cmd"
114 | fi
115 | }
116 |
117 | # Strip invalid architectures
118 | strip_invalid_archs() {
119 | binary="$1"
120 | # Get architectures for current target binary
121 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
122 | # Intersect them with the architectures we are building for
123 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
124 | # If there are no archs supported by this binary then warn the user
125 | if [[ -z "$intersected_archs" ]]; then
126 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
127 | STRIP_BINARY_RETVAL=0
128 | return
129 | fi
130 | stripped=""
131 | for arch in $binary_archs; do
132 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then
133 | # Strip non-valid architectures in-place
134 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1
135 | stripped="$stripped $arch"
136 | fi
137 | done
138 | if [[ "$stripped" ]]; then
139 | echo "Stripped $binary of architectures:$stripped"
140 | fi
141 | STRIP_BINARY_RETVAL=1
142 | }
143 |
144 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
145 | wait
146 | fi
147 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo-resources.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -u
4 | set -o pipefail
5 |
6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
8 | # resources to, so exit 0 (signalling the script phase was successful).
9 | exit 0
10 | fi
11 |
12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
13 |
14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
15 | > "$RESOURCES_TO_COPY"
16 |
17 | XCASSET_FILES=()
18 |
19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution
20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
22 |
23 | case "${TARGETED_DEVICE_FAMILY:-}" in
24 | 1,2)
25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
26 | ;;
27 | 1)
28 | TARGET_DEVICE_ARGS="--target-device iphone"
29 | ;;
30 | 2)
31 | TARGET_DEVICE_ARGS="--target-device ipad"
32 | ;;
33 | 3)
34 | TARGET_DEVICE_ARGS="--target-device tv"
35 | ;;
36 | 4)
37 | TARGET_DEVICE_ARGS="--target-device watch"
38 | ;;
39 | *)
40 | TARGET_DEVICE_ARGS="--target-device mac"
41 | ;;
42 | esac
43 |
44 | install_resource()
45 | {
46 | if [[ "$1" = /* ]] ; then
47 | RESOURCE_PATH="$1"
48 | else
49 | RESOURCE_PATH="${PODS_ROOT}/$1"
50 | fi
51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then
52 | cat << EOM
53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script.
54 | EOM
55 | exit 1
56 | fi
57 | case $RESOURCE_PATH in
58 | *.storyboard)
59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
61 | ;;
62 | *.xib)
63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
65 | ;;
66 | *.framework)
67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
71 | ;;
72 | *.xcdatamodel)
73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
75 | ;;
76 | *.xcdatamodeld)
77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
79 | ;;
80 | *.xcmappingmodel)
81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
83 | ;;
84 | *.xcassets)
85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
87 | ;;
88 | *)
89 | echo "$RESOURCE_PATH" || true
90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
91 | ;;
92 | esac
93 | }
94 |
95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
100 | fi
101 | rm -f "$RESOURCES_TO_COPY"
102 |
103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ]
104 | then
105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets).
106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
107 | while read line; do
108 | if [[ $line != "${PODS_ROOT}*" ]]; then
109 | XCASSET_FILES+=("$line")
110 | fi
111 | done <<<"$OTHER_XCASSETS"
112 |
113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then
114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
115 | else
116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist"
117 | fi
118 | fi
119 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo.debug.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/M80AttributedLabel"
3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/M80AttributedLabel"
4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"M80AttributedLabel" -framework "CoreGraphics" -framework "CoreText" -framework "QuartzCore"
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
8 | PODS_ROOT = ${SRCROOT}/Pods
9 |
--------------------------------------------------------------------------------
/SwiftDemo/Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo.release.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/M80AttributedLabel"
3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/M80AttributedLabel"
4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"M80AttributedLabel" -framework "CoreGraphics" -framework "CoreText" -framework "QuartzCore"
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
8 | PODS_ROOT = ${SRCROOT}/Pods
9 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 0FB94F06796F3C9E19E46DEB /* libPods-SwiftDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 01D0D40D9991462264CA89E7 /* libPods-SwiftDemo.a */; };
11 | E40951AE1DAF27E300773E64 /* LineBreakModeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E40951AD1DAF27E300773E64 /* LineBreakModeViewController.swift */; };
12 | E40951B01DAF2ACC00773E64 /* TextAlignmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E40951AF1DAF2ACC00773E64 /* TextAlignmentViewController.swift */; };
13 | E4A331A81DAE0B3D00B59A16 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A331A71DAE0B3D00B59A16 /* AppDelegate.swift */; };
14 | E4A331AA1DAE0B3D00B59A16 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A331A91DAE0B3D00B59A16 /* ViewController.swift */; };
15 | E4A331AD1DAE0B3D00B59A16 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4A331AB1DAE0B3D00B59A16 /* Main.storyboard */; };
16 | E4A331AF1DAE0B3D00B59A16 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E4A331AE1DAE0B3D00B59A16 /* Assets.xcassets */; };
17 | E4A331B21DAE0B3D00B59A16 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4A331B01DAE0B3D00B59A16 /* LaunchScreen.storyboard */; };
18 | E4A331E21DAE0FDD00B59A16 /* DemoTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A331E11DAE0FDD00B59A16 /* DemoTableViewController.swift */; };
19 | E4A331E61DAE14CB00B59A16 /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A331E51DAE14CB00B59A16 /* BaseViewController.swift */; };
20 | E4D22BBE1DAE166C00EB8F7E /* BasicAttributedLabelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4D22BBD1DAE166C00EB8F7E /* BasicAttributedLabelViewController.swift */; };
21 | E4D22BC01DAE180100EB8F7E /* CustomTextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4D22BBF1DAE180100EB8F7E /* CustomTextViewController.swift */; };
22 | E4D22BC91DAE191C00EB8F7E /* Util.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4D22BC81DAE191C00EB8F7E /* Util.swift */; };
23 | E4D22BCF1DAE203C00EB8F7E /* avatar.png in Resources */ = {isa = PBXBuildFile; fileRef = E4D22BCB1DAE203C00EB8F7E /* avatar.png */; };
24 | E4D22BD01DAE203C00EB8F7E /* haha.png in Resources */ = {isa = PBXBuildFile; fileRef = E4D22BCC1DAE203C00EB8F7E /* haha.png */; };
25 | E4D22BD11DAE203C00EB8F7E /* play@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E4D22BCD1DAE203C00EB8F7E /* play@2x.png */; };
26 | E4D22BD21DAE203C00EB8F7E /* test.txt in Resources */ = {isa = PBXBuildFile; fileRef = E4D22BCE1DAE203C00EB8F7E /* test.txt */; };
27 | E4D22BD41DAE227700EB8F7E /* LinksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4D22BD31DAE227700EB8F7E /* LinksViewController.swift */; };
28 | E4D22BD81DAE315300EB8F7E /* ImagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4D22BD71DAE315300EB8F7E /* ImagesViewController.swift */; };
29 | E4D22BDA1DAE325500EB8F7E /* AttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4D22BD91DAE325500EB8F7E /* AttachmentViewController.swift */; };
30 | E4D22BDC1DAE348500EB8F7E /* LongTextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4D22BDB1DAE348500EB8F7E /* LongTextViewController.swift */; };
31 | /* End PBXBuildFile section */
32 |
33 | /* Begin PBXFileReference section */
34 | 01D0D40D9991462264CA89E7 /* libPods-SwiftDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SwiftDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; };
35 | 4BCEAB4CF3E5C6DDE3B882EA /* Pods-SwiftDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo.release.xcconfig"; sourceTree = ""; };
36 | C43C45C0E63F53F1B14DF04D /* Pods-SwiftDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo.debug.xcconfig"; sourceTree = ""; };
37 | E40951AD1DAF27E300773E64 /* LineBreakModeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineBreakModeViewController.swift; sourceTree = ""; };
38 | E40951AF1DAF2ACC00773E64 /* TextAlignmentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextAlignmentViewController.swift; sourceTree = ""; };
39 | E4A331A41DAE0B3D00B59A16 /* SwiftDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
40 | E4A331A71DAE0B3D00B59A16 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
41 | E4A331A91DAE0B3D00B59A16 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
42 | E4A331AC1DAE0B3D00B59A16 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
43 | E4A331AE1DAE0B3D00B59A16 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
44 | E4A331B11DAE0B3D00B59A16 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
45 | E4A331B31DAE0B3D00B59A16 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
46 | E4A331CF1DAE0DAE00B59A16 /* SwiftDemo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SwiftDemo-Bridging-Header.h"; sourceTree = ""; };
47 | E4A331E11DAE0FDD00B59A16 /* DemoTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemoTableViewController.swift; sourceTree = ""; };
48 | E4A331E51DAE14CB00B59A16 /* BaseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = ""; };
49 | E4D22BBD1DAE166C00EB8F7E /* BasicAttributedLabelViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicAttributedLabelViewController.swift; sourceTree = ""; };
50 | E4D22BBF1DAE180100EB8F7E /* CustomTextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomTextViewController.swift; sourceTree = ""; };
51 | E4D22BC81DAE191C00EB8F7E /* Util.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Util.swift; sourceTree = ""; };
52 | E4D22BCB1DAE203C00EB8F7E /* avatar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = avatar.png; sourceTree = ""; };
53 | E4D22BCC1DAE203C00EB8F7E /* haha.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = haha.png; sourceTree = ""; };
54 | E4D22BCD1DAE203C00EB8F7E /* play@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "play@2x.png"; sourceTree = ""; };
55 | E4D22BCE1DAE203C00EB8F7E /* test.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test.txt; sourceTree = ""; };
56 | E4D22BD31DAE227700EB8F7E /* LinksViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinksViewController.swift; sourceTree = ""; };
57 | E4D22BD71DAE315300EB8F7E /* ImagesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImagesViewController.swift; sourceTree = ""; };
58 | E4D22BD91DAE325500EB8F7E /* AttachmentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentViewController.swift; sourceTree = ""; };
59 | E4D22BDB1DAE348500EB8F7E /* LongTextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LongTextViewController.swift; sourceTree = ""; };
60 | /* End PBXFileReference section */
61 |
62 | /* Begin PBXFrameworksBuildPhase section */
63 | E4A331A11DAE0B3D00B59A16 /* Frameworks */ = {
64 | isa = PBXFrameworksBuildPhase;
65 | buildActionMask = 2147483647;
66 | files = (
67 | 0FB94F06796F3C9E19E46DEB /* libPods-SwiftDemo.a in Frameworks */,
68 | );
69 | runOnlyForDeploymentPostprocessing = 0;
70 | };
71 | /* End PBXFrameworksBuildPhase section */
72 |
73 | /* Begin PBXGroup section */
74 | 3427210FF04A2630E4701FC1 /* Pods */ = {
75 | isa = PBXGroup;
76 | children = (
77 | C43C45C0E63F53F1B14DF04D /* Pods-SwiftDemo.debug.xcconfig */,
78 | 4BCEAB4CF3E5C6DDE3B882EA /* Pods-SwiftDemo.release.xcconfig */,
79 | );
80 | name = Pods;
81 | sourceTree = "";
82 | };
83 | A63A55A60449EAEBC9DC5118 /* Frameworks */ = {
84 | isa = PBXGroup;
85 | children = (
86 | 01D0D40D9991462264CA89E7 /* libPods-SwiftDemo.a */,
87 | );
88 | name = Frameworks;
89 | sourceTree = "";
90 | };
91 | E4A3319B1DAE0B3D00B59A16 = {
92 | isa = PBXGroup;
93 | children = (
94 | E4A331A61DAE0B3D00B59A16 /* SwiftDemo */,
95 | E4A331A51DAE0B3D00B59A16 /* Products */,
96 | 3427210FF04A2630E4701FC1 /* Pods */,
97 | A63A55A60449EAEBC9DC5118 /* Frameworks */,
98 | );
99 | sourceTree = "";
100 | };
101 | E4A331A51DAE0B3D00B59A16 /* Products */ = {
102 | isa = PBXGroup;
103 | children = (
104 | E4A331A41DAE0B3D00B59A16 /* SwiftDemo.app */,
105 | );
106 | name = Products;
107 | sourceTree = "";
108 | };
109 | E4A331A61DAE0B3D00B59A16 /* SwiftDemo */ = {
110 | isa = PBXGroup;
111 | children = (
112 | E4D22BCA1DAE203C00EB8F7E /* Resource */,
113 | E4A331CD1DAE0BB600B59A16 /* Classes */,
114 | E4A331A71DAE0B3D00B59A16 /* AppDelegate.swift */,
115 | E4A331A91DAE0B3D00B59A16 /* ViewController.swift */,
116 | E4A331AB1DAE0B3D00B59A16 /* Main.storyboard */,
117 | E4A331AE1DAE0B3D00B59A16 /* Assets.xcassets */,
118 | E4A331B01DAE0B3D00B59A16 /* LaunchScreen.storyboard */,
119 | E4A331B31DAE0B3D00B59A16 /* Info.plist */,
120 | );
121 | path = SwiftDemo;
122 | sourceTree = "";
123 | };
124 | E4A331CD1DAE0BB600B59A16 /* Classes */ = {
125 | isa = PBXGroup;
126 | children = (
127 | E4D22BC31DAE188300EB8F7E /* Util */,
128 | E4A331CF1DAE0DAE00B59A16 /* SwiftDemo-Bridging-Header.h */,
129 | E4A331E11DAE0FDD00B59A16 /* DemoTableViewController.swift */,
130 | E4D22BD71DAE315300EB8F7E /* ImagesViewController.swift */,
131 | E4A331E51DAE14CB00B59A16 /* BaseViewController.swift */,
132 | E4D22BBD1DAE166C00EB8F7E /* BasicAttributedLabelViewController.swift */,
133 | E4D22BBF1DAE180100EB8F7E /* CustomTextViewController.swift */,
134 | E4D22BD31DAE227700EB8F7E /* LinksViewController.swift */,
135 | E4D22BD91DAE325500EB8F7E /* AttachmentViewController.swift */,
136 | E4D22BDB1DAE348500EB8F7E /* LongTextViewController.swift */,
137 | E40951AD1DAF27E300773E64 /* LineBreakModeViewController.swift */,
138 | E40951AF1DAF2ACC00773E64 /* TextAlignmentViewController.swift */,
139 | );
140 | path = Classes;
141 | sourceTree = SOURCE_ROOT;
142 | };
143 | E4D22BC31DAE188300EB8F7E /* Util */ = {
144 | isa = PBXGroup;
145 | children = (
146 | E4D22BC81DAE191C00EB8F7E /* Util.swift */,
147 | );
148 | path = Util;
149 | sourceTree = "";
150 | };
151 | E4D22BCA1DAE203C00EB8F7E /* Resource */ = {
152 | isa = PBXGroup;
153 | children = (
154 | E4D22BCB1DAE203C00EB8F7E /* avatar.png */,
155 | E4D22BCC1DAE203C00EB8F7E /* haha.png */,
156 | E4D22BCD1DAE203C00EB8F7E /* play@2x.png */,
157 | E4D22BCE1DAE203C00EB8F7E /* test.txt */,
158 | );
159 | name = Resource;
160 | path = ../../Resource;
161 | sourceTree = "";
162 | };
163 | /* End PBXGroup section */
164 |
165 | /* Begin PBXNativeTarget section */
166 | E4A331A31DAE0B3D00B59A16 /* SwiftDemo */ = {
167 | isa = PBXNativeTarget;
168 | buildConfigurationList = E4A331B61DAE0B3D00B59A16 /* Build configuration list for PBXNativeTarget "SwiftDemo" */;
169 | buildPhases = (
170 | 0E44B47670F8F73369558D69 /* [CP] Check Pods Manifest.lock */,
171 | E4A331A01DAE0B3D00B59A16 /* Sources */,
172 | E4A331A11DAE0B3D00B59A16 /* Frameworks */,
173 | E4A331A21DAE0B3D00B59A16 /* Resources */,
174 | );
175 | buildRules = (
176 | );
177 | dependencies = (
178 | );
179 | name = SwiftDemo;
180 | productName = SwiftDemo;
181 | productReference = E4A331A41DAE0B3D00B59A16 /* SwiftDemo.app */;
182 | productType = "com.apple.product-type.application";
183 | };
184 | /* End PBXNativeTarget section */
185 |
186 | /* Begin PBXProject section */
187 | E4A3319C1DAE0B3D00B59A16 /* Project object */ = {
188 | isa = PBXProject;
189 | attributes = {
190 | LastSwiftUpdateCheck = 0800;
191 | LastUpgradeCheck = 0810;
192 | ORGANIZATIONNAME = amao;
193 | TargetAttributes = {
194 | E4A331A31DAE0B3D00B59A16 = {
195 | CreatedOnToolsVersion = 8.0;
196 | DevelopmentTeam = L5CU59RTNH;
197 | LastSwiftMigration = 0800;
198 | ProvisioningStyle = Automatic;
199 | };
200 | };
201 | };
202 | buildConfigurationList = E4A3319F1DAE0B3D00B59A16 /* Build configuration list for PBXProject "SwiftDemo" */;
203 | compatibilityVersion = "Xcode 3.2";
204 | developmentRegion = English;
205 | hasScannedForEncodings = 0;
206 | knownRegions = (
207 | English,
208 | en,
209 | Base,
210 | );
211 | mainGroup = E4A3319B1DAE0B3D00B59A16;
212 | productRefGroup = E4A331A51DAE0B3D00B59A16 /* Products */;
213 | projectDirPath = "";
214 | projectRoot = "";
215 | targets = (
216 | E4A331A31DAE0B3D00B59A16 /* SwiftDemo */,
217 | );
218 | };
219 | /* End PBXProject section */
220 |
221 | /* Begin PBXResourcesBuildPhase section */
222 | E4A331A21DAE0B3D00B59A16 /* Resources */ = {
223 | isa = PBXResourcesBuildPhase;
224 | buildActionMask = 2147483647;
225 | files = (
226 | E4D22BCF1DAE203C00EB8F7E /* avatar.png in Resources */,
227 | E4D22BD01DAE203C00EB8F7E /* haha.png in Resources */,
228 | E4D22BD11DAE203C00EB8F7E /* play@2x.png in Resources */,
229 | E4A331B21DAE0B3D00B59A16 /* LaunchScreen.storyboard in Resources */,
230 | E4A331AF1DAE0B3D00B59A16 /* Assets.xcassets in Resources */,
231 | E4D22BD21DAE203C00EB8F7E /* test.txt in Resources */,
232 | E4A331AD1DAE0B3D00B59A16 /* Main.storyboard in Resources */,
233 | );
234 | runOnlyForDeploymentPostprocessing = 0;
235 | };
236 | /* End PBXResourcesBuildPhase section */
237 |
238 | /* Begin PBXShellScriptBuildPhase section */
239 | 0E44B47670F8F73369558D69 /* [CP] Check Pods Manifest.lock */ = {
240 | isa = PBXShellScriptBuildPhase;
241 | buildActionMask = 2147483647;
242 | files = (
243 | );
244 | inputPaths = (
245 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
246 | "${PODS_ROOT}/Manifest.lock",
247 | );
248 | name = "[CP] Check Pods Manifest.lock";
249 | outputPaths = (
250 | "$(DERIVED_FILE_DIR)/Pods-SwiftDemo-checkManifestLockResult.txt",
251 | );
252 | runOnlyForDeploymentPostprocessing = 0;
253 | shellPath = /bin/sh;
254 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
255 | showEnvVarsInLog = 0;
256 | };
257 | /* End PBXShellScriptBuildPhase section */
258 |
259 | /* Begin PBXSourcesBuildPhase section */
260 | E4A331A01DAE0B3D00B59A16 /* Sources */ = {
261 | isa = PBXSourcesBuildPhase;
262 | buildActionMask = 2147483647;
263 | files = (
264 | E4A331AA1DAE0B3D00B59A16 /* ViewController.swift in Sources */,
265 | E4A331A81DAE0B3D00B59A16 /* AppDelegate.swift in Sources */,
266 | E4D22BD41DAE227700EB8F7E /* LinksViewController.swift in Sources */,
267 | E4D22BDC1DAE348500EB8F7E /* LongTextViewController.swift in Sources */,
268 | E40951AE1DAF27E300773E64 /* LineBreakModeViewController.swift in Sources */,
269 | E4D22BC01DAE180100EB8F7E /* CustomTextViewController.swift in Sources */,
270 | E4A331E61DAE14CB00B59A16 /* BaseViewController.swift in Sources */,
271 | E4D22BC91DAE191C00EB8F7E /* Util.swift in Sources */,
272 | E4D22BD81DAE315300EB8F7E /* ImagesViewController.swift in Sources */,
273 | E40951B01DAF2ACC00773E64 /* TextAlignmentViewController.swift in Sources */,
274 | E4D22BDA1DAE325500EB8F7E /* AttachmentViewController.swift in Sources */,
275 | E4A331E21DAE0FDD00B59A16 /* DemoTableViewController.swift in Sources */,
276 | E4D22BBE1DAE166C00EB8F7E /* BasicAttributedLabelViewController.swift in Sources */,
277 | );
278 | runOnlyForDeploymentPostprocessing = 0;
279 | };
280 | /* End PBXSourcesBuildPhase section */
281 |
282 | /* Begin PBXVariantGroup section */
283 | E4A331AB1DAE0B3D00B59A16 /* Main.storyboard */ = {
284 | isa = PBXVariantGroup;
285 | children = (
286 | E4A331AC1DAE0B3D00B59A16 /* Base */,
287 | );
288 | name = Main.storyboard;
289 | sourceTree = "";
290 | };
291 | E4A331B01DAE0B3D00B59A16 /* LaunchScreen.storyboard */ = {
292 | isa = PBXVariantGroup;
293 | children = (
294 | E4A331B11DAE0B3D00B59A16 /* Base */,
295 | );
296 | name = LaunchScreen.storyboard;
297 | sourceTree = "";
298 | };
299 | /* End PBXVariantGroup section */
300 |
301 | /* Begin XCBuildConfiguration section */
302 | E4A331B41DAE0B3D00B59A16 /* Debug */ = {
303 | isa = XCBuildConfiguration;
304 | buildSettings = {
305 | ALWAYS_SEARCH_USER_PATHS = NO;
306 | CLANG_ANALYZER_NONNULL = YES;
307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
308 | CLANG_CXX_LIBRARY = "libc++";
309 | CLANG_ENABLE_MODULES = YES;
310 | CLANG_ENABLE_OBJC_ARC = YES;
311 | CLANG_WARN_BOOL_CONVERSION = YES;
312 | CLANG_WARN_CONSTANT_CONVERSION = YES;
313 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
314 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
315 | CLANG_WARN_EMPTY_BODY = YES;
316 | CLANG_WARN_ENUM_CONVERSION = YES;
317 | CLANG_WARN_INFINITE_RECURSION = YES;
318 | CLANG_WARN_INT_CONVERSION = YES;
319 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
320 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
321 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
322 | CLANG_WARN_UNREACHABLE_CODE = YES;
323 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
324 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
325 | COPY_PHASE_STRIP = NO;
326 | DEBUG_INFORMATION_FORMAT = dwarf;
327 | ENABLE_STRICT_OBJC_MSGSEND = YES;
328 | ENABLE_TESTABILITY = YES;
329 | GCC_C_LANGUAGE_STANDARD = gnu99;
330 | GCC_DYNAMIC_NO_PIC = NO;
331 | GCC_NO_COMMON_BLOCKS = YES;
332 | GCC_OPTIMIZATION_LEVEL = 0;
333 | GCC_PREPROCESSOR_DEFINITIONS = (
334 | "DEBUG=1",
335 | "$(inherited)",
336 | );
337 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
338 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
339 | GCC_WARN_UNDECLARED_SELECTOR = YES;
340 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
341 | GCC_WARN_UNUSED_FUNCTION = YES;
342 | GCC_WARN_UNUSED_VARIABLE = YES;
343 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
344 | MTL_ENABLE_DEBUG_INFO = YES;
345 | ONLY_ACTIVE_ARCH = YES;
346 | SDKROOT = iphoneos;
347 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
348 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
349 | };
350 | name = Debug;
351 | };
352 | E4A331B51DAE0B3D00B59A16 /* Release */ = {
353 | isa = XCBuildConfiguration;
354 | buildSettings = {
355 | ALWAYS_SEARCH_USER_PATHS = NO;
356 | CLANG_ANALYZER_NONNULL = YES;
357 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
358 | CLANG_CXX_LIBRARY = "libc++";
359 | CLANG_ENABLE_MODULES = YES;
360 | CLANG_ENABLE_OBJC_ARC = YES;
361 | CLANG_WARN_BOOL_CONVERSION = YES;
362 | CLANG_WARN_CONSTANT_CONVERSION = YES;
363 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
364 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
365 | CLANG_WARN_EMPTY_BODY = YES;
366 | CLANG_WARN_ENUM_CONVERSION = YES;
367 | CLANG_WARN_INFINITE_RECURSION = YES;
368 | CLANG_WARN_INT_CONVERSION = YES;
369 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
370 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
371 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
372 | CLANG_WARN_UNREACHABLE_CODE = YES;
373 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
374 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
375 | COPY_PHASE_STRIP = NO;
376 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
377 | ENABLE_NS_ASSERTIONS = NO;
378 | ENABLE_STRICT_OBJC_MSGSEND = YES;
379 | GCC_C_LANGUAGE_STANDARD = gnu99;
380 | GCC_NO_COMMON_BLOCKS = YES;
381 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
382 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
383 | GCC_WARN_UNDECLARED_SELECTOR = YES;
384 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
385 | GCC_WARN_UNUSED_FUNCTION = YES;
386 | GCC_WARN_UNUSED_VARIABLE = YES;
387 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
388 | MTL_ENABLE_DEBUG_INFO = NO;
389 | SDKROOT = iphoneos;
390 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
391 | VALIDATE_PRODUCT = YES;
392 | };
393 | name = Release;
394 | };
395 | E4A331B71DAE0B3D00B59A16 /* Debug */ = {
396 | isa = XCBuildConfiguration;
397 | baseConfigurationReference = C43C45C0E63F53F1B14DF04D /* Pods-SwiftDemo.debug.xcconfig */;
398 | buildSettings = {
399 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
400 | CLANG_ENABLE_MODULES = YES;
401 | DEVELOPMENT_TEAM = L5CU59RTNH;
402 | INFOPLIST_FILE = SwiftDemo/Info.plist;
403 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
404 | PRODUCT_BUNDLE_IDENTIFIER = com.xiangwangfeng.www.SwiftDemo;
405 | PRODUCT_NAME = "$(TARGET_NAME)";
406 | SWIFT_OBJC_BRIDGING_HEADER = "Classes/SwiftDemo-Bridging-Header.h";
407 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
408 | SWIFT_VERSION = 5.0;
409 | };
410 | name = Debug;
411 | };
412 | E4A331B81DAE0B3D00B59A16 /* Release */ = {
413 | isa = XCBuildConfiguration;
414 | baseConfigurationReference = 4BCEAB4CF3E5C6DDE3B882EA /* Pods-SwiftDemo.release.xcconfig */;
415 | buildSettings = {
416 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
417 | CLANG_ENABLE_MODULES = YES;
418 | DEVELOPMENT_TEAM = L5CU59RTNH;
419 | INFOPLIST_FILE = SwiftDemo/Info.plist;
420 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
421 | PRODUCT_BUNDLE_IDENTIFIER = com.xiangwangfeng.www.SwiftDemo;
422 | PRODUCT_NAME = "$(TARGET_NAME)";
423 | SWIFT_OBJC_BRIDGING_HEADER = "Classes/SwiftDemo-Bridging-Header.h";
424 | SWIFT_VERSION = 5.0;
425 | };
426 | name = Release;
427 | };
428 | /* End XCBuildConfiguration section */
429 |
430 | /* Begin XCConfigurationList section */
431 | E4A3319F1DAE0B3D00B59A16 /* Build configuration list for PBXProject "SwiftDemo" */ = {
432 | isa = XCConfigurationList;
433 | buildConfigurations = (
434 | E4A331B41DAE0B3D00B59A16 /* Debug */,
435 | E4A331B51DAE0B3D00B59A16 /* Release */,
436 | );
437 | defaultConfigurationIsVisible = 0;
438 | defaultConfigurationName = Release;
439 | };
440 | E4A331B61DAE0B3D00B59A16 /* Build configuration list for PBXNativeTarget "SwiftDemo" */ = {
441 | isa = XCConfigurationList;
442 | buildConfigurations = (
443 | E4A331B71DAE0B3D00B59A16 /* Debug */,
444 | E4A331B81DAE0B3D00B59A16 /* Release */,
445 | );
446 | defaultConfigurationIsVisible = 0;
447 | defaultConfigurationName = Release;
448 | };
449 | /* End XCConfigurationList section */
450 | };
451 | rootObject = E4A3319C1DAE0B3D00B59A16 /* Project object */;
452 | }
453 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SwiftDemo
4 | //
5 | // Created by amao on 2016/10/12.
6 | // Copyright © 2016年 amao. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 |
19 | self.window = UIWindow(frame: UIScreen.main.bounds)
20 | let vc = DemoTableViewController()
21 | let nav = UINavigationController(rootViewController: vc)
22 | self.window?.rootViewController = nav
23 | self.window?.makeKeyAndVisible()
24 | return true
25 | }
26 |
27 | func applicationWillResignActive(_ application: UIApplication) {
28 | }
29 |
30 | func applicationDidEnterBackground(_ application: UIApplication) {
31 | }
32 |
33 | func applicationWillEnterForeground(_ application: UIApplication) {
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | }
38 |
39 | func applicationWillTerminate(_ application: UIApplication) {
40 |
41 | }
42 |
43 |
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/SwiftDemo/SwiftDemo/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SwiftDemo
4 | //
5 | // Created by amao on 2016/10/12.
6 | // Copyright © 2016年 amao. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | class ViewController: UIViewController {
13 |
14 | override func viewDidLoad() {
15 | super.viewDidLoad()
16 |
17 | }
18 |
19 | override func didReceiveMemoryWarning() {
20 | super.didReceiveMemoryWarning()
21 | }
22 |
23 |
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/pod_push.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import os
3 | import re
4 |
5 | pod_spec_filename = 'M80AttributedLabel.podspec'
6 |
7 | def run():
8 | new_version = get_new_version()
9 | old_version = get_old_version()
10 | print('current version is [' + old_version + ']')
11 | if new_version is not None and old_version is not None:
12 | question = 'do u want to upgrade current pod to \'' + new_version + '\' ? (y/n)\n'
13 | choice = input(question).lower()
14 | if choice == 'y' or choice == 'yes':
15 | update(old_version,new_version)
16 |
17 | def update(old_version,new_version):
18 |
19 | if run_shell('pod lib lint --no-clean') != 0:
20 | return
21 |
22 | if update_pod_spec(old_version,new_version) == False:
23 | return
24 |
25 | git_add = 'git add .'
26 | git_commit = 'git commit . -m " pod version update to ' + new_version + '"'
27 | git_push = 'git push'
28 | git_add_tag = 'git tag ' + new_version
29 | git_push_tag = 'git push --tags'
30 | pod_push = 'pod trunk push ' + pod_spec_filename
31 |
32 | command_list = [git_add,git_commit,git_push,git_add_tag,git_push_tag,pod_push]
33 | for command in command_list:
34 | run_shell(command)
35 |
36 |
37 |
38 |
39 | def get_old_version():
40 | old_version = None
41 | version_pattern = r"\s*s.version\s+=\s+'(\d+.\d+.\d+)'"
42 | pod_file = './' + pod_spec_filename
43 | with open(pod_file) as podspec:
44 | content = podspec.read()
45 | old_version = re.search(version_pattern,content).group(1)
46 | return old_version
47 |
48 |
49 | def update_pod_spec(old_version,new_version):
50 | pod_file = './' + pod_spec_filename
51 | new_content = None
52 | with open(pod_file) as podspec:
53 | content = podspec.read()
54 | new_content = content.replace(old_version,new_version,1)
55 | if new_content is not None:
56 | with open(pod_file,'w') as podspec:
57 | podspec.write(new_content)
58 | return True
59 | return False
60 |
61 |
62 |
63 | def run_shell(command):
64 | return os.system(command)
65 |
66 |
67 | def get_new_version():
68 | version = None
69 | if len(sys.argv) == 2:
70 | candidate_version = sys.argv[1].strip()
71 | if is_valid_version(candidate_version):
72 | version = candidate_version
73 | else:
74 | print('version needed')
75 | return version
76 |
77 | def is_valid_version(version):
78 | valid = False
79 | components = version.split('.')
80 | if len(components) >= 3:
81 | for component in components:
82 | try:
83 | num = int(component)
84 | except:
85 | print('invalid version: ',version)
86 | return False
87 | valid = True
88 | if valid is False:
89 | print('invalid version: ',version)
90 | return valid
91 |
92 | if __name__ == '__main__':
93 | run()
--------------------------------------------------------------------------------