├── .gitignore ├── LICENSE ├── LMJHorizontalScrollText.podspec ├── LMJHorizontalScrollText ├── LMJHorizontalScrollText.h └── LMJHorizontalScrollText.m ├── LMJHorizontalScrollTextExample.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ ├── jerrylmj.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── limingjie.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── jerrylmj.xcuserdatad │ └── xcschemes │ │ └── xcschememanagement.plist │ └── limingjie.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── LMJHorizontalScrollTextExample ├── AppDelegate │ ├── AppDelegate.h │ └── AppDelegate.m ├── Demo-Base │ ├── ViewController.h │ └── ViewController.m ├── Demo-Storyboard │ ├── Demo-StoryboardVC.h │ ├── Demo-StoryboardVC.m │ └── Demo.storyboard ├── Demo-TableViewCell │ ├── Demo-TableViewCellVC.h │ └── Demo-TableViewCellVC.m └── Supporting Files │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── main.m ├── LMJHorizontalScrollTextExampleTests ├── Info.plist └── LMJHorizontalScrollTextExampleTests.m ├── LMJHorizontalScrollTextExampleUITests ├── Info.plist └── LMJHorizontalScrollTextExampleUITests.m ├── README.en.md ├── README.md └── demo.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | 3 | .DS_Store 4 | 5 | ## Build generated 6 | 7 | build/ 8 | 9 | DerivedData/ 10 | 11 | ## Various settings 12 | 13 | *.pbxuser 14 | 15 | !default.pbxuser 16 | 17 | *.mode1v3 18 | 19 | !default.mode1v3 20 | 21 | *.mode2v3 22 | 23 | !default.mode2v3 24 | 25 | *.perspectivev3 26 | 27 | !default.perspectivev3 28 | 29 | xcuserdata/ 30 | 31 | ## Other 32 | 33 | *.moved-aside 34 | 35 | *.xccheckout 36 | 37 | *.xcworkspace 38 | 39 | !default.xcworkspace 40 | 41 | ## Obj-C/Swift specific 42 | 43 | *.hmap 44 | 45 | *.ipa 46 | 47 | *.dSYM.zip 48 | 49 | *.dSYM 50 | 51 | # CocoaPods 52 | 53 | Pods 54 | 55 | !Podfile 56 | 57 | !Podfile.lock 58 | 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2019 LMJHorizontalScrollText (https://github.com/JerryLMJ/LMJHorizontalScrollText) 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. -------------------------------------------------------------------------------- /LMJHorizontalScrollText.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'LMJHorizontalScrollText' 3 | s.version = '2.0.2' 4 | s.summary = 'An easy way to use horizontal-scroll-text' 5 | s.homepage = 'https://github.com/JerryLMJ/LMJHorizontalScrollText' 6 | s.license = {:type => 'MIT', :file => 'LICENSE' } 7 | s.authors = {'JerryLMJ' => 'limingjie_mail@163.com'} 8 | s.platform = :ios, '8.0' 9 | s.source = {:git => 'https://github.com/JerryLMJ/LMJHorizontalScrollText.git', :tag => s.version} 10 | s.source_files = 'LMJHorizontalScrollText/**/*' 11 | s.requires_arc = true 12 | end 13 | -------------------------------------------------------------------------------- /LMJHorizontalScrollText/LMJHorizontalScrollText.h: -------------------------------------------------------------------------------- 1 | // 2 | // LMJHorizontalScrollText.h 3 | // LMJHorizontalScrollTextExample 4 | // 5 | // Created by LiMingjie on 2019/8/22. 6 | // Copyright © 2019 LMJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | /** 14 | 描述字符串滚动前端起始位置: 15 | */ 16 | typedef enum { 17 | LMJTextScrollContinuous, // 从控件内开始连续滚动 18 | LMJTextScrollIntermittent, // 从控件内开始间断滚动 19 | LMJTextScrollFromOutside, // 从控件外开始滚动 20 | LMJTextScrollWandering // 在控件中往返滚动(不受设置方向影响) 21 | }LMJTextScrollMode; 22 | 23 | /** 24 | 描述字符串移动的方向 25 | */ 26 | typedef enum { 27 | LMJTextScrollMoveLeft, 28 | LMJTextScrollMoveRight 29 | }LMJTextScrollMoveDirection; 30 | 31 | 32 | @interface LMJHorizontalScrollText : UIView 33 | 34 | @property (nonatomic,copy) NSString * text; 35 | @property (nonatomic,copy) UIFont * textFont; 36 | @property (nonatomic,copy) UIColor * textColor; 37 | 38 | @property (nonatomic,assign) CGFloat speed; 39 | 40 | @property (nonatomic,assign) LMJTextScrollMode moveMode; 41 | @property (nonatomic,assign) LMJTextScrollMoveDirection moveDirection; 42 | 43 | - (void)move; 44 | - (void)stop; 45 | 46 | @end 47 | 48 | NS_ASSUME_NONNULL_END 49 | -------------------------------------------------------------------------------- /LMJHorizontalScrollText/LMJHorizontalScrollText.m: -------------------------------------------------------------------------------- 1 | // 2 | // LMJHorizontalScrollText.m 3 | // LMJHorizontalScrollTextExample 4 | // 5 | // Created by LiMingjie on 2019/8/22. 6 | // Copyright © 2019 LMJ. All rights reserved. 7 | // 8 | 9 | #import "LMJHorizontalScrollText.h" 10 | 11 | @interface LMJHorizontalScrollText() 12 | 13 | @property (nonatomic, strong) UILabel * contentLabel1; 14 | @property (nonatomic, strong) UILabel * contentLabel2; 15 | 16 | @property (nonatomic, assign) CGFloat textWidth; 17 | @property (nonatomic, assign) int wanderingOffset; 18 | 19 | @property (nonatomic, strong) NSTimer * timer; 20 | 21 | @end 22 | 23 | @implementation LMJHorizontalScrollText 24 | { 25 | CGFloat _selfWidth; 26 | CGFloat _selfHeight; 27 | } 28 | 29 | #pragma mark - Init 30 | - (id)init{ 31 | self = [super init]; 32 | if (self) { 33 | self.frame = CGRectMake(0, 0, 100, 20); // 设置一个初始的frame 34 | } 35 | return self; 36 | } 37 | - (id)initWithFrame:(CGRect)frame{ 38 | self = [super initWithFrame:frame]; 39 | if (self) { 40 | [self setInitialSettings]; 41 | } 42 | return self; 43 | } 44 | - (void)awakeFromNib{ 45 | [super awakeFromNib]; 46 | [self setInitialSettings]; 47 | } 48 | 49 | - (void)layoutSubviews{ 50 | _selfWidth = self.frame.size.width; 51 | _selfHeight = self.frame.size.height; 52 | } 53 | 54 | - (void)setInitialSettings { 55 | self.clipsToBounds = YES; 56 | 57 | _contentLabel1 = nil; 58 | _contentLabel2 = nil; 59 | 60 | _text = @""; 61 | _textFont = [UIFont systemFontOfSize:12]; 62 | _textColor = [UIColor blackColor]; 63 | 64 | _speed = 0.03; 65 | _textWidth = 0; 66 | _wanderingOffset = -1; 67 | 68 | _moveMode = LMJTextScrollWandering; 69 | _moveDirection = LMJTextScrollMoveLeft; 70 | 71 | _timer = nil; 72 | 73 | _selfWidth = self.frame.size.width; 74 | _selfHeight = self.frame.size.height; 75 | } 76 | 77 | 78 | #pragma mark - Set 79 | - (void)setText:(NSString *)text{ 80 | if ([_text isEqualToString: text]) return; 81 | _text = text; 82 | [self updateTextWidth]; 83 | [self updateLabelsFrame]; 84 | if (_contentLabel1 != nil) { 85 | _contentLabel1.text = _text; 86 | } 87 | if (_contentLabel2 != nil) { 88 | _contentLabel2.text = _text; 89 | } 90 | } 91 | 92 | - (void)setTextFont:(UIFont *)textFont{ 93 | if (_textFont == textFont) return; 94 | _textFont = textFont; 95 | [self updateTextWidth]; 96 | [self updateLabelsFrame]; 97 | if (_contentLabel1 != nil) { 98 | _contentLabel1.font = _textFont; 99 | } 100 | if (_contentLabel2 != nil) { 101 | _contentLabel2.font = _textFont; 102 | } 103 | } 104 | 105 | - (void)setTextColor:(UIColor *)textColor{ 106 | _textColor = textColor; 107 | if (_contentLabel1 != nil) { 108 | _contentLabel1.textColor = _textColor; 109 | } 110 | if (_contentLabel2 != nil) { 111 | _contentLabel2.textColor = _textColor; 112 | } 113 | } 114 | 115 | - (void)setSpeed:(CGFloat)speed{ 116 | _speed = speed; 117 | [self move]; 118 | } 119 | 120 | - (void)setMoveMode:(LMJTextScrollMode)moveMode { 121 | _moveMode = moveMode; 122 | 123 | // if (self.text.length == 0) {//如果字符串长度为0,直接返回 124 | // return; 125 | // } 126 | 127 | if (_timer) { 128 | [_timer invalidate]; 129 | _timer = nil; 130 | } 131 | 132 | [self.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 133 | [obj removeFromSuperview]; 134 | obj = nil; 135 | }]; 136 | 137 | switch (self.moveMode) { 138 | case LMJTextScrollContinuous: 139 | { 140 | if (self.moveDirection == LMJTextScrollMoveLeft) { 141 | [self creatLabel1WithFrame1:CGRectMake(0, 0, _textWidth, _selfHeight) andLabel2WithFrame2:CGRectMake(_textWidth, 0, _textWidth, _selfHeight)]; 142 | }else{ 143 | [self creatLabel1WithFrame1:CGRectMake(_selfWidth -_textWidth, 0, _textWidth, _selfHeight) andLabel2WithFrame2:CGRectMake(_selfWidth -_textWidth -_textWidth, 0, _textWidth, _selfHeight)]; 144 | } 145 | }break; 146 | 147 | case LMJTextScrollIntermittent: 148 | { 149 | if (self.moveDirection == LMJTextScrollMoveLeft) { 150 | [self creatLabel1WithFrame:CGRectMake(0, 0, _textWidth, _selfHeight)]; 151 | }else{ 152 | [self creatLabel1WithFrame:CGRectMake(_selfWidth -_textWidth, 0, _textWidth, _selfHeight)]; 153 | } 154 | }break; 155 | 156 | case LMJTextScrollFromOutside: 157 | { 158 | if (self.moveDirection == LMJTextScrollMoveLeft) { 159 | [self creatLabel1WithFrame:CGRectMake(_selfWidth, 0, _textWidth, _selfHeight)]; 160 | }else{ 161 | [self creatLabel1WithFrame:CGRectMake(_textWidth, 0, _textWidth, _selfHeight)]; 162 | } 163 | }break; 164 | 165 | case LMJTextScrollWandering: 166 | { 167 | [self creatLabel1WithFrame:CGRectMake(0, 0, _textWidth, _selfHeight)]; 168 | }break; 169 | 170 | default: 171 | break; 172 | } 173 | 174 | if (!_timer) { 175 | [self move]; 176 | } 177 | } 178 | 179 | #pragma mark - Create Labels 180 | -(void)creatLabel1WithFrame:(CGRect)frame{ 181 | _contentLabel1 = [[UILabel alloc] initWithFrame:frame]; 182 | _contentLabel1.text = self.text; 183 | _contentLabel1.font = self.textFont; 184 | _contentLabel1.textColor = self.textColor; 185 | _contentLabel1.tag = 1001; 186 | _contentLabel1.backgroundColor = [UIColor clearColor]; 187 | [self addSubview:_contentLabel1]; 188 | 189 | if (_contentLabel2) { 190 | [_contentLabel2 removeFromSuperview]; 191 | _contentLabel2 = nil; 192 | } 193 | } 194 | -(void)creatLabel1WithFrame1:(CGRect)frame1 andLabel2WithFrame2:(CGRect)frame2{ 195 | [self creatLabel1WithFrame:frame1]; 196 | 197 | _contentLabel2 = [[UILabel alloc] initWithFrame:frame2]; 198 | _contentLabel2.text = self.text; 199 | _contentLabel2.font = self.textFont; 200 | _contentLabel2.textColor = self.textColor; 201 | _contentLabel2.tag = 1002; 202 | _contentLabel2.backgroundColor = [UIColor clearColor]; 203 | [self addSubview:_contentLabel2]; 204 | } 205 | 206 | 207 | #pragma mark - Util 208 | - (void)updateTextWidth { 209 | _textWidth = [self.text sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:self.textFont, NSFontAttributeName, nil]].width; 210 | } 211 | 212 | - (void)updateLabelsFrame { 213 | 214 | CGFloat label1_x = _contentLabel1.frame.origin.x; 215 | CGFloat label2_x = _contentLabel2.frame.origin.x; 216 | 217 | if (_contentLabel1 && _contentLabel2) { 218 | if (label1_x < label2_x) { 219 | _contentLabel1.frame = CGRectMake(label1_x, 0, _textWidth, _selfHeight); 220 | _contentLabel2.frame = CGRectMake(label1_x + _textWidth, 0, _textWidth, _selfHeight); 221 | } else { 222 | _contentLabel2.frame = CGRectMake(label2_x, 0, _textWidth, _selfHeight); 223 | _contentLabel1.frame = CGRectMake(label2_x + _textWidth, 0, _textWidth, _selfHeight); 224 | 225 | } 226 | } else { 227 | if (_contentLabel1) { 228 | _contentLabel1.frame = CGRectMake(label1_x, 0, _textWidth, _selfHeight); 229 | } 230 | if (_contentLabel2) { 231 | _contentLabel2.frame = CGRectMake(label2_x, 0, _textWidth, _selfHeight); 232 | } 233 | } 234 | } 235 | 236 | - (void)resetLabelsPosition { 237 | switch (self.moveMode) { 238 | case LMJTextScrollContinuous: 239 | { 240 | if (self.moveDirection == LMJTextScrollMoveLeft) { 241 | _contentLabel1.frame = CGRectMake(0, 0, _textWidth, _selfHeight); 242 | _contentLabel2.frame = CGRectMake(_textWidth, 0, _textWidth, _selfHeight); 243 | }else{ 244 | _contentLabel1.frame = CGRectMake(_selfWidth -_textWidth, 0, _textWidth, _selfHeight); 245 | _contentLabel2.frame = CGRectMake(_selfWidth -_textWidth -_textWidth, 0, _textWidth, _selfHeight); 246 | } 247 | }break; 248 | 249 | case LMJTextScrollIntermittent: 250 | { 251 | if (self.moveDirection == LMJTextScrollMoveLeft) { 252 | _contentLabel1.frame = CGRectMake(0, 0, _textWidth, _selfHeight); 253 | }else{ 254 | _contentLabel2.frame = CGRectMake(_selfWidth -_textWidth, 0, _textWidth, _selfHeight); 255 | } 256 | }break; 257 | 258 | case LMJTextScrollFromOutside: 259 | { 260 | if (self.moveDirection == LMJTextScrollMoveLeft) { 261 | _contentLabel1.frame = CGRectMake(_selfWidth, 0, _textWidth, _selfHeight); 262 | }else{ 263 | _contentLabel1.frame = CGRectMake(_textWidth, 0, _textWidth, _selfHeight); 264 | } 265 | }break; 266 | 267 | case LMJTextScrollWandering: 268 | { 269 | _contentLabel1.frame = CGRectMake(0, 0, _textWidth, _selfHeight); 270 | }break; 271 | 272 | default: 273 | break; 274 | } 275 | } 276 | 277 | #pragma mark - Move Action 278 | // LMJTextScrollContinuous 279 | -(void)moveContinuous{ 280 | if (self.moveDirection == LMJTextScrollMoveLeft) { 281 | _contentLabel1.frame = CGRectMake(_contentLabel1.frame.origin.x -1, 0, _textWidth, _selfHeight); 282 | _contentLabel2.frame = CGRectMake(_contentLabel2.frame.origin.x -1, 0, _textWidth, _selfHeight); 283 | if (_contentLabel1.frame.origin.x < -_textWidth) { 284 | _contentLabel1.frame = CGRectMake(_contentLabel2.frame.origin.x + _textWidth, 0, _textWidth, _selfHeight); 285 | } 286 | if (_contentLabel2.frame.origin.x < -_textWidth) { 287 | _contentLabel2.frame = CGRectMake(_contentLabel1.frame.origin.x + _textWidth, 0, _textWidth, _selfHeight); 288 | } 289 | }else{ 290 | _contentLabel1.frame = CGRectMake(_contentLabel1.frame.origin.x +1, 0, _textWidth, _selfHeight); 291 | _contentLabel2.frame = CGRectMake(_contentLabel2.frame.origin.x +1, 0, _textWidth, _selfHeight); 292 | if (_contentLabel1.frame.origin.x > _selfWidth) { 293 | _contentLabel1.frame = CGRectMake(_contentLabel2.frame.origin.x - _textWidth, 0, _textWidth, _selfHeight); 294 | } 295 | if (_contentLabel2.frame.origin.x > _selfWidth) { 296 | _contentLabel2.frame = CGRectMake(_contentLabel1.frame.origin.x - _textWidth, 0, _textWidth, _selfHeight); 297 | } 298 | } 299 | } 300 | // LMJTextScrollIntermittent 301 | -(void)moveIntermittent{ 302 | if (self.moveDirection == LMJTextScrollMoveLeft) { 303 | _contentLabel1.frame = CGRectMake(_contentLabel1.frame.origin.x -1, 0, _textWidth, _selfHeight); 304 | if (_contentLabel1.frame.origin.x < -_textWidth) { 305 | _contentLabel1.frame = CGRectMake(0, 0, _textWidth, _selfHeight); 306 | } 307 | }else{ 308 | _contentLabel1.frame = CGRectMake(_contentLabel1.frame.origin.x +1, 0, _textWidth, _selfHeight); 309 | if (_contentLabel1.frame.origin.x > _selfWidth) { 310 | _contentLabel1.frame = CGRectMake(_selfWidth -_textWidth, 0, _textWidth, _selfHeight); 311 | } 312 | } 313 | } 314 | // LMJTextScrollFromOutside 315 | -(void)moveFromOutside{ 316 | if (self.moveDirection == LMJTextScrollMoveLeft) { 317 | _contentLabel1.frame = CGRectMake(_contentLabel1.frame.origin.x -1, 0, _textWidth, _selfHeight); 318 | if (_contentLabel1.frame.origin.x < -_textWidth) { 319 | _contentLabel1.frame = CGRectMake(_selfWidth, 0, _textWidth, _selfHeight); 320 | } 321 | }else{ 322 | _contentLabel1.frame = CGRectMake(_contentLabel1.frame.origin.x +1, 0, _textWidth, _selfHeight); 323 | if (_contentLabel1.frame.origin.x > _selfWidth) { 324 | _contentLabel1.frame = CGRectMake(-_textWidth, 0, _textWidth, _selfHeight); 325 | } 326 | } 327 | } 328 | // LMJTextScrollWandering 329 | -(void)moveWandering{ 330 | if (_textWidth > _selfWidth) { 331 | _contentLabel1.frame = CGRectMake(_contentLabel1.frame.origin.x + _wanderingOffset, 0, _textWidth, _selfHeight); 332 | if (_contentLabel1.frame.origin.x < -(_textWidth -_selfWidth +2)) { 333 | _wanderingOffset = 1; 334 | } 335 | if (_contentLabel1.frame.origin.x > 2) { 336 | _wanderingOffset = -1; 337 | } 338 | }else if (_textWidth < _selfWidth){ 339 | _contentLabel1.frame = CGRectMake(_contentLabel1.frame.origin.x + _wanderingOffset, 0, _textWidth, _selfHeight); 340 | if (_contentLabel1.frame.origin.x < 0) { 341 | _wanderingOffset = 1; 342 | } 343 | if (_contentLabel1.frame.origin.x > _selfWidth - _textWidth) { 344 | _wanderingOffset = -1; 345 | } 346 | } 347 | } 348 | 349 | #pragma mark - API Methods 350 | - (void)move { 351 | if (_timer != nil) { 352 | [_timer invalidate]; 353 | _timer = nil; 354 | } 355 | switch (self.moveMode) { 356 | case LMJTextScrollContinuous: 357 | { 358 | _timer = [NSTimer scheduledTimerWithTimeInterval:self.speed target:self selector:@selector(moveContinuous) userInfo:nil repeats:YES]; 359 | } 360 | break; 361 | case LMJTextScrollIntermittent: 362 | { 363 | _timer = [NSTimer scheduledTimerWithTimeInterval:self.speed target:self selector:@selector(moveIntermittent) userInfo:nil repeats:YES]; 364 | } 365 | break; 366 | case LMJTextScrollFromOutside: 367 | { 368 | _timer = [NSTimer scheduledTimerWithTimeInterval:self.speed target:self selector:@selector(moveFromOutside) userInfo:nil repeats:YES]; 369 | } 370 | break; 371 | case LMJTextScrollWandering: 372 | { 373 | _timer = [NSTimer scheduledTimerWithTimeInterval:self.speed target:self selector:@selector(moveWandering) userInfo:nil repeats:YES]; 374 | } 375 | break; 376 | default: 377 | break; 378 | } 379 | [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes]; 380 | } 381 | 382 | - (void)stop { 383 | [_timer invalidate]; 384 | _timer = nil; 385 | [self resetLabelsPosition]; 386 | } 387 | 388 | - (void)dealloc { 389 | [_timer invalidate]; 390 | _timer = nil; 391 | } 392 | 393 | @end 394 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 999DE9C923AE524F0037BD94 /* Demo-TableViewCellVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 999DE9C823AE524F0037BD94 /* Demo-TableViewCellVC.m */; }; 11 | E4088A10230EAD0E0032CC9C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E4088A0F230EAD0E0032CC9C /* AppDelegate.m */; }; 12 | E4088A13230EAD0E0032CC9C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E4088A12230EAD0E0032CC9C /* ViewController.m */; }; 13 | E4088A16230EAD0E0032CC9C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4088A14230EAD0E0032CC9C /* Main.storyboard */; }; 14 | E4088A18230EAD0E0032CC9C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E4088A17230EAD0E0032CC9C /* Assets.xcassets */; }; 15 | E4088A1B230EAD0E0032CC9C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4088A19230EAD0E0032CC9C /* LaunchScreen.storyboard */; }; 16 | E4088A1E230EAD0E0032CC9C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E4088A1D230EAD0E0032CC9C /* main.m */; }; 17 | E4088A28230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E4088A27230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests.m */; }; 18 | E4088A33230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = E4088A32230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests.m */; }; 19 | E4088A43230EADA20032CC9C /* LMJHorizontalScrollText.m in Sources */ = {isa = PBXBuildFile; fileRef = E4088A42230EADA20032CC9C /* LMJHorizontalScrollText.m */; }; 20 | E479C2782338D2AE0076FAAC /* Demo-StoryboardVC.m in Sources */ = {isa = PBXBuildFile; fileRef = E479C2772338D2AE0076FAAC /* Demo-StoryboardVC.m */; }; 21 | E479C27A2338D2B90076FAAC /* Demo.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E479C2792338D2B90076FAAC /* Demo.storyboard */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | E4088A24230EAD0F0032CC9C /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = E4088A03230EAD0E0032CC9C /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = E4088A0A230EAD0E0032CC9C; 30 | remoteInfo = LMJHorizontalScrollTextExample; 31 | }; 32 | E4088A2F230EAD0F0032CC9C /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = E4088A03230EAD0E0032CC9C /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = E4088A0A230EAD0E0032CC9C; 37 | remoteInfo = LMJHorizontalScrollTextExample; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | 999DE9C723AE524F0037BD94 /* Demo-TableViewCellVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Demo-TableViewCellVC.h"; sourceTree = ""; }; 43 | 999DE9C823AE524F0037BD94 /* Demo-TableViewCellVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "Demo-TableViewCellVC.m"; sourceTree = ""; }; 44 | E4088A0B230EAD0E0032CC9C /* LMJHorizontalScrollTextExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LMJHorizontalScrollTextExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | E4088A0E230EAD0E0032CC9C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 46 | E4088A0F230EAD0E0032CC9C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 47 | E4088A11230EAD0E0032CC9C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 48 | E4088A12230EAD0E0032CC9C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 49 | E4088A15230EAD0E0032CC9C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 50 | E4088A17230EAD0E0032CC9C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 51 | E4088A1A230EAD0E0032CC9C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 52 | E4088A1C230EAD0E0032CC9C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53 | E4088A1D230EAD0E0032CC9C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 54 | E4088A23230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LMJHorizontalScrollTextExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | E4088A27230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LMJHorizontalScrollTextExampleTests.m; sourceTree = ""; }; 56 | E4088A29230EAD0F0032CC9C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | E4088A2E230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LMJHorizontalScrollTextExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | E4088A32230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LMJHorizontalScrollTextExampleUITests.m; sourceTree = ""; }; 59 | E4088A34230EAD0F0032CC9C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | E4088A41230EADA20032CC9C /* LMJHorizontalScrollText.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LMJHorizontalScrollText.h; sourceTree = ""; }; 61 | E4088A42230EADA20032CC9C /* LMJHorizontalScrollText.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LMJHorizontalScrollText.m; sourceTree = ""; }; 62 | E479C2762338D2AE0076FAAC /* Demo-StoryboardVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Demo-StoryboardVC.h"; sourceTree = ""; }; 63 | E479C2772338D2AE0076FAAC /* Demo-StoryboardVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "Demo-StoryboardVC.m"; sourceTree = ""; }; 64 | E479C2792338D2B90076FAAC /* Demo.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Demo.storyboard; sourceTree = ""; }; 65 | /* End PBXFileReference section */ 66 | 67 | /* Begin PBXFrameworksBuildPhase section */ 68 | E4088A08230EAD0E0032CC9C /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 2147483647; 71 | files = ( 72 | ); 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | E4088A20230EAD0F0032CC9C /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | E4088A2B230EAD0F0032CC9C /* Frameworks */ = { 83 | isa = PBXFrameworksBuildPhase; 84 | buildActionMask = 2147483647; 85 | files = ( 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | /* End PBXFrameworksBuildPhase section */ 90 | 91 | /* Begin PBXGroup section */ 92 | 999DE9C623AE51FF0037BD94 /* Demo-TableViewCell */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 999DE9C723AE524F0037BD94 /* Demo-TableViewCellVC.h */, 96 | 999DE9C823AE524F0037BD94 /* Demo-TableViewCellVC.m */, 97 | ); 98 | path = "Demo-TableViewCell"; 99 | sourceTree = ""; 100 | }; 101 | E4088A02230EAD0E0032CC9C = { 102 | isa = PBXGroup; 103 | children = ( 104 | E4088A40230EAD1A0032CC9C /* LMJHorizontalScrollText */, 105 | E4088A0D230EAD0E0032CC9C /* LMJHorizontalScrollTextExample */, 106 | E4088A26230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests */, 107 | E4088A31230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests */, 108 | E4088A0C230EAD0E0032CC9C /* Products */, 109 | ); 110 | sourceTree = ""; 111 | }; 112 | E4088A0C230EAD0E0032CC9C /* Products */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | E4088A0B230EAD0E0032CC9C /* LMJHorizontalScrollTextExample.app */, 116 | E4088A23230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests.xctest */, 117 | E4088A2E230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests.xctest */, 118 | ); 119 | name = Products; 120 | sourceTree = ""; 121 | }; 122 | E4088A0D230EAD0E0032CC9C /* LMJHorizontalScrollTextExample */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | E4088A46230F937C0032CC9C /* Demo-Base */, 126 | E479C2752338D2690076FAAC /* Demo-Storyboard */, 127 | 999DE9C623AE51FF0037BD94 /* Demo-TableViewCell */, 128 | E4088A45230EAE180032CC9C /* Supporting Files */, 129 | E4088A44230EADF70032CC9C /* AppDelegate */, 130 | ); 131 | path = LMJHorizontalScrollTextExample; 132 | sourceTree = ""; 133 | }; 134 | E4088A26230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | E4088A27230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests.m */, 138 | E4088A29230EAD0F0032CC9C /* Info.plist */, 139 | ); 140 | path = LMJHorizontalScrollTextExampleTests; 141 | sourceTree = ""; 142 | }; 143 | E4088A31230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | E4088A32230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests.m */, 147 | E4088A34230EAD0F0032CC9C /* Info.plist */, 148 | ); 149 | path = LMJHorizontalScrollTextExampleUITests; 150 | sourceTree = ""; 151 | }; 152 | E4088A40230EAD1A0032CC9C /* LMJHorizontalScrollText */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | E4088A41230EADA20032CC9C /* LMJHorizontalScrollText.h */, 156 | E4088A42230EADA20032CC9C /* LMJHorizontalScrollText.m */, 157 | ); 158 | path = LMJHorizontalScrollText; 159 | sourceTree = ""; 160 | }; 161 | E4088A44230EADF70032CC9C /* AppDelegate */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | E4088A0E230EAD0E0032CC9C /* AppDelegate.h */, 165 | E4088A0F230EAD0E0032CC9C /* AppDelegate.m */, 166 | ); 167 | path = AppDelegate; 168 | sourceTree = ""; 169 | }; 170 | E4088A45230EAE180032CC9C /* Supporting Files */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | E4088A14230EAD0E0032CC9C /* Main.storyboard */, 174 | E4088A17230EAD0E0032CC9C /* Assets.xcassets */, 175 | E4088A19230EAD0E0032CC9C /* LaunchScreen.storyboard */, 176 | E4088A1C230EAD0E0032CC9C /* Info.plist */, 177 | E4088A1D230EAD0E0032CC9C /* main.m */, 178 | ); 179 | path = "Supporting Files"; 180 | sourceTree = ""; 181 | }; 182 | E4088A46230F937C0032CC9C /* Demo-Base */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | E4088A11230EAD0E0032CC9C /* ViewController.h */, 186 | E4088A12230EAD0E0032CC9C /* ViewController.m */, 187 | ); 188 | path = "Demo-Base"; 189 | sourceTree = ""; 190 | }; 191 | E479C2752338D2690076FAAC /* Demo-Storyboard */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | E479C2762338D2AE0076FAAC /* Demo-StoryboardVC.h */, 195 | E479C2772338D2AE0076FAAC /* Demo-StoryboardVC.m */, 196 | E479C2792338D2B90076FAAC /* Demo.storyboard */, 197 | ); 198 | path = "Demo-Storyboard"; 199 | sourceTree = ""; 200 | }; 201 | /* End PBXGroup section */ 202 | 203 | /* Begin PBXNativeTarget section */ 204 | E4088A0A230EAD0E0032CC9C /* LMJHorizontalScrollTextExample */ = { 205 | isa = PBXNativeTarget; 206 | buildConfigurationList = E4088A37230EAD0F0032CC9C /* Build configuration list for PBXNativeTarget "LMJHorizontalScrollTextExample" */; 207 | buildPhases = ( 208 | E4088A07230EAD0E0032CC9C /* Sources */, 209 | E4088A08230EAD0E0032CC9C /* Frameworks */, 210 | E4088A09230EAD0E0032CC9C /* Resources */, 211 | ); 212 | buildRules = ( 213 | ); 214 | dependencies = ( 215 | ); 216 | name = LMJHorizontalScrollTextExample; 217 | productName = LMJHorizontalScrollTextExample; 218 | productReference = E4088A0B230EAD0E0032CC9C /* LMJHorizontalScrollTextExample.app */; 219 | productType = "com.apple.product-type.application"; 220 | }; 221 | E4088A22230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests */ = { 222 | isa = PBXNativeTarget; 223 | buildConfigurationList = E4088A3A230EAD0F0032CC9C /* Build configuration list for PBXNativeTarget "LMJHorizontalScrollTextExampleTests" */; 224 | buildPhases = ( 225 | E4088A1F230EAD0F0032CC9C /* Sources */, 226 | E4088A20230EAD0F0032CC9C /* Frameworks */, 227 | E4088A21230EAD0F0032CC9C /* Resources */, 228 | ); 229 | buildRules = ( 230 | ); 231 | dependencies = ( 232 | E4088A25230EAD0F0032CC9C /* PBXTargetDependency */, 233 | ); 234 | name = LMJHorizontalScrollTextExampleTests; 235 | productName = LMJHorizontalScrollTextExampleTests; 236 | productReference = E4088A23230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests.xctest */; 237 | productType = "com.apple.product-type.bundle.unit-test"; 238 | }; 239 | E4088A2D230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests */ = { 240 | isa = PBXNativeTarget; 241 | buildConfigurationList = E4088A3D230EAD0F0032CC9C /* Build configuration list for PBXNativeTarget "LMJHorizontalScrollTextExampleUITests" */; 242 | buildPhases = ( 243 | E4088A2A230EAD0F0032CC9C /* Sources */, 244 | E4088A2B230EAD0F0032CC9C /* Frameworks */, 245 | E4088A2C230EAD0F0032CC9C /* Resources */, 246 | ); 247 | buildRules = ( 248 | ); 249 | dependencies = ( 250 | E4088A30230EAD0F0032CC9C /* PBXTargetDependency */, 251 | ); 252 | name = LMJHorizontalScrollTextExampleUITests; 253 | productName = LMJHorizontalScrollTextExampleUITests; 254 | productReference = E4088A2E230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests.xctest */; 255 | productType = "com.apple.product-type.bundle.ui-testing"; 256 | }; 257 | /* End PBXNativeTarget section */ 258 | 259 | /* Begin PBXProject section */ 260 | E4088A03230EAD0E0032CC9C /* Project object */ = { 261 | isa = PBXProject; 262 | attributes = { 263 | LastUpgradeCheck = 1030; 264 | ORGANIZATIONNAME = LMJ; 265 | TargetAttributes = { 266 | E4088A0A230EAD0E0032CC9C = { 267 | CreatedOnToolsVersion = 10.3; 268 | }; 269 | E4088A22230EAD0F0032CC9C = { 270 | CreatedOnToolsVersion = 10.3; 271 | TestTargetID = E4088A0A230EAD0E0032CC9C; 272 | }; 273 | E4088A2D230EAD0F0032CC9C = { 274 | CreatedOnToolsVersion = 10.3; 275 | TestTargetID = E4088A0A230EAD0E0032CC9C; 276 | }; 277 | }; 278 | }; 279 | buildConfigurationList = E4088A06230EAD0E0032CC9C /* Build configuration list for PBXProject "LMJHorizontalScrollTextExample" */; 280 | compatibilityVersion = "Xcode 9.3"; 281 | developmentRegion = en; 282 | hasScannedForEncodings = 0; 283 | knownRegions = ( 284 | en, 285 | Base, 286 | ); 287 | mainGroup = E4088A02230EAD0E0032CC9C; 288 | productRefGroup = E4088A0C230EAD0E0032CC9C /* Products */; 289 | projectDirPath = ""; 290 | projectRoot = ""; 291 | targets = ( 292 | E4088A0A230EAD0E0032CC9C /* LMJHorizontalScrollTextExample */, 293 | E4088A22230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests */, 294 | E4088A2D230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests */, 295 | ); 296 | }; 297 | /* End PBXProject section */ 298 | 299 | /* Begin PBXResourcesBuildPhase section */ 300 | E4088A09230EAD0E0032CC9C /* Resources */ = { 301 | isa = PBXResourcesBuildPhase; 302 | buildActionMask = 2147483647; 303 | files = ( 304 | E4088A1B230EAD0E0032CC9C /* LaunchScreen.storyboard in Resources */, 305 | E4088A18230EAD0E0032CC9C /* Assets.xcassets in Resources */, 306 | E4088A16230EAD0E0032CC9C /* Main.storyboard in Resources */, 307 | E479C27A2338D2B90076FAAC /* Demo.storyboard in Resources */, 308 | ); 309 | runOnlyForDeploymentPostprocessing = 0; 310 | }; 311 | E4088A21230EAD0F0032CC9C /* Resources */ = { 312 | isa = PBXResourcesBuildPhase; 313 | buildActionMask = 2147483647; 314 | files = ( 315 | ); 316 | runOnlyForDeploymentPostprocessing = 0; 317 | }; 318 | E4088A2C230EAD0F0032CC9C /* Resources */ = { 319 | isa = PBXResourcesBuildPhase; 320 | buildActionMask = 2147483647; 321 | files = ( 322 | ); 323 | runOnlyForDeploymentPostprocessing = 0; 324 | }; 325 | /* End PBXResourcesBuildPhase section */ 326 | 327 | /* Begin PBXSourcesBuildPhase section */ 328 | E4088A07230EAD0E0032CC9C /* Sources */ = { 329 | isa = PBXSourcesBuildPhase; 330 | buildActionMask = 2147483647; 331 | files = ( 332 | E4088A13230EAD0E0032CC9C /* ViewController.m in Sources */, 333 | E4088A43230EADA20032CC9C /* LMJHorizontalScrollText.m in Sources */, 334 | E4088A1E230EAD0E0032CC9C /* main.m in Sources */, 335 | E4088A10230EAD0E0032CC9C /* AppDelegate.m in Sources */, 336 | E479C2782338D2AE0076FAAC /* Demo-StoryboardVC.m in Sources */, 337 | 999DE9C923AE524F0037BD94 /* Demo-TableViewCellVC.m in Sources */, 338 | ); 339 | runOnlyForDeploymentPostprocessing = 0; 340 | }; 341 | E4088A1F230EAD0F0032CC9C /* Sources */ = { 342 | isa = PBXSourcesBuildPhase; 343 | buildActionMask = 2147483647; 344 | files = ( 345 | E4088A28230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleTests.m in Sources */, 346 | ); 347 | runOnlyForDeploymentPostprocessing = 0; 348 | }; 349 | E4088A2A230EAD0F0032CC9C /* Sources */ = { 350 | isa = PBXSourcesBuildPhase; 351 | buildActionMask = 2147483647; 352 | files = ( 353 | E4088A33230EAD0F0032CC9C /* LMJHorizontalScrollTextExampleUITests.m in Sources */, 354 | ); 355 | runOnlyForDeploymentPostprocessing = 0; 356 | }; 357 | /* End PBXSourcesBuildPhase section */ 358 | 359 | /* Begin PBXTargetDependency section */ 360 | E4088A25230EAD0F0032CC9C /* PBXTargetDependency */ = { 361 | isa = PBXTargetDependency; 362 | target = E4088A0A230EAD0E0032CC9C /* LMJHorizontalScrollTextExample */; 363 | targetProxy = E4088A24230EAD0F0032CC9C /* PBXContainerItemProxy */; 364 | }; 365 | E4088A30230EAD0F0032CC9C /* PBXTargetDependency */ = { 366 | isa = PBXTargetDependency; 367 | target = E4088A0A230EAD0E0032CC9C /* LMJHorizontalScrollTextExample */; 368 | targetProxy = E4088A2F230EAD0F0032CC9C /* PBXContainerItemProxy */; 369 | }; 370 | /* End PBXTargetDependency section */ 371 | 372 | /* Begin PBXVariantGroup section */ 373 | E4088A14230EAD0E0032CC9C /* Main.storyboard */ = { 374 | isa = PBXVariantGroup; 375 | children = ( 376 | E4088A15230EAD0E0032CC9C /* Base */, 377 | ); 378 | name = Main.storyboard; 379 | sourceTree = ""; 380 | }; 381 | E4088A19230EAD0E0032CC9C /* LaunchScreen.storyboard */ = { 382 | isa = PBXVariantGroup; 383 | children = ( 384 | E4088A1A230EAD0E0032CC9C /* Base */, 385 | ); 386 | name = LaunchScreen.storyboard; 387 | sourceTree = ""; 388 | }; 389 | /* End PBXVariantGroup section */ 390 | 391 | /* Begin XCBuildConfiguration section */ 392 | E4088A35230EAD0F0032CC9C /* Debug */ = { 393 | isa = XCBuildConfiguration; 394 | buildSettings = { 395 | ALWAYS_SEARCH_USER_PATHS = NO; 396 | CLANG_ANALYZER_NONNULL = YES; 397 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 398 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 399 | CLANG_CXX_LIBRARY = "libc++"; 400 | CLANG_ENABLE_MODULES = YES; 401 | CLANG_ENABLE_OBJC_ARC = YES; 402 | CLANG_ENABLE_OBJC_WEAK = YES; 403 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 404 | CLANG_WARN_BOOL_CONVERSION = YES; 405 | CLANG_WARN_COMMA = YES; 406 | CLANG_WARN_CONSTANT_CONVERSION = YES; 407 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 408 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 409 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 410 | CLANG_WARN_EMPTY_BODY = YES; 411 | CLANG_WARN_ENUM_CONVERSION = YES; 412 | CLANG_WARN_INFINITE_RECURSION = YES; 413 | CLANG_WARN_INT_CONVERSION = YES; 414 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 415 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 416 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 417 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 418 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 419 | CLANG_WARN_STRICT_PROTOTYPES = YES; 420 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 421 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 422 | CLANG_WARN_UNREACHABLE_CODE = YES; 423 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 424 | CODE_SIGN_IDENTITY = "iPhone Developer"; 425 | COPY_PHASE_STRIP = NO; 426 | DEBUG_INFORMATION_FORMAT = dwarf; 427 | ENABLE_STRICT_OBJC_MSGSEND = YES; 428 | ENABLE_TESTABILITY = YES; 429 | GCC_C_LANGUAGE_STANDARD = gnu11; 430 | GCC_DYNAMIC_NO_PIC = NO; 431 | GCC_NO_COMMON_BLOCKS = YES; 432 | GCC_OPTIMIZATION_LEVEL = 0; 433 | GCC_PREPROCESSOR_DEFINITIONS = ( 434 | "DEBUG=1", 435 | "$(inherited)", 436 | ); 437 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 438 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 439 | GCC_WARN_UNDECLARED_SELECTOR = YES; 440 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 441 | GCC_WARN_UNUSED_FUNCTION = YES; 442 | GCC_WARN_UNUSED_VARIABLE = YES; 443 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 444 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 445 | MTL_FAST_MATH = YES; 446 | ONLY_ACTIVE_ARCH = YES; 447 | SDKROOT = iphoneos; 448 | }; 449 | name = Debug; 450 | }; 451 | E4088A36230EAD0F0032CC9C /* Release */ = { 452 | isa = XCBuildConfiguration; 453 | buildSettings = { 454 | ALWAYS_SEARCH_USER_PATHS = NO; 455 | CLANG_ANALYZER_NONNULL = YES; 456 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 457 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 458 | CLANG_CXX_LIBRARY = "libc++"; 459 | CLANG_ENABLE_MODULES = YES; 460 | CLANG_ENABLE_OBJC_ARC = YES; 461 | CLANG_ENABLE_OBJC_WEAK = YES; 462 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 463 | CLANG_WARN_BOOL_CONVERSION = YES; 464 | CLANG_WARN_COMMA = YES; 465 | CLANG_WARN_CONSTANT_CONVERSION = YES; 466 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 467 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 468 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 469 | CLANG_WARN_EMPTY_BODY = YES; 470 | CLANG_WARN_ENUM_CONVERSION = YES; 471 | CLANG_WARN_INFINITE_RECURSION = YES; 472 | CLANG_WARN_INT_CONVERSION = YES; 473 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 474 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 475 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 476 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 477 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 478 | CLANG_WARN_STRICT_PROTOTYPES = YES; 479 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 480 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 481 | CLANG_WARN_UNREACHABLE_CODE = YES; 482 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 483 | CODE_SIGN_IDENTITY = "iPhone Developer"; 484 | COPY_PHASE_STRIP = NO; 485 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 486 | ENABLE_NS_ASSERTIONS = NO; 487 | ENABLE_STRICT_OBJC_MSGSEND = YES; 488 | GCC_C_LANGUAGE_STANDARD = gnu11; 489 | GCC_NO_COMMON_BLOCKS = YES; 490 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 491 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 492 | GCC_WARN_UNDECLARED_SELECTOR = YES; 493 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 494 | GCC_WARN_UNUSED_FUNCTION = YES; 495 | GCC_WARN_UNUSED_VARIABLE = YES; 496 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 497 | MTL_ENABLE_DEBUG_INFO = NO; 498 | MTL_FAST_MATH = YES; 499 | SDKROOT = iphoneos; 500 | VALIDATE_PRODUCT = YES; 501 | }; 502 | name = Release; 503 | }; 504 | E4088A38230EAD0F0032CC9C /* Debug */ = { 505 | isa = XCBuildConfiguration; 506 | buildSettings = { 507 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 508 | CODE_SIGN_STYLE = Automatic; 509 | DEVELOPMENT_TEAM = BEDD2XY992; 510 | INFOPLIST_FILE = "$(SRCROOT)/LMJHorizontalScrollTextExample/Supporting Files/Info.plist"; 511 | LD_RUNPATH_SEARCH_PATHS = ( 512 | "$(inherited)", 513 | "@executable_path/Frameworks", 514 | ); 515 | PRODUCT_BUNDLE_IDENTIFIER = com.LMJ.LMJHorizontalScrollTextExample; 516 | PRODUCT_NAME = "$(TARGET_NAME)"; 517 | TARGETED_DEVICE_FAMILY = "1,2"; 518 | }; 519 | name = Debug; 520 | }; 521 | E4088A39230EAD0F0032CC9C /* Release */ = { 522 | isa = XCBuildConfiguration; 523 | buildSettings = { 524 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 525 | CODE_SIGN_STYLE = Automatic; 526 | DEVELOPMENT_TEAM = BEDD2XY992; 527 | INFOPLIST_FILE = "$(SRCROOT)/LMJHorizontalScrollTextExample/Supporting Files/Info.plist"; 528 | LD_RUNPATH_SEARCH_PATHS = ( 529 | "$(inherited)", 530 | "@executable_path/Frameworks", 531 | ); 532 | PRODUCT_BUNDLE_IDENTIFIER = com.LMJ.LMJHorizontalScrollTextExample; 533 | PRODUCT_NAME = "$(TARGET_NAME)"; 534 | TARGETED_DEVICE_FAMILY = "1,2"; 535 | }; 536 | name = Release; 537 | }; 538 | E4088A3B230EAD0F0032CC9C /* Debug */ = { 539 | isa = XCBuildConfiguration; 540 | buildSettings = { 541 | BUNDLE_LOADER = "$(TEST_HOST)"; 542 | CODE_SIGN_STYLE = Automatic; 543 | DEVELOPMENT_TEAM = BEDD2XY992; 544 | INFOPLIST_FILE = LMJHorizontalScrollTextExampleTests/Info.plist; 545 | LD_RUNPATH_SEARCH_PATHS = ( 546 | "$(inherited)", 547 | "@executable_path/Frameworks", 548 | "@loader_path/Frameworks", 549 | ); 550 | PRODUCT_BUNDLE_IDENTIFIER = com.LMJ.LMJHorizontalScrollTextExampleTests; 551 | PRODUCT_NAME = "$(TARGET_NAME)"; 552 | TARGETED_DEVICE_FAMILY = "1,2"; 553 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LMJHorizontalScrollTextExample.app/LMJHorizontalScrollTextExample"; 554 | }; 555 | name = Debug; 556 | }; 557 | E4088A3C230EAD0F0032CC9C /* Release */ = { 558 | isa = XCBuildConfiguration; 559 | buildSettings = { 560 | BUNDLE_LOADER = "$(TEST_HOST)"; 561 | CODE_SIGN_STYLE = Automatic; 562 | DEVELOPMENT_TEAM = BEDD2XY992; 563 | INFOPLIST_FILE = LMJHorizontalScrollTextExampleTests/Info.plist; 564 | LD_RUNPATH_SEARCH_PATHS = ( 565 | "$(inherited)", 566 | "@executable_path/Frameworks", 567 | "@loader_path/Frameworks", 568 | ); 569 | PRODUCT_BUNDLE_IDENTIFIER = com.LMJ.LMJHorizontalScrollTextExampleTests; 570 | PRODUCT_NAME = "$(TARGET_NAME)"; 571 | TARGETED_DEVICE_FAMILY = "1,2"; 572 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LMJHorizontalScrollTextExample.app/LMJHorizontalScrollTextExample"; 573 | }; 574 | name = Release; 575 | }; 576 | E4088A3E230EAD0F0032CC9C /* Debug */ = { 577 | isa = XCBuildConfiguration; 578 | buildSettings = { 579 | CODE_SIGN_STYLE = Automatic; 580 | DEVELOPMENT_TEAM = BEDD2XY992; 581 | INFOPLIST_FILE = LMJHorizontalScrollTextExampleUITests/Info.plist; 582 | LD_RUNPATH_SEARCH_PATHS = ( 583 | "$(inherited)", 584 | "@executable_path/Frameworks", 585 | "@loader_path/Frameworks", 586 | ); 587 | PRODUCT_BUNDLE_IDENTIFIER = com.LMJ.LMJHorizontalScrollTextExampleUITests; 588 | PRODUCT_NAME = "$(TARGET_NAME)"; 589 | TARGETED_DEVICE_FAMILY = "1,2"; 590 | TEST_TARGET_NAME = LMJHorizontalScrollTextExample; 591 | }; 592 | name = Debug; 593 | }; 594 | E4088A3F230EAD0F0032CC9C /* Release */ = { 595 | isa = XCBuildConfiguration; 596 | buildSettings = { 597 | CODE_SIGN_STYLE = Automatic; 598 | DEVELOPMENT_TEAM = BEDD2XY992; 599 | INFOPLIST_FILE = LMJHorizontalScrollTextExampleUITests/Info.plist; 600 | LD_RUNPATH_SEARCH_PATHS = ( 601 | "$(inherited)", 602 | "@executable_path/Frameworks", 603 | "@loader_path/Frameworks", 604 | ); 605 | PRODUCT_BUNDLE_IDENTIFIER = com.LMJ.LMJHorizontalScrollTextExampleUITests; 606 | PRODUCT_NAME = "$(TARGET_NAME)"; 607 | TARGETED_DEVICE_FAMILY = "1,2"; 608 | TEST_TARGET_NAME = LMJHorizontalScrollTextExample; 609 | }; 610 | name = Release; 611 | }; 612 | /* End XCBuildConfiguration section */ 613 | 614 | /* Begin XCConfigurationList section */ 615 | E4088A06230EAD0E0032CC9C /* Build configuration list for PBXProject "LMJHorizontalScrollTextExample" */ = { 616 | isa = XCConfigurationList; 617 | buildConfigurations = ( 618 | E4088A35230EAD0F0032CC9C /* Debug */, 619 | E4088A36230EAD0F0032CC9C /* Release */, 620 | ); 621 | defaultConfigurationIsVisible = 0; 622 | defaultConfigurationName = Release; 623 | }; 624 | E4088A37230EAD0F0032CC9C /* Build configuration list for PBXNativeTarget "LMJHorizontalScrollTextExample" */ = { 625 | isa = XCConfigurationList; 626 | buildConfigurations = ( 627 | E4088A38230EAD0F0032CC9C /* Debug */, 628 | E4088A39230EAD0F0032CC9C /* Release */, 629 | ); 630 | defaultConfigurationIsVisible = 0; 631 | defaultConfigurationName = Release; 632 | }; 633 | E4088A3A230EAD0F0032CC9C /* Build configuration list for PBXNativeTarget "LMJHorizontalScrollTextExampleTests" */ = { 634 | isa = XCConfigurationList; 635 | buildConfigurations = ( 636 | E4088A3B230EAD0F0032CC9C /* Debug */, 637 | E4088A3C230EAD0F0032CC9C /* Release */, 638 | ); 639 | defaultConfigurationIsVisible = 0; 640 | defaultConfigurationName = Release; 641 | }; 642 | E4088A3D230EAD0F0032CC9C /* Build configuration list for PBXNativeTarget "LMJHorizontalScrollTextExampleUITests" */ = { 643 | isa = XCConfigurationList; 644 | buildConfigurations = ( 645 | E4088A3E230EAD0F0032CC9C /* Debug */, 646 | E4088A3F230EAD0F0032CC9C /* Release */, 647 | ); 648 | defaultConfigurationIsVisible = 0; 649 | defaultConfigurationName = Release; 650 | }; 651 | /* End XCConfigurationList section */ 652 | }; 653 | rootObject = E4088A03230EAD0E0032CC9C /* Project object */; 654 | } 655 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample.xcodeproj/project.xcworkspace/xcuserdata/jerrylmj.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JerryLMJ/LMJHorizontalScrollText/14f00dade63cd4746c7c4ae1221c45bda42598be/LMJHorizontalScrollTextExample.xcodeproj/project.xcworkspace/xcuserdata/jerrylmj.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample.xcodeproj/project.xcworkspace/xcuserdata/limingjie.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JerryLMJ/LMJHorizontalScrollText/14f00dade63cd4746c7c4ae1221c45bda42598be/LMJHorizontalScrollTextExample.xcodeproj/project.xcworkspace/xcuserdata/limingjie.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample.xcodeproj/xcuserdata/jerrylmj.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LMJHorizontalScrollTextExample.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample.xcodeproj/xcuserdata/limingjie.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample.xcodeproj/xcuserdata/limingjie.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LMJHorizontalScrollTextExample.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/AppDelegate/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // LMJHorizontalScrollTextExample 4 | // 5 | // Created by LiMingjie on 2019/8/22. 6 | // Copyright © 2019 LMJ. 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 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/AppDelegate/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // LMJHorizontalScrollTextExample 4 | // 5 | // Created by LiMingjie on 2019/8/22. 6 | // Copyright © 2019 LMJ. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Demo-Base/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // LMJHorizontalScrollTextExample 4 | // 5 | // Created by LiMingjie on 2019/8/22. 6 | // Copyright © 2019 LMJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Demo-Base/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // LMJHorizontalScrollTextExample 4 | // 5 | // Created by LiMingjie on 2019/8/22. 6 | // Copyright © 2019 LMJ. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "Demo-StoryboardVC.h" 11 | #import "Demo-TableViewCellVC.h" 12 | #import "LMJHorizontalScrollText.h" 13 | 14 | 15 | @interface ViewController () 16 | 17 | @property (nonatomic, strong) LMJHorizontalScrollText * scrollText1_1; 18 | @property (nonatomic, strong) LMJHorizontalScrollText * scrollText1_2; 19 | 20 | @property (nonatomic, strong) LMJHorizontalScrollText * scrollText2_1; 21 | @property (nonatomic, strong) LMJHorizontalScrollText * scrollText2_2; 22 | 23 | @property (nonatomic, strong) LMJHorizontalScrollText * scrollText3_1; 24 | @property (nonatomic, strong) LMJHorizontalScrollText * scrollText3_2; 25 | 26 | @property (nonatomic, strong) LMJHorizontalScrollText * scrollText4_1; 27 | @property (nonatomic, strong) LMJHorizontalScrollText * scrollText4_2; 28 | 29 | 30 | @property (nonatomic, strong) UILabel * speedValueLabel; 31 | @end 32 | 33 | @implementation ViewController 34 | { 35 | CGFloat _screenWidth; 36 | UIColor * _bgColor; 37 | } 38 | 39 | - (void)viewDidLoad { 40 | [super viewDidLoad]; 41 | _screenWidth = self.view.frame.size.width; 42 | _bgColor = [UIColor colorWithRed:64/255.f green:151/255.f blue:255/255.f alpha:0.5]; 43 | 44 | [self buildHorizontalScrollTexts_Wandering]; 45 | [self buildHorizontalScrollTexts_Continuous]; 46 | [self buildHorizontalScrollTexts_Intermittent]; 47 | [self buildHorizontalScrollTexts_FromOutside]; 48 | 49 | [self buildSpeedControl]; 50 | 51 | [self buildGotoStoryboardPageBtn]; 52 | [self buildGotoTableViewCellPageBtn]; 53 | } 54 | 55 | - (void)buildHorizontalScrollTexts_Wandering { 56 | _scrollText1_1 = [[LMJHorizontalScrollText alloc] initWithFrame: CGRectMake(15, 50, _screenWidth -30, 20)]; 57 | _scrollText1_1.layer.cornerRadius = 3; 58 | _scrollText1_1.backgroundColor = _bgColor; 59 | _scrollText1_1.text = @"<<<=往返滚动(back and forth)=>>>"; 60 | _scrollText1_1.textColor = [UIColor whiteColor]; 61 | _scrollText1_1.textFont = [UIFont systemFontOfSize:14]; 62 | _scrollText1_1.speed = 0.03; 63 | _scrollText1_1.moveMode = LMJTextScrollWandering; 64 | [self.view addSubview:_scrollText1_1]; 65 | 66 | _scrollText1_2 = [[LMJHorizontalScrollText alloc] initWithFrame: CGRectMake(15, 80, _screenWidth -30, 20)]; 67 | _scrollText1_2.layer.cornerRadius = 3; 68 | _scrollText1_2.backgroundColor = _bgColor; 69 | _scrollText1_2.text = @"<<<=往返滚动(back and forth)|往返滚动(back and forth)=>>>"; 70 | _scrollText1_2.textColor = [UIColor whiteColor]; 71 | _scrollText1_2.textFont = [UIFont systemFontOfSize:14]; 72 | _scrollText1_2.speed = 0.03; 73 | _scrollText1_2.moveMode = LMJTextScrollWandering; 74 | [self.view addSubview:_scrollText1_2]; 75 | 76 | [_scrollText1_1 move]; 77 | [_scrollText1_2 move]; 78 | } 79 | 80 | - (void)buildHorizontalScrollTexts_Continuous { 81 | _scrollText2_1 = [[LMJHorizontalScrollText alloc] initWithFrame: CGRectMake(15, 140, _screenWidth -30, 20)]; 82 | _scrollText2_1.layer.cornerRadius = 3; 83 | _scrollText2_1.backgroundColor = _bgColor; 84 | _scrollText2_1.text = @"<<<=向左,连续滚动(left,continuous)向左,连续滚动(left,continuous)"; 85 | _scrollText2_1.textColor = [UIColor whiteColor]; 86 | _scrollText2_1.textFont = [UIFont systemFontOfSize:14]; 87 | _scrollText2_1.speed = 0.03; 88 | _scrollText2_1.moveDirection = LMJTextScrollMoveLeft; 89 | _scrollText2_1.moveMode = LMJTextScrollContinuous; 90 | [self.view addSubview:_scrollText2_1]; 91 | 92 | 93 | _scrollText2_2 = [[LMJHorizontalScrollText alloc] initWithFrame: CGRectMake(15, 170, _screenWidth -30, 20)]; 94 | _scrollText2_2.layer.cornerRadius = 3; 95 | _scrollText2_2.backgroundColor = _bgColor; 96 | _scrollText2_2.text = @"(right,continuous)向右,连续滚动(right,continuous)向右,连续滚动=>>>"; 97 | _scrollText2_2.textColor = [UIColor whiteColor]; 98 | _scrollText2_2.textFont = [UIFont systemFontOfSize:14]; 99 | _scrollText2_2.speed = 0.03; 100 | _scrollText2_2.moveDirection = LMJTextScrollMoveRight; 101 | _scrollText2_2.moveMode = LMJTextScrollContinuous; 102 | [self.view addSubview:_scrollText2_2]; 103 | 104 | [_scrollText2_1 move]; 105 | [_scrollText2_2 move]; 106 | } 107 | 108 | - (void)buildHorizontalScrollTexts_Intermittent { 109 | _scrollText3_1 = [[LMJHorizontalScrollText alloc] initWithFrame: CGRectMake(15, 230, _screenWidth -30, 20)]; 110 | _scrollText3_1.layer.cornerRadius = 3; 111 | _scrollText3_1.backgroundColor = _bgColor; 112 | _scrollText3_1.text = @"<<<=向左,间断滚动(left,intermittent)"; 113 | _scrollText3_1.textColor = [UIColor whiteColor]; 114 | _scrollText3_1.textFont = [UIFont systemFontOfSize:14]; 115 | _scrollText3_1.speed = 0.03; 116 | _scrollText3_1.moveDirection = LMJTextScrollMoveLeft; 117 | _scrollText3_1.moveMode = LMJTextScrollIntermittent; 118 | [self.view addSubview:_scrollText3_1]; 119 | 120 | 121 | _scrollText3_2 = [[LMJHorizontalScrollText alloc] initWithFrame: CGRectMake(15, 260, _screenWidth -30, 20)]; 122 | _scrollText3_2.layer.cornerRadius = 3; 123 | _scrollText3_2.backgroundColor = _bgColor; 124 | _scrollText3_2.text = @"(right,intermittent)向右,间断滚动=>>>"; 125 | _scrollText3_2.textColor = [UIColor whiteColor]; 126 | _scrollText3_2.textFont = [UIFont systemFontOfSize:14]; 127 | _scrollText3_2.speed = 0.03; 128 | _scrollText3_2.moveDirection = LMJTextScrollMoveRight; 129 | _scrollText3_2.moveMode = LMJTextScrollIntermittent; 130 | [self.view addSubview:_scrollText3_2]; 131 | 132 | [_scrollText3_1 move]; 133 | [_scrollText3_2 move]; 134 | } 135 | 136 | - (void)buildHorizontalScrollTexts_FromOutside { 137 | _scrollText4_1 = [[LMJHorizontalScrollText alloc] initWithFrame: CGRectMake(15, 320, _screenWidth -30, 20)]; 138 | _scrollText4_1.layer.cornerRadius = 3; 139 | _scrollText4_1.backgroundColor = _bgColor; 140 | _scrollText4_1.text = @"<<<=向左,控件外开始滚动(left,outside start)"; 141 | _scrollText4_1.textColor = [UIColor whiteColor]; 142 | _scrollText4_1.textFont = [UIFont systemFontOfSize:14]; 143 | _scrollText4_1.speed = 0.03; 144 | _scrollText4_1.moveDirection = LMJTextScrollMoveLeft; 145 | _scrollText4_1.moveMode = LMJTextScrollFromOutside; 146 | [self.view addSubview:_scrollText4_1]; 147 | 148 | 149 | _scrollText4_2 = [[LMJHorizontalScrollText alloc] initWithFrame: CGRectMake(15, 350, _screenWidth -30, 20)]; 150 | _scrollText4_2.layer.cornerRadius = 3; 151 | _scrollText4_2.backgroundColor = _bgColor; 152 | _scrollText4_2.text = @"(right,outside start)向右,控件外开始滚动=>>>"; 153 | _scrollText4_2.textColor = [UIColor whiteColor]; 154 | _scrollText4_2.textFont = [UIFont systemFontOfSize:14]; 155 | _scrollText4_2.speed = 0.03; 156 | _scrollText4_2.moveDirection = LMJTextScrollMoveRight; 157 | _scrollText4_2.moveMode = LMJTextScrollFromOutside; 158 | [self.view addSubview:_scrollText4_2]; 159 | 160 | [_scrollText4_1 move]; 161 | [_scrollText4_2 move]; 162 | } 163 | 164 | - (void)buildSpeedControl { 165 | UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(15, 450, 60, 20)]; 166 | label.text = @"speed:"; 167 | label.font = [UIFont boldSystemFontOfSize:14]; 168 | [self.view addSubview:label]; 169 | 170 | UISlider * slider = [[UISlider alloc] initWithFrame:CGRectMake(80, 450, _screenWidth -80 -60, 20)]; 171 | slider.minimumValue = 0.01; 172 | slider.maximumValue = 0.1; 173 | slider.value = 0.03; 174 | slider.continuous = NO; 175 | [slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged]; 176 | [self.view addSubview:slider]; 177 | 178 | _speedValueLabel = [[UILabel alloc] initWithFrame:CGRectMake(_screenWidth -60, 450, 60, 20)]; 179 | _speedValueLabel.text = @"0.03"; 180 | _speedValueLabel.font = [UIFont boldSystemFontOfSize:14]; 181 | [self.view addSubview:_speedValueLabel]; 182 | } 183 | - (void)buildGotoStoryboardPageBtn{ 184 | UIButton * demoAddToXibPageBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 185 | [demoAddToXibPageBtn setTitle:@"DemoAddToXibPage >>>" forState:UIControlStateNormal]; 186 | [demoAddToXibPageBtn setBackgroundColor:[UIColor grayColor]]; 187 | [demoAddToXibPageBtn setFrame:CGRectMake(20, 550, 300, 30)]; 188 | [demoAddToXibPageBtn addTarget:self action:@selector(clickDemoAddToXibPageBtn) forControlEvents:UIControlEventTouchUpInside]; 189 | demoAddToXibPageBtn.layer.cornerRadius = 3; 190 | [self.view addSubview:demoAddToXibPageBtn]; 191 | } 192 | - (void)buildGotoTableViewCellPageBtn{ 193 | UIButton * demoAddToTableViewCellPageBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 194 | [demoAddToTableViewCellPageBtn setTitle:@"DemoAddToTableViewCellPage >>>" forState:UIControlStateNormal]; 195 | [demoAddToTableViewCellPageBtn setBackgroundColor:[UIColor grayColor]]; 196 | [demoAddToTableViewCellPageBtn setFrame:CGRectMake(20, 600, 300, 30)]; 197 | [demoAddToTableViewCellPageBtn addTarget:self action:@selector(clickDemoAddToTableViewCellPageBtn) forControlEvents:UIControlEventTouchUpInside]; 198 | demoAddToTableViewCellPageBtn.layer.cornerRadius = 3; 199 | [self.view addSubview:demoAddToTableViewCellPageBtn]; 200 | } 201 | 202 | #pragma mark - action 203 | - (void)sliderValueChanged:(UISlider *)slider { 204 | CGFloat value = slider.value; 205 | _speedValueLabel.text = [NSString stringWithFormat:@"%0.2f", value]; 206 | 207 | _scrollText1_1.speed = value; 208 | _scrollText1_2.speed = value; 209 | _scrollText2_1.speed = value; 210 | _scrollText2_2.speed = value; 211 | _scrollText3_1.speed = value; 212 | _scrollText3_2.speed = value; 213 | _scrollText4_1.speed = value; 214 | _scrollText4_2.speed = value; 215 | } 216 | 217 | - (void)clickDemoAddToXibPageBtn { 218 | Demo_StoryboardVC * vc = [[UIStoryboard storyboardWithName:@"Demo" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"Demo_StoryboardVC"]; 219 | [self presentViewController:vc animated:YES completion:nil]; 220 | } 221 | - (void)clickDemoAddToTableViewCellPageBtn { 222 | Demo_TableViewCellVC * vc = [[Demo_TableViewCellVC alloc] init]; 223 | [self presentViewController:vc animated:YES completion:nil]; 224 | } 225 | 226 | 227 | @end 228 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Demo-Storyboard/Demo-StoryboardVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // Demo-StoryboardVC.h 3 | // LMJHorizontalScrollTextExample 4 | // 5 | // Created by LiMingjie on 2019/9/23. 6 | // Copyright © 2019 LMJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Demo_StoryboardVC : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Demo-Storyboard/Demo-StoryboardVC.m: -------------------------------------------------------------------------------- 1 | // 2 | // Demo-StoryboardVC.m 3 | // LMJHorizontalScrollTextExample 4 | // 5 | // Created by LiMingjie on 2019/9/23. 6 | // Copyright © 2019 LMJ. All rights reserved. 7 | // 8 | 9 | #import "Demo-StoryboardVC.h" 10 | #import "LMJHorizontalScrollText.h" 11 | 12 | @interface Demo_StoryboardVC () 13 | 14 | @property (weak, nonatomic) IBOutlet LMJHorizontalScrollText *scrollText1; 15 | @property (weak, nonatomic) IBOutlet LMJHorizontalScrollText *scrollText2; 16 | @property (weak, nonatomic) IBOutlet LMJHorizontalScrollText *scrollText3; 17 | @property (weak, nonatomic) IBOutlet LMJHorizontalScrollText *scrollText4; 18 | 19 | @end 20 | 21 | @implementation Demo_StoryboardVC 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | 26 | UIButton * backBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 27 | [backBtn setTitle:@"back" forState:UIControlStateNormal]; 28 | [backBtn setBackgroundColor:[UIColor lightGrayColor]]; 29 | [backBtn setFrame:CGRectMake(20, 50, 90, 30)]; 30 | [backBtn addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside]; 31 | [self.view addSubview:backBtn]; 32 | 33 | 34 | 35 | 36 | _scrollText1.text = @"<<<=往返滚动(back and forth)|往返滚动(back and forth)=>>>"; 37 | _scrollText1.textColor = [UIColor whiteColor]; 38 | _scrollText1.textFont = [UIFont systemFontOfSize:14]; 39 | _scrollText1.speed = 0.03; 40 | _scrollText1.moveMode = LMJTextScrollWandering; 41 | 42 | 43 | _scrollText2.text = @"<<<=向左,连续滚动(left,continuous)向左,连续滚动(left,continuous)"; 44 | _scrollText2.textColor = [UIColor whiteColor]; 45 | _scrollText2.textFont = [UIFont systemFontOfSize:14]; 46 | _scrollText2.speed = 0.03; 47 | _scrollText2.moveDirection = LMJTextScrollMoveLeft; 48 | _scrollText2.moveMode = LMJTextScrollContinuous; 49 | 50 | 51 | _scrollText3.text = @"(right,intermittent)向右,间断滚动=>>>"; 52 | _scrollText3.textColor = [UIColor whiteColor]; 53 | _scrollText3.textFont = [UIFont systemFontOfSize:14]; 54 | _scrollText3.speed = 0.03; 55 | _scrollText3.moveDirection = LMJTextScrollMoveRight; 56 | _scrollText3.moveMode = LMJTextScrollIntermittent; 57 | 58 | 59 | _scrollText4.text = @"<<<=向左,控件外开始滚动(left,outside start)"; 60 | _scrollText4.textColor = [UIColor whiteColor]; 61 | _scrollText4.textFont = [UIFont systemFontOfSize:14]; 62 | _scrollText4.speed = 0.03; 63 | _scrollText4.moveDirection = LMJTextScrollMoveLeft; 64 | _scrollText4.moveMode = LMJTextScrollFromOutside; 65 | 66 | } 67 | 68 | 69 | - (void)backAction{ 70 | [self dismissViewControllerAnimated:YES completion:nil]; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Demo-Storyboard/Demo.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 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Demo-TableViewCell/Demo-TableViewCellVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // Demo-TableViewCellVC.h 3 | // LMJHorizontalScrollTextExample 4 | // 5 | // Created by JerryLMJ on 2019/12/21. 6 | // Copyright © 2019 LMJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Demo_TableViewCellVC : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Demo-TableViewCell/Demo-TableViewCellVC.m: -------------------------------------------------------------------------------- 1 | // 2 | // Demo-TableViewCellVC.m 3 | // LMJHorizontalScrollTextExample 4 | // 5 | // Created by JerryLMJ on 2019/12/21. 6 | // Copyright © 2019 LMJ. All rights reserved. 7 | // 8 | 9 | #import "Demo-TableViewCellVC.h" 10 | #import "LMJHorizontalScrollText.h" 11 | 12 | @interface Demo_TableViewCellVC() 13 | 14 | @end 15 | 16 | @implementation Demo_TableViewCellVC 17 | { 18 | UITableView * _listView; 19 | } 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | 23 | self.view.backgroundColor = [UIColor whiteColor]; 24 | 25 | UIButton * backBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 26 | [backBtn setTitle:@"back" forState:UIControlStateNormal]; 27 | [backBtn setBackgroundColor:[UIColor lightGrayColor]]; 28 | [backBtn setFrame:CGRectMake(20, 50, 90, 30)]; 29 | [backBtn addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside]; 30 | [self.view addSubview:backBtn]; 31 | 32 | _listView = [[UITableView alloc] initWithFrame:CGRectMake(20, 100, 300, 600)]; 33 | _listView.delegate = self; 34 | _listView.dataSource = self; 35 | [self.view addSubview:_listView]; 36 | } 37 | 38 | - (void)backAction{ 39 | [self dismissViewControllerAnimated:YES completion:nil]; 40 | } 41 | 42 | #pragma mark - TableView Delegate 43 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 44 | return 20; 45 | } 46 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 47 | return 40; 48 | } 49 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 50 | static NSString * cellId = @"cell"; 51 | UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellId]; 52 | if (cell == nil) { 53 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId]; 54 | cell.backgroundColor = [UIColor lightGrayColor]; 55 | 56 | /* LMJHorizontalScrollText */ 57 | LMJHorizontalScrollText * text = [[LMJHorizontalScrollText alloc] initWithFrame:CGRectMake(20, 10, 260, 20)]; 58 | text.backgroundColor = [UIColor colorWithRed:64/255.f green:151/255.f blue:255/255.f alpha:0.5]; 59 | text.textColor = [UIColor whiteColor]; 60 | text.textFont = [UIFont systemFontOfSize:14]; 61 | text.speed = 0.03; 62 | text.moveDirection = LMJTextScrollMoveLeft; 63 | text.moveMode = LMJTextScrollContinuous; 64 | text.layer.cornerRadius = 3; 65 | text.tag = 999; 66 | [cell addSubview:text]; 67 | /* LMJHorizontalScrollText */ 68 | 69 | } 70 | 71 | /* LMJHorizontalScrollText */ 72 | LMJHorizontalScrollText * text = [cell viewWithTag:999]; 73 | text.text = [NSString stringWithFormat:@"<<<=往返滚动(back and forth)%ld=>>>", (long)indexPath.row]; 74 | /* LMJHorizontalScrollText */ 75 | 76 | return cell; 77 | } 78 | 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Supporting Files/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 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Supporting Files/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Supporting Files/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 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Supporting Files/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 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExample/Supporting Files/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LMJHorizontalScrollTextExample 4 | // 5 | // Created by LiMingjie on 2019/8/22. 6 | // Copyright © 2019 LMJ. 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 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExampleTests/LMJHorizontalScrollTextExampleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // LMJHorizontalScrollTextExampleTests.m 3 | // LMJHorizontalScrollTextExampleTests 4 | // 5 | // Created by LiMingjie on 2019/8/22. 6 | // Copyright © 2019 LMJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LMJHorizontalScrollTextExampleTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation LMJHorizontalScrollTextExampleTests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | - (void)tearDown { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | - (void)testExample { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | 30 | - (void)testPerformanceExample { 31 | // This is an example of a performance test case. 32 | [self measureBlock:^{ 33 | // Put the code you want to measure the time of here. 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExampleUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /LMJHorizontalScrollTextExampleUITests/LMJHorizontalScrollTextExampleUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // LMJHorizontalScrollTextExampleUITests.m 3 | // LMJHorizontalScrollTextExampleUITests 4 | // 5 | // Created by LiMingjie on 2019/8/22. 6 | // Copyright © 2019 LMJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LMJHorizontalScrollTextExampleUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation LMJHorizontalScrollTextExampleUITests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | 20 | // In UI tests it is usually best to stop immediately when a failure occurs. 21 | self.continueAfterFailure = NO; 22 | 23 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 24 | [[[XCUIApplication alloc] init] launch]; 25 | 26 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 27 | } 28 | 29 | - (void)tearDown { 30 | // Put teardown code here. This method is called after the invocation of each test method in the class. 31 | } 32 | 33 | - (void)testExample { 34 | // Use recording to get started writing UI tests. 35 | // Use XCTAssert and related functions to verify your tests produce the correct results. 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /README.en.md: -------------------------------------------------------------------------------- 1 | ![(logo)](https://avatars2.githubusercontent.com/u/15794032?s=460&v=4) 2 | 3 | [简体中文](./README.md) | English 4 | 5 | # LMJHorizontalScrollText 6 | 7 | ![podversion](https://img.shields.io/cocoapods/v/LMJHorizontalScrollText.svg?style=flat) 8 | ![](https://img.shields.io/cocoapods/p/LMJHorizontalScrollText.svg?style=flat) 9 | ![](https://img.shields.io/badge/language-oc-orange.svg) 10 | ![](https://img.shields.io/cocoapods/l/LMJHorizontalScrollText.svg?style=flat) 11 | 12 | - A simple and easy to use string scroll control 13 | 14 | 15 | ## Effect 16 | ![](https://github.com/JerryLMJ/LMJHorizontalScrollText/raw/master/demo.gif) 17 | 18 | 19 | 20 | ## Support what kinds of scenarios to use 21 | - UIView、UITableViewCell、Storyboard etc. 22 | 23 | 24 | ## Usage 25 | **A choice:** 26 | * Use cocoapods: 27 | `pod 'LMJHorizontalScrollText'` 28 | 29 | * Manual import: 30 | * Drag All files in the `LMJHorizontalScrollText` folder to project 31 | * Import the main file:`#import "LMJHorizontalScrollText.h"` 32 | 33 | 34 | ## Properties and methods 35 | | Attribute | Description | 36 | | --- | --- 37 | | text | scroll string content 38 | | textFont | font 39 | | textColor | font color 40 | | speed | rolling speed, value range 0.01~0.1, default 0.03, the smaller the value, the faster the speed 41 | | moveDirection | Scroll mode, default LMJTextScrollWandering, enumeration values are as follows:
- LMJTextScrollMoveLeft: left
- LMJTextScrollMoveRight: right 42 | | moveMode | scroll way, default LMJTextScrollWandering, enumeration values are as follows:
- LMJTextScrollContinuous: starting control in continuous rolling
- LMJTextScrollIntermittent: starting control in continuous rolling
- LMJTextScrollFromOutside: starting from the outside control rolling
- LMJTextScrollWandering: Scroll back and forth in the control (not affected by the moveDirection property) 43 | 44 | | Method | Description | 45 | | --- | --- 46 | | move | to scroll 47 | | stop | stop scrolling 48 | 49 | 50 | ## Update log 51 | - **2019.12.23 (2.0.2) :** 52 | Fixed some errors using controls on UITableViewCell to enable the control to support the cell's reuse mechanism. 53 | Optimize the stop method. 54 | Added demo for controls used in UITableViewCell. 55 | - **2019.9.23 (2.0.1) :** 56 | Fixed a display error when the control rotated to landscape. 57 | Added demo used by controls in Storyboard to simulate changes of controls when screen rotation. 58 | - **2019.8.23 (2.0.0) :** 59 | Here comes the new 2.0! 🎉 🎉 🎉 60 | To better match the control functions, the project name will be changed from LMJScrollTextView to LMJHorizontalScrollText. 61 | This update reconstructs the way the control is used, removing multiple initialization methods and adding more flexible control properties to improve control performance. 62 | Newly added cocoapods installation which is always required by everyone, and improved the file structure of demo module and new Chinese and English documents. 63 | - **2017.12.5 (1.2.0) :** 64 | Fix exceptions caused by excessively short strings. 65 | Fix some bugs. 66 | Improve the test Demo. 67 | - **2015.11.23 (1.0.0) :** 68 | This demo mainly realizes string scrolling effect 69 | Scroll direction can be set (left, right, round trip). 70 | you can set the starting position of scrolling (starting from outside the control, starting from the edge of the control). 71 | You can set the rolling speed. 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![(logo)](https://avatars2.githubusercontent.com/u/15794032?s=460&v=4) 2 | 3 | 简体中文 | [English](./README.en.md) 4 | 5 | # LMJHorizontalScrollText 6 | 7 | ![podversion](https://img.shields.io/cocoapods/v/LMJHorizontalScrollText.svg?style=flat) 8 | ![](https://img.shields.io/cocoapods/p/LMJHorizontalScrollText.svg?style=flat) 9 | ![](https://img.shields.io/badge/language-oc-orange.svg) 10 | ![](https://img.shields.io/cocoapods/l/LMJHorizontalScrollText.svg?style=flat) 11 | 12 | - 一个简单好用的字符串滚动控件 13 | 14 | ## 效果 15 | 16 | ![](https://github.com/JerryLMJ/LMJHorizontalScrollText/raw/master/demo.gif) 17 | 18 | ## 支持哪些场景 19 | 20 | - UIView、UITableViewCell、Storyboard 等... 21 | 22 | ## 使用 23 | **二选一:** 24 | - 使用 cocoapods 安装: 25 | `pod 'LMJHorizontalScrollText'` 26 | - 手动导入: 27 | 将 `LMJHorizontalScrollText` 文件拖拽到工程中 28 | 导入头文件`#import "LMJHorizontalScrollText.h"` 29 | 30 | ## 属性及方法 31 | 32 | | 属性 | 描述 | 33 | | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 34 | | text | 滚动字符串内容 | 35 | | textFont | 字体 | 36 | | textColor | 字体颜色 | 37 | | speed | 滚动速度,取值范围 0.01~0.1,默认 0.03,值越小速度越快 | 38 | | moveDirection | 滚动方向,默认 LMJTextScrollMoveLeft,枚举值如下:
- LMJTextScrollMoveLeft:向左滚动
- LMJTextScrollMoveRight:向右滚动 | 39 | | moveMode | 滚动方式,默认 LMJTextScrollWandering,枚举值如下:
- LMJTextScrollContinuous: 从控件内开始连续滚动
- LMJTextScrollIntermittent:从控件内开始间断滚动
- LMJTextScrollFromOutside:从控件外开始滚动
- LMJTextScrollWandering: 在控件中往返滚动(不受 moveDirection 属性影响) | 40 | 41 | | 方法 | 描述 | 42 | | ---- | -------- | 43 | | move | 开始滚动 | 44 | | stop | 停止滚动 | 45 | 46 | ## 更新日志 47 | 48 | - **2019.12.23(2.0.2):** 49 | 修复了在UITableViewCell上使用控件出现的一些错误,使控件支持cell的复用机制。 50 | 优化了stop方法。 51 | 增加了控件在 UITableViewCell中使用的 demo。 52 | 53 | - **2019.9.23(2.0.1):** 54 | 修复了控件在屏幕旋转为横屏时,出现的显示错误。 55 | 增加了控件在 Storyboard 中使用的 demo,可模拟屏幕旋转时控件的变化。 56 | 57 | - **2019.8.23(2.0.0):** 58 | 全新的 2.0 版本来啦!🎉🎉🎉 59 | 为更贴合控件功能,项目名称将由 LMJScrollTextView 更换为 LMJHorizontalScrollText 60 | 本次更新重构控件的使用方式,移除了多个初始化方法,增加使用更加灵活的控件属性 ,提高控件性能 61 | 新增加了大家一直要求的 cocoapods 安装,并完善了 demo 模块的文件结构以及全新的中英文文档 62 | 63 | - **2017.12.5(1.2.0):** 64 | 1、修复字符串过短时产生的异常 65 | 2、修复一些 bug 66 | 3、完善测试 Demo 67 | 68 | - **2015.11.23(1.0.0):** 69 | 本 demo 主要实现字符串滚动效果 70 | 1、可以设置滚动方向(左、右、往返) 71 | 2、可以设置滚动起始位置(从控件外开始、从控件边缘开始) 72 | 3,可以设置滚动速度 73 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JerryLMJ/LMJHorizontalScrollText/14f00dade63cd4746c7c4ae1221c45bda42598be/demo.gif --------------------------------------------------------------------------------