├── Untitled.gif
├── RollingNotice
├── Assets.xcassets
│ ├── Contents.json
│ ├── tb_icon.imageset
│ │ ├── tb_icon@2x.png
│ │ └── Contents.json
│ ├── tb_icon2.imageset
│ │ ├── tb_icon2@2x.png
│ │ └── Contents.json
│ ├── tb_icon3.imageset
│ │ ├── tb_icon3@2x.png
│ │ └── Contents.json
│ ├── tb_icon5.imageset
│ │ ├── tb_icon5@2x.png
│ │ └── Contents.json
│ ├── tb_icon6.imageset
│ │ ├── tb_icon6@2x.png
│ │ └── Contents.json
│ ├── tb_icon7.imageset
│ │ ├── tb_icon7@2x.png
│ │ └── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── ViewController.h
├── SecondViewController.h
├── DemoCell2.h
├── AppDelegate.h
├── ThirdViewController.h
├── CustomNoticeCell.h
├── DemoCell3.h
├── main.m
├── DemoCodeAutoLayout.h
├── DemoCell3.m
├── GYRollingNoticeView
│ ├── GYNoticeViewCell.h
│ ├── GYRollingNoticeView.h
│ ├── GYNoticeViewCell.m
│ └── GYRollingNoticeView.m
├── DemoCell2.m
├── CustomNoticeCell.m
├── Info.plist
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── DemoCodeAutoLayout.m
├── AppDelegate.m
├── SecondViewController.m
├── ThirdViewController.m
├── SecondViewController.xib
├── DemoCell3.xib
├── ViewController.m
└── CustomNoticeCell.xib
├── RollingNotice.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── qm.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
├── xcuserdata
│ └── qm.xcuserdatad
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── RollingNotice.xcscheme
├── xcshareddata
│ └── xcschemes
│ │ └── RollingNotice.xcscheme
└── project.pbxproj
├── LICENSE
├── README_en.md
├── README.md
└── RollingNotice.podspec
/Untitled.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maltsugar/RollingNotice/HEAD/Untitled.gif
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon.imageset/tb_icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maltsugar/RollingNotice/HEAD/RollingNotice/Assets.xcassets/tb_icon.imageset/tb_icon@2x.png
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon2.imageset/tb_icon2@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maltsugar/RollingNotice/HEAD/RollingNotice/Assets.xcassets/tb_icon2.imageset/tb_icon2@2x.png
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon3.imageset/tb_icon3@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maltsugar/RollingNotice/HEAD/RollingNotice/Assets.xcassets/tb_icon3.imageset/tb_icon3@2x.png
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon5.imageset/tb_icon5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maltsugar/RollingNotice/HEAD/RollingNotice/Assets.xcassets/tb_icon5.imageset/tb_icon5@2x.png
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon6.imageset/tb_icon6@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maltsugar/RollingNotice/HEAD/RollingNotice/Assets.xcassets/tb_icon6.imageset/tb_icon6@2x.png
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon7.imageset/tb_icon7@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maltsugar/RollingNotice/HEAD/RollingNotice/Assets.xcassets/tb_icon7.imageset/tb_icon7@2x.png
--------------------------------------------------------------------------------
/RollingNotice.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/RollingNotice.xcodeproj/project.xcworkspace/xcuserdata/qm.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maltsugar/RollingNotice/HEAD/RollingNotice.xcodeproj/project.xcworkspace/xcuserdata/qm.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/RollingNotice/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/4.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/RollingNotice/SecondViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SecondViewController.h
3 | // RollingNotice
4 | //
5 | // Created by qm on 2018/8/7.
6 | // Copyright © 2018年 qm. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SecondViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/RollingNotice/DemoCell2.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCell2.h
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/13.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import "GYNoticeViewCell.h"
10 |
11 | @interface DemoCell2 : GYNoticeViewCell
12 |
13 | @property (nonatomic, strong) UILabel *customLab;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/RollingNotice/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/4.
6 | // Copyright © 2017年 qm. 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 |
--------------------------------------------------------------------------------
/RollingNotice/ThirdViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ThirdViewController.h
3 | // RollingNotice
4 | //
5 | // Created by zgy on 2020/4/15.
6 | // Copyright © 2020 qm. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface ThirdViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/RollingNotice/CustomNoticeCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // CustomNoticeCell.h
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/8.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import "GYNoticeViewCell.h"
10 |
11 | @interface CustomNoticeCell : GYNoticeViewCell
12 |
13 | - (void)noticeCellWithArr:(NSArray *)arr forIndex:(NSUInteger)index;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/RollingNotice/DemoCell3.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCell3.h
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/13.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import "GYNoticeViewCell.h"
10 |
11 | @interface DemoCell3 : GYNoticeViewCell
12 |
13 | @property (weak, nonatomic) IBOutlet UILabel *lab0;
14 | @property (weak, nonatomic) IBOutlet UILabel *lab1;
15 |
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/RollingNotice/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/4.
6 | // Copyright © 2017年 qm. 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 |
--------------------------------------------------------------------------------
/RollingNotice/DemoCodeAutoLayout.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCodeAutoLayout.h
3 | // RollingNotice
4 | //
5 | // Created by zgy on 2020/4/15.
6 | // Copyright © 2020 qm. All rights reserved.
7 | //
8 |
9 | #import "GYNoticeViewCell.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoCodeAutoLayout : GYNoticeViewCell
14 |
15 |
16 |
17 | @property (nonatomic, strong) UILabel *customLab;
18 |
19 | @end
20 |
21 | NS_ASSUME_NONNULL_END
22 |
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tb_icon@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tb_icon2@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tb_icon3@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tb_icon5@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tb_icon6@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/RollingNotice/Assets.xcassets/tb_icon7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tb_icon7@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/RollingNotice/DemoCell3.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCell3.m
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/13.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import "DemoCell3.h"
10 |
11 | @implementation DemoCell3
12 |
13 | /*
14 | // Only override drawRect: if you perform custom drawing.
15 | // An empty implementation adversely affects performance during animation.
16 | - (void)drawRect:(CGRect)rect {
17 | // Drawing code
18 | }
19 | */
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/RollingNotice.xcodeproj/xcuserdata/qm.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | RollingNotice.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 91FFD8761FD52A36004A1A27
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/RollingNotice/GYRollingNoticeView/GYNoticeViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // GYNoticeViewCell.h
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/4.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | // 调试cell内存地址log
12 | static BOOL GYRollingDebugLog = NO;
13 |
14 | @interface GYNoticeViewCell : UIView
15 |
16 | @property (nonatomic, readonly, strong) UIView *contentView;
17 | @property (nonatomic, readonly, strong) UILabel *textLabel;
18 | @property (nonatomic, readonly, copy) NSString *reuseIdentifier;
19 |
20 |
21 | /// 普通用法label,左右间距, 必须>=0, 默认10
22 | @property (nonatomic, assign) CGFloat textLabelLeading;
23 | @property (nonatomic, assign) CGFloat textLabelTrailing;
24 |
25 |
26 | - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier NS_DESIGNATED_INITIALIZER;
27 | - (instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
28 | @end
29 |
--------------------------------------------------------------------------------
/RollingNotice/DemoCell2.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCell2.m
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/13.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import "DemoCell2.h"
10 |
11 | @interface DemoCell2 ()
12 |
13 | @property (nonatomic, strong) UIButton *testBtn;
14 |
15 |
16 |
17 | @end
18 |
19 | @implementation DemoCell2
20 |
21 | - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
22 | {
23 | self = [super initWithReuseIdentifier:reuseIdentifier];
24 | if (self) {
25 | [self setupUI];
26 | }
27 | return self;
28 | }
29 |
30 | // cell 高度30
31 | - (void)setupUI
32 | {
33 | UIButton *testBtn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
34 | [self.contentView addSubview:testBtn];
35 | testBtn.frame = CGRectMake(10, 5, 20, 20);
36 |
37 | _customLab = [[UILabel alloc]initWithFrame:CGRectMake(30+10, 5, 200, 20)];
38 | _customLab.textColor = [UIColor redColor];
39 | _customLab.backgroundColor = [UIColor lightGrayColor];
40 | [self.contentView addSubview:_customLab];
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 maltsugar <173678978@qq.com>
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/RollingNotice/CustomNoticeCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // CustomNoticeCell.m
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/8.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import "CustomNoticeCell.h"
10 | @interface CustomNoticeCell ()
11 |
12 | @property (weak, nonatomic) IBOutlet UIImageView *trailIconImgView;
13 |
14 | @property (weak, nonatomic) IBOutlet UILabel *tagLab0;
15 | @property (weak, nonatomic) IBOutlet UILabel *titleLab0;
16 |
17 | @property (weak, nonatomic) IBOutlet UILabel *tagLab1;
18 | @property (weak, nonatomic) IBOutlet UILabel *titleLab1;
19 |
20 |
21 | @end
22 | @implementation CustomNoticeCell
23 |
24 |
25 | - (void)awakeFromNib
26 | {
27 | [super awakeFromNib];
28 |
29 | _tagLab0.layer.borderColor = [UIColor orangeColor].CGColor;
30 | _tagLab0.layer.borderWidth = 0.5;
31 | _tagLab0.layer.cornerRadius = 3;
32 |
33 | _tagLab1.layer.borderColor = [UIColor orangeColor].CGColor;
34 | _tagLab1.layer.borderWidth = 0.5;
35 | _tagLab1.layer.cornerRadius = 3;
36 | }
37 |
38 |
39 | - (void)noticeCellWithArr:(NSArray *)arr forIndex:(NSUInteger)index
40 | {
41 | NSDictionary *dic = arr[index];
42 | _trailIconImgView.image = [UIImage imageNamed:dic[@"img"]];
43 |
44 | _tagLab0.text = [dic[@"arr"] firstObject][@"tag"];
45 | _titleLab0.text = [dic[@"arr"] firstObject][@"title"];
46 |
47 | _tagLab1.text = [dic[@"arr"] lastObject][@"tag"];
48 | _titleLab1.text = [dic[@"arr"] lastObject][@"title"];
49 |
50 | }
51 |
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/RollingNotice/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 |
--------------------------------------------------------------------------------
/README_en.md:
--------------------------------------------------------------------------------
1 | # Rolling Notice、Rolling Advertisement
2 |   [](http://cocoapods.org/pods/RollingNotice) 
3 |
4 | ##### [Swift Version](https://github.com/maltsugar/RollingNotice-Swift)
5 | ### Introduce
6 | This library can scroll any view, scroll up and down the notice, advertising. It can be very flexible, similar to UITableViewCell.
7 | You only need to customize the view and assin value according to the index, roll will be done by it!
8 |
9 |
10 | ### Features
11 | - According to the UITableView design concept, developers only need to customize their own view (no matter how complicated it is) and assign value according to the index, roll will be done by it!
12 | - A simple use for one line label roll, its own cell will be OK. For complicated cell you can customize view.
13 | - All cells support reuse, same kind of cell will be allocted up to 2
14 | - Support dynamic refresh data source, multi type cell mix
15 | - Almost the same as UITableView usage
16 |
17 | Issues are welcome, hope you like it!
18 | ### Usage
19 | - manual: drag `GYRollingNoticeView` in your project
20 | - Cocoapods: `pod 'RollingNotice'`
21 |
22 | **customized cell must inherit `GYNoticeViewCell`.**
23 |
24 | For more details, see the demo project. Just similar as UITableView.
25 |
26 |
27 | 
28 | ### License
29 | GYRollingNoticeView is provided under the MIT license. See LICENSE file for details.
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/RollingNotice/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 |
--------------------------------------------------------------------------------
/RollingNotice/GYRollingNoticeView/GYRollingNoticeView.h:
--------------------------------------------------------------------------------
1 | //
2 | // GYRollingNoticeView.h
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/4.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "GYNoticeViewCell.h"
11 |
12 | @class GYRollingNoticeView;
13 | @protocol GYRollingNoticeViewDataSource
14 | @required
15 | - (NSInteger)numberOfRowsForRollingNoticeView:(GYRollingNoticeView *)rollingView;
16 | - (GYNoticeViewCell *)rollingNoticeView:(GYRollingNoticeView *)rollingView cellAtIndex:(NSUInteger)index;
17 | @end
18 |
19 | @protocol GYRollingNoticeViewDelegate
20 | @optional
21 | - (void)didClickRollingNoticeView:(GYRollingNoticeView *)rollingView forIndex:(NSUInteger)index;
22 |
23 | @end
24 |
25 | typedef NS_ENUM(NSUInteger, GYRollingNoticeViewStatus) {
26 | GYRollingNoticeViewStatusIdle,
27 | GYRollingNoticeViewStatusWorking,
28 | GYRollingNoticeViewStatusPause,
29 | };
30 |
31 | @interface GYRollingNoticeView : UIView
32 |
33 |
34 | @property (nonatomic, weak) id dataSource;
35 | @property (nonatomic, weak) id delegate;
36 | @property (nonatomic, assign) NSTimeInterval stayInterval; // 停留时间 默认2秒
37 | @property (nonatomic, assign, readonly) int currentIndex;
38 | @property (nonatomic, assign, readonly) GYRollingNoticeViewStatus status;
39 |
40 |
41 | - (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier;
42 | - (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier;
43 | - (__kindof GYNoticeViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;
44 |
45 | - (void)reloadDataAndStartRoll;
46 | - (void)stopRoll; // 如果想要释放,请在合适的地方停止timer。 If you want to release, please stop the timer in the right place,for example '-viewDidDismiss'
47 |
48 | - (void)pause;
49 | - (void)resume;
50 |
51 |
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/RollingNotice/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 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 滚动公告、广告
2 |   [](http://cocoapods.org/pods/RollingNotice) 
3 |
4 | ##### [English](https://github.com/maltsugar/RollingNotice/blob/master/README_en.md)
5 | ##### [Swift 版本](https://github.com/maltsugar/RollingNotice-Swift)
6 |
7 |
8 | ### 版本记录
9 |
10 | - 1.1.1 修复[#16](https://github.com/maltsugar/RollingNotice/issues/16)、[#17](https://github.com/maltsugar/RollingNotice/issues/17),感谢[@xygkevin](https://github.com/xygkevin)
11 | - 1.1.0 新增暂停/恢复功能
12 | - 1.0.9 数据源返回数量为0时,不再显示cell
13 | - 1.0.8 普通用法textLabel支持左右间距设置
14 | - 1.0.6 delegate和dataSource使用weak修饰,更加安全合理,代理、数据源释放时属性自动置nil
15 | - 1.0.5 小更新,修改readme里一个单词拼写错误,去掉动画block里self强引用提示
16 | - 1.0.4 支持xib创建滚动视图[#9](https://github.com/maltsugar/RollingNotice/issues/9)
17 | - 1.0.3 修复极少数情况下,动画过程退到后台,可能出现残影的bug,感谢[@pcjbird](https://github.com/pcjbird)指出并帮忙修复
18 |
19 |
20 | ### 经历
21 | 前一段时间遇到了滚动公告的需求,搜了好多天,发现没有简单明了的库可用。大神们写的都太复杂了,star比较高的两个,一个不支持动态刷新标题,一个甚至写了循环scrollView的功能,功能太过强大,我认为比较庞大,就没有用了(我本人喜欢简洁一点的库)。后来找了一个简单的[WCScrollLabelView](https://github.com/Verchen/WCScrollLabelView),算是符合我的预期,然鹅我又给他改[两个bug](https://github.com/Verchen/WCScrollLabelView/issues/1),一个是timer不释放,一个是只有一个label时有问题。😅
22 |
23 | ---
24 | 于是就有了这个开源库,很曲折啊。闲暇时间写了一个,非常灵活。
25 |
26 | ### 特点:
27 |
28 | - UITableView设计理念, 开发者只需要自定义自己的view(想要多复杂的View都行) 并根据index赋值,轮播交给它。
29 | - 简单一行文字轮播用自带的cell, 复杂的自定义cell
30 | - cell 支持重用,目前一种cell最多创建2个
31 | - 支持动态刷新数据源,多种cell混用
32 | - 用法几乎和UITableView一样
33 |
34 |
35 | 希望大家共同进步,有问题欢迎issue
36 | ### 用法
37 | 几乎和UITableView一样的体验,自定义cell的话`必须`继承`GYNoticeViewCell`,你只管自定义你的View,并根据index赋值,轮播交给它。
38 | 具体用法demo 里有的!
39 |
40 | - 手动下载: `GYRollingNoticeView`拖进去
41 | - Cocoapods: `pod 'RollingNotice'`
42 |
43 |
44 | 
45 |
46 | ### 许可证
47 | 转载请注明出处,谢谢
48 |
49 | GYRollingNoticeView 使用 MIT 许可证,详情见 LICENSE 文件。
50 |
51 |
52 |
--------------------------------------------------------------------------------
/RollingNotice/DemoCodeAutoLayout.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCodeAutoLayout.m
3 | // RollingNotice
4 | //
5 | // Created by zgy on 2020/4/15.
6 | // Copyright © 2020 qm. All rights reserved.
7 | //
8 |
9 | #import "DemoCodeAutoLayout.h"
10 |
11 | @implementation DemoCodeAutoLayout
12 |
13 | - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
14 | {
15 | self = [super initWithReuseIdentifier:reuseIdentifier];
16 | if (self) {
17 | [self setupUI];
18 | }
19 | return self;
20 | }
21 |
22 | // cell 高度30
23 | - (void)setupUI
24 | {
25 | UIButton *testBtn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
26 | [self.contentView addSubview:testBtn];
27 | // testBtn.frame = CGRectMake(10, 5, 20, 20);
28 | testBtn.translatesAutoresizingMaskIntoConstraints = NO;
29 | [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[v]" options:0 metrics:nil views:@{@"v": testBtn}]];
30 | [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[v]" options:0 metrics:nil views:@{@"v": testBtn}]];
31 |
32 | [testBtn addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[v(30)]" options:0 metrics:nil views:@{@"v": testBtn}]];
33 | [testBtn addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[v(60)]" options:0 metrics:nil views:@{@"v": testBtn}]];
34 |
35 |
36 |
37 | _customLab = [[UILabel alloc]init];
38 | _customLab.textColor = [UIColor redColor];
39 | _customLab.backgroundColor = [UIColor lightGrayColor];
40 | [self.contentView addSubview:_customLab];
41 |
42 | _customLab.translatesAutoresizingMaskIntoConstraints = NO;
43 | [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[v]|" options:0 metrics:nil views:@{@"v": _customLab}]];
44 | [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-80-[v]" options:0 metrics:nil views:@{@"v": _customLab}]];
45 | [_customLab addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[v(160)]" options:0 metrics:nil views:@{@"v": _customLab}]];
46 |
47 |
48 | }
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/RollingNotice/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/4.
6 | // Copyright © 2017年 qm. 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 |
--------------------------------------------------------------------------------
/RollingNotice/GYRollingNoticeView/GYNoticeViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // GYNoticeViewCell.m
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/4.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import "GYNoticeViewCell.h"
10 |
11 | @implementation GYNoticeViewCell
12 |
13 | - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
14 | {
15 | self = [super initWithFrame:CGRectZero];
16 | if (self) {
17 | if (GYRollingDebugLog) {
18 | NSLog(@"init a cell from code: %p", self);
19 | }
20 | _textLabelLeading = 10;
21 | _textLabelTrailing = 10;
22 | _reuseIdentifier = reuseIdentifier;
23 | [self setupInitialUI];
24 | }
25 | return self;
26 | }
27 |
28 | - (instancetype)initWithCoder:(NSCoder *)aDecoder
29 | {
30 | self = [super initWithCoder:aDecoder];
31 | if (self) {
32 |
33 | if (GYRollingDebugLog) {
34 | NSLog(@"init a cell from xib");
35 | }
36 | }
37 | return self;
38 | }
39 | - (instancetype)initWithFrame:(CGRect)frame
40 | {
41 | return [self initWithReuseIdentifier:@""];
42 | }
43 |
44 | - (void)setupInitialUI
45 | {
46 | self.backgroundColor = [UIColor whiteColor];
47 | _contentView = [[UIView alloc] init];
48 | [self addSubview:_contentView];
49 |
50 | _textLabel = [[UILabel alloc]init];
51 | [_contentView addSubview:_textLabel];
52 | }
53 |
54 |
55 | - (void)layoutSubviews
56 | {
57 | [super layoutSubviews];
58 |
59 | _contentView.frame = self.bounds;
60 |
61 | if (nil != _textLabel) {
62 | CGFloat lead = _textLabelLeading;
63 | if (lead < 0) {
64 | NSLog(@"⚠️⚠️textLabelLeading must >= 0⚠️⚠️");
65 | lead = 0;
66 | }
67 | CGFloat trai = _textLabelTrailing;
68 | if (trai < 0) {
69 | NSLog(@"⚠️⚠️textLabelTrailing must >= 0⚠️⚠️");
70 | trai = 0;
71 | }
72 | CGFloat width = self.frame.size.width - lead - trai;
73 | if (width < 0) {
74 | NSLog(@"⚠️⚠️width must >= 0⚠️⚠️");
75 | width = 0;
76 | }
77 | _textLabel.frame = CGRectMake(lead, 0, width, self.frame.size.height);
78 | }
79 |
80 |
81 | }
82 |
83 | - (void)dealloc
84 | {
85 | if (GYRollingDebugLog) {
86 | NSLog(@"%p, %s", self, __func__);
87 | }
88 |
89 | }
90 |
91 |
92 | @end
93 |
--------------------------------------------------------------------------------
/RollingNotice/SecondViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SecondViewController.m
3 | // RollingNotice
4 | //
5 | // Created by qm on 2018/8/7.
6 | // Copyright © 2018年 qm. All rights reserved.
7 | //
8 |
9 | #import "SecondViewController.h"
10 | #import "GYRollingNoticeView.h"
11 |
12 | @interface SecondViewController ()
13 |
14 | {
15 | NSArray *_arr;
16 |
17 | }
18 |
19 | @property (weak, nonatomic) IBOutlet GYRollingNoticeView *noticeView;
20 |
21 |
22 | @end
23 |
24 | @implementation SecondViewController
25 |
26 | - (void)viewDidLoad {
27 | [super viewDidLoad];
28 | // Do any additional setup after loading the view from its nib.
29 |
30 | _arr = @[@"小米千元全面屏:抱歉,久等!625献上",
31 | @"可怜狗狗被抛弃,苦苦等候主人半年",
32 | @"三星中端新机改名,全面屏火力全开",
33 | @"学会这些,这5种花不用去花店买了",
34 | @"华为nova2S发布,剧透了荣耀10?"
35 | ];
36 |
37 | _noticeView.delegate = self;
38 | _noticeView.dataSource = self;
39 | [_noticeView registerClass:[GYNoticeViewCell class] forCellReuseIdentifier:@"GYNoticeViewCell"];
40 |
41 | [_noticeView reloadDataAndStartRoll];
42 | }
43 |
44 | - (void)viewWillDisappear:(BOOL)animated
45 | {
46 | [super viewWillDisappear:animated];
47 | [_noticeView stopRoll];
48 | }
49 |
50 |
51 | #pragma mark-
52 | - (NSInteger)numberOfRowsForRollingNoticeView:(GYRollingNoticeView *)rollingView
53 | {
54 | return _arr.count;
55 | }
56 | - (__kindof GYNoticeViewCell *)rollingNoticeView:(GYRollingNoticeView *)rollingView cellAtIndex:(NSUInteger)index
57 | {
58 | GYNoticeViewCell *cell = [rollingView dequeueReusableCellWithIdentifier:@"GYNoticeViewCell"];
59 | cell.textLabel.text = [NSString stringWithFormat:@"index %d ,%@", (int)index, _arr[index]];
60 | cell.contentView.backgroundColor = [UIColor orangeColor];
61 | cell.textLabelLeading = 100;
62 | cell.textLabelTrailing = 80;
63 | if (index % 2 == 0) {
64 | cell.contentView.backgroundColor = [UIColor greenColor];
65 | cell.textLabelLeading = 0;
66 | }
67 | return cell;
68 |
69 | }
70 |
71 | - (void)didClickRollingNoticeView:(GYRollingNoticeView *)rollingView forIndex:(NSUInteger)index
72 | {
73 | NSLog(@"点击的index: %d", rollingView.currentIndex);
74 | }
75 |
76 |
77 |
78 | - (IBAction)handleBtnAction:(UIButton *)sender {
79 | if (_noticeView.status == GYRollingNoticeViewStatusWorking) {
80 | [_noticeView pause];
81 | [sender setTitle:@"resume" forState:UIControlStateNormal];
82 |
83 | }else if (_noticeView.status != GYRollingNoticeViewStatusWorking) {
84 | [_noticeView resume];
85 | [sender setTitle:@"pause" forState:UIControlStateNormal];
86 | }
87 | }
88 |
89 |
90 |
91 |
92 | - (void)dealloc
93 | {
94 | NSLog(@"%s", __func__);
95 | }
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/RollingNotice/ThirdViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ThirdViewController.m
3 | // RollingNotice
4 | //
5 | // Created by zgy on 2020/4/15.
6 | // Copyright © 2020 qm. All rights reserved.
7 | //
8 |
9 | #import "ThirdViewController.h"
10 | #import "DemoCodeAutoLayout.h"
11 | #import "GYRollingNoticeView.h"
12 |
13 | @interface ThirdViewController ()
14 |
15 | {
16 | NSArray *_arr;
17 |
18 | }
19 | @property (nonatomic, strong) GYRollingNoticeView *noticeView;
20 | @end
21 |
22 | @implementation ThirdViewController
23 |
24 | - (instancetype)init
25 | {
26 | self = [super init];
27 | if (self) {
28 |
29 | _arr = @[@"小米千元全面屏:抱歉,久等!625献上",
30 | // @"可怜狗狗被抛弃,苦苦等候主人半年",
31 | // @"三星中端新机改名,全面屏火力全开",
32 | // @"学会这些,这5种花不用去花店买了",
33 | // @"华为nova2S发布,剧透了荣耀10?"
34 | ];
35 |
36 |
37 | _noticeView = [[GYRollingNoticeView alloc] init];
38 | _noticeView.delegate = self;
39 | _noticeView.dataSource = self;
40 |
41 | [self.view addSubview:_noticeView];
42 |
43 |
44 | [_noticeView registerClass:[DemoCodeAutoLayout class] forCellReuseIdentifier:@"DemoCodeAutoLayout"];
45 |
46 | [_noticeView reloadDataAndStartRoll];
47 |
48 | _noticeView.translatesAutoresizingMaskIntoConstraints = NO;
49 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-160-[v]" options:0 metrics:nil views:@{@"v": _noticeView}]];
50 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[v]-20-|" options:0 metrics:nil views:@{@"v": _noticeView}]];
51 |
52 | [_noticeView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[v(30)]" options:0 metrics:nil views:@{@"v": _noticeView}]];
53 |
54 | }
55 | return self;
56 | }
57 |
58 |
59 | - (void)viewDidLoad {
60 | [super viewDidLoad];
61 | self.view.backgroundColor = [UIColor whiteColor];
62 | }
63 |
64 |
65 | - (void)viewWillDisappear:(BOOL)animated
66 | {
67 | [super viewWillDisappear:animated];
68 | [_noticeView stopRoll];
69 | }
70 |
71 |
72 | #pragma mark-
73 | - (NSInteger)numberOfRowsForRollingNoticeView:(GYRollingNoticeView *)rollingView
74 | {
75 | return _arr.count;
76 | }
77 | - (__kindof GYNoticeViewCell *)rollingNoticeView:(GYRollingNoticeView *)rollingView cellAtIndex:(NSUInteger)index
78 | {
79 | DemoCodeAutoLayout *cell = [rollingView dequeueReusableCellWithIdentifier:@"DemoCodeAutoLayout"];
80 | cell.customLab.text = _arr[index];
81 | return cell;
82 |
83 | }
84 |
85 | - (void)didClickRollingNoticeView:(GYRollingNoticeView *)rollingView forIndex:(NSUInteger)index
86 | {
87 | NSLog(@"点击的index: %d", rollingView.currentIndex);
88 | }
89 |
90 | @end
91 |
--------------------------------------------------------------------------------
/RollingNotice.xcodeproj/xcshareddata/xcschemes/RollingNotice.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/RollingNotice.xcodeproj/xcuserdata/qm.xcuserdatad/xcschemes/RollingNotice.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/RollingNotice/SecondViewController.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 |
27 |
28 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/RollingNotice/DemoCell3.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 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/RollingNotice/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 |
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 |
--------------------------------------------------------------------------------
/RollingNotice.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod spec lint RollingNotice.podspec' to ensure this is a
3 | # valid spec and to remove all comments including this before submitting the spec.
4 | #
5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
7 | #
8 |
9 | Pod::Spec.new do |s|
10 |
11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
12 | #
13 | # These will help people to find your library, and whilst it
14 | # can feel like a chore to fill in it's definitely to your advantage. The
15 | # summary should be tweet-length, and the description more in depth.
16 | #
17 |
18 | s.name = "RollingNotice"
19 | s.version = "1.1.1"
20 | s.summary = "滚动公告、广告,支持灵活自定义cell。淘宝、口碑、京东、美团、天猫等等一切滚动广告 Roll Notice or Advertising. A rolling banner, custom cell like UITableViewCell supported"
21 |
22 | # This description is used to generate tags and improve search results.
23 | # * Think: What does it do? Why did you write it? What is the focus?
24 | # * Try to keep it short, snappy and to the point.
25 | # * Write the description between the DESC delimiters below.
26 | # * Finally, don't worry about the indent, CocoaPods strips it!
27 | s.description = <<-DESC
28 | 可以简单的滚动文本公告,也可以像淘宝头条那样很复杂。你自定义cell,根据index赋值,滚动交给它!
29 | 用法和UITableView几乎一样,也支持重用
30 | A rolling banner for iOS, you can custom cell for it. Just similar as UITableView
31 | DESC
32 |
33 | s.homepage = "https://github.com/maltsugar/RollingNotice"
34 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
35 |
36 |
37 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
38 | #
39 | # Licensing your code is important. See http://choosealicense.com for more info.
40 | # CocoaPods will detect a license file if there is a named LICENSE*
41 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
42 | #
43 |
44 | s.license = { :type => "MIT", :file => "LICENSE" }
45 |
46 |
47 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
48 | #
49 | # Specify the authors of the library, with email addresses. Email addresses
50 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
51 | # accepts just a name if you'd rather not provide an email address.
52 | #
53 | # Specify a social_media_url where others can refer to, for example a twitter
54 | # profile URL.
55 | #
56 |
57 | s.author = { "zgy" => "173678978@qq.com" }
58 | # Or just: s.author = "zgy"
59 | # s.authors = { "zgy" => "173678978@qq.com" }
60 | # s.social_media_url = "http://twitter.com/zgy"
61 |
62 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
63 | #
64 | # If this Pod runs only on iOS or OS X, then specify the platform and
65 | # the deployment target. You can optionally include the target after the platform.
66 | #
67 |
68 |
69 | s.platform = :ios, "5.0"
70 |
71 | # When using multiple platforms
72 | s.ios.deployment_target = "5.0"
73 | # s.osx.deployment_target = "10.7"
74 | # s.watchos.deployment_target = "2.0"
75 | # s.tvos.deployment_target = "9.0"
76 |
77 |
78 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
79 | #
80 | # Specify the location from where the source should be retrieved.
81 | # Supports git, hg, bzr, svn and HTTP.
82 | #
83 |
84 | s.source = { :git => "https://github.com/maltsugar/RollingNotice.git", :tag => "#{s.version}" }
85 |
86 |
87 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
88 | #
89 | # CocoaPods is smart about how it includes source code. For source files
90 | # giving a folder will include any swift, h, m, mm, c & cpp files.
91 | # For header files it will include any header in the folder.
92 | # Not including the public_header_files will make all headers public.
93 | #
94 |
95 | s.source_files = "GYRollingNoticeView", "RollingNotice/GYRollingNoticeView/*.{h,m}"
96 | s.framework = "UIKit"
97 |
98 | # s.public_header_files = "Classes/**/*.h"
99 |
100 |
101 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
102 | #
103 | # A list of resources included with the Pod. These are copied into the
104 | # target bundle with a build phase script. Anything else will be cleaned.
105 | # You can preserve files from being cleaned, please don't preserve
106 | # non-essential files like tests, examples and documentation.
107 | #
108 |
109 | # s.resource = "icon.png"
110 | # s.resources = "Resources/*.png"
111 |
112 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave"
113 |
114 |
115 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
116 | #
117 | # Link your library with frameworks, or libraries. Libraries do not include
118 | # the lib prefix of their name.
119 | #
120 |
121 | # s.framework = "SomeFramework"
122 | # s.frameworks = "SomeFramework", "AnotherFramework"
123 |
124 | # s.library = "iconv"
125 | # s.libraries = "iconv", "xml2"
126 |
127 |
128 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
129 | #
130 | # If your library depends on compiler flags you can set them in the xcconfig hash
131 | # where they will only apply to your library. If you depend on other Podspecs
132 | # you can include multiple dependencies to ensure it works.
133 |
134 | # s.requires_arc = true
135 |
136 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
137 | # s.dependency "JSONKit", "~> 1.4"
138 |
139 | end
140 |
--------------------------------------------------------------------------------
/RollingNotice/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/4.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "GYRollingNoticeView.h"
11 | #import "CustomNoticeCell.h"
12 | #import "DemoCell2.h"
13 | #import "DemoCell3.h"
14 | #import "SecondViewController.h"
15 | #import "ThirdViewController.h"
16 |
17 | @interface ViewController ()
18 | {
19 | NSArray *_arr0;
20 | NSArray *_arr1;
21 |
22 | GYRollingNoticeView *_noticeView0;
23 | GYRollingNoticeView *_noticeView1;
24 |
25 | }
26 | @end
27 |
28 | @implementation ViewController
29 |
30 | - (void)viewDidLoad {
31 | [super viewDidLoad];
32 | float w = [[UIScreen mainScreen] bounds].size.width;
33 | UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(0, 80, w, 100)];
34 | lab.numberOfLines = 0;
35 | lab.text = @"滚动公告、广告,支持自定义cell,模仿淘宝头条等等。 \nUITableViewCell重用理念,支持请Star!";
36 | [self.view addSubview:lab];
37 |
38 |
39 |
40 | _arr0 = @[
41 | @{@"arr": @[@{@"tag": @"手机", @"title": @"小米千元全面屏:抱歉,久等!625献上"}, @{@"tag": @"萌宠", @"title": @"可怜狗狗被抛弃,苦苦等候主人半年"}], @"img": @"tb_icon2"},
42 | @{@"arr": @[@{@"tag": @"手机", @"title": @"三星中端新机改名,全面屏火力全开"}, @{@"tag": @"围观", @"title": @"主人假装离去,狗狗直接把孩子推回去了"}], @"img": @"tb_icon3"},
43 | @{@"arr": @[@{@"tag": @"园艺", @"title": @"学会这些,这5种花不用去花店买了"}, @{@"tag": @"手机", @"title": @"华为nova2S发布,剧透了荣耀10?"}], @"img": @"tb_icon5"},
44 | @{@"arr": @[@{@"tag": @"开发", @"title": @"iOS 内购最新讲解"}, @{@"tag": @"博客", @"title": @"技术博客那些事儿"}], @"img": @"tb_icon6"},
45 | @{@"arr": @[@{@"tag": @"招聘", @"title": @"招聘XX高级开发工程师"}, @{@"tag": @"资讯", @"title": @"如何写一篇好的技术博客"}], @"img": @"tb_icon7"}
46 | ];
47 | _arr1 = @[@"小米千元全面屏:抱歉,久等!625献上",
48 | @"可怜狗狗被抛弃,苦苦等候主人半年",
49 | @"三星中端新机改名,全面屏火力全开",
50 | @"学会这些,这5种花不用去花店买了",
51 | @"华为nova2S发布,剧透了荣耀10?"
52 | ];
53 |
54 | [self creatRollingViewWithArray:_arr0 isFirst:YES];
55 | [self creatRollingViewWithArray:_arr1 isFirst:NO];
56 |
57 |
58 | // 刷新数据源 reload datasource test ok
59 | // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
60 | // _arr1 = @[@"0", @"1", @"2", @"3", @"4", @"5"];
61 | //// _arr1 = @[@"0"];
62 | // [_noticeView1 reloadDataAndStartRoll];
63 | // });
64 |
65 | }
66 |
67 | // 请在合适的时机 停止
68 | - (void)viewDidDisappear:(BOOL)animated
69 | {
70 | [super viewDidDisappear:animated];
71 | [_noticeView0 stopRoll];
72 | [_noticeView1 stopRoll];
73 | }
74 |
75 | - (void)viewWillAppear:(BOOL)animated
76 | {
77 | [super viewWillAppear:animated];
78 | [_noticeView0 reloadDataAndStartRoll];
79 | }
80 |
81 |
82 | - (void)creatRollingViewWithArray:(NSArray *)arr isFirst:(BOOL)isFirst
83 | {
84 | float w = [[UIScreen mainScreen] bounds].size.width;
85 | CGRect frame = CGRectMake(0, 190, w, 50);
86 | if (!isFirst) {
87 | frame = CGRectMake(0, 290, w, 30);
88 | }
89 |
90 | GYRollingNoticeView *noticeView = [[GYRollingNoticeView alloc]initWithFrame:frame];
91 | noticeView.dataSource = self;
92 | noticeView.delegate = self;
93 | [self.view addSubview:noticeView];
94 | noticeView.backgroundColor = [UIColor lightGrayColor];
95 |
96 | if (isFirst) {
97 | _noticeView0 = noticeView;
98 | [noticeView registerNib:[UINib nibWithNibName:@"CustomNoticeCell" bundle:nil] forCellReuseIdentifier:@"CustomNoticeCell"];
99 | [noticeView registerNib:[UINib nibWithNibName:@"DemoCell3" bundle:nil] forCellReuseIdentifier:@"DemoCell3"];
100 |
101 | }else{
102 | _noticeView1 = noticeView;
103 | [noticeView registerClass:[GYNoticeViewCell class] forCellReuseIdentifier:@"GYNoticeViewCell"];
104 | [noticeView registerClass:[DemoCell2 class] forCellReuseIdentifier:@"DemoCell2"];
105 | }
106 |
107 | [noticeView reloadDataAndStartRoll];
108 | }
109 |
110 |
111 |
112 | - (NSInteger)numberOfRowsForRollingNoticeView:(GYRollingNoticeView *)rollingView
113 | {
114 | if (rollingView == _noticeView0) {
115 | return _arr0.count;
116 | }
117 |
118 | if (rollingView == _noticeView1) {
119 | return _arr1.count;
120 | }
121 |
122 | return 0;
123 | }
124 | - (__kindof GYNoticeViewCell *)rollingNoticeView:(GYRollingNoticeView *)rollingView cellAtIndex:(NSUInteger)index
125 | {
126 | if (rollingView == _noticeView0) {
127 |
128 | if (index < 3) {
129 | CustomNoticeCell *cell = [rollingView dequeueReusableCellWithIdentifier:@"CustomNoticeCell"];
130 | [cell noticeCellWithArr:_arr0 forIndex:index];
131 | return cell;
132 | }else
133 | {
134 | DemoCell3 *cell = [rollingView dequeueReusableCellWithIdentifier:@"DemoCell3"];
135 | NSDictionary *dic = _arr0[index];
136 | cell.lab0.text = [dic[@"arr"] firstObject][@"title"];
137 | cell.lab1.text = [dic[@"arr"] lastObject][@"title"];
138 | return cell;
139 | }
140 |
141 |
142 |
143 | }
144 |
145 | // 普通用法,只有一行label滚动显示文字
146 | // normal use, only one line label rolling
147 | if (rollingView == _noticeView1) {
148 | if (index < 3) {
149 | GYNoticeViewCell *cell = [rollingView dequeueReusableCellWithIdentifier:@"GYNoticeViewCell"];
150 | cell.textLabel.text = [NSString stringWithFormat:@"第1种cell %@", _arr1[index]];
151 | cell.contentView.backgroundColor = [UIColor orangeColor];
152 | if (index % 2 == 0) {
153 | cell.contentView.backgroundColor = [UIColor greenColor];
154 | }
155 | return cell;
156 | }else {
157 |
158 | DemoCell2 *cell = [rollingView dequeueReusableCellWithIdentifier:@"DemoCell2"];
159 | cell.customLab.text = [NSString stringWithFormat:@"第2种cell %@", _arr1[index]];
160 | cell.contentView.backgroundColor = [UIColor purpleColor];
161 | return cell;
162 | }
163 |
164 |
165 | }
166 |
167 |
168 | return nil;
169 | }
170 |
171 | - (void)didClickRollingNoticeView:(GYRollingNoticeView *)rollingView forIndex:(NSUInteger)index
172 | {
173 | NSLog(@"点击的index: %lu", (unsigned long)index);
174 | }
175 |
176 | #pragma mark- IBActions
177 |
178 | - (IBAction)handleRightAction:(UIBarButtonItem *)sender
179 | {
180 | // SecondViewController *vc = [SecondViewController new];
181 | ThirdViewController *vc = [ThirdViewController new];
182 | [self.navigationController pushViewController:vc animated:YES];
183 | }
184 |
185 |
186 | - (IBAction)handlePauseResumeAction:(UIButton *)sender {
187 | if (_noticeView0.status == GYRollingNoticeViewStatusWorking) {
188 | [_noticeView0 pause];
189 |
190 | }else if (_noticeView0.status != GYRollingNoticeViewStatusWorking) {
191 | [_noticeView0 resume];
192 | }
193 | }
194 |
195 | @end
196 |
--------------------------------------------------------------------------------
/RollingNotice/CustomNoticeCell.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 |
27 |
28 |
29 |
30 |
40 |
46 |
56 |
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 |
--------------------------------------------------------------------------------
/RollingNotice/GYRollingNoticeView/GYRollingNoticeView.m:
--------------------------------------------------------------------------------
1 | //
2 | // GYRollingNoticeView.m
3 | // RollingNotice
4 | //
5 | // Created by qm on 2017/12/4.
6 | // Copyright © 2017年 qm. All rights reserved.
7 | //
8 |
9 | #import "GYRollingNoticeView.h"
10 | #import "GYNoticeViewCell.h"
11 |
12 |
13 | #define kGYNotiWeakSelf(type) __weak typeof(type) weak##type = type;
14 | #define kGYNotiStrongSelf(type) __strong typeof(type) type = weak##type;
15 |
16 | @interface GYRollingNoticeView ()
17 |
18 | {
19 | int _cIdx;
20 | BOOL _needTryRoll;
21 | }
22 |
23 | @property (nonatomic, strong) NSMutableDictionary *cellClsDict;
24 | @property (nonatomic, strong) NSMutableArray *reuseCells;
25 |
26 | @property (nonatomic, strong) NSTimer *timer;
27 | @property (nonatomic, strong) GYNoticeViewCell *currentCell;
28 | @property (nonatomic, strong) GYNoticeViewCell *willShowCell;
29 | @property (nonatomic, assign) BOOL isAnimating;
30 |
31 |
32 | @end
33 |
34 | @implementation GYRollingNoticeView
35 | @dynamic currentIndex;
36 |
37 | - (instancetype)init
38 | {
39 | self = [super init];
40 | if (self) {
41 | [self setupNoticeViews];
42 | }
43 | return self;
44 | }
45 |
46 | - (instancetype)initWithFrame:(CGRect)frame
47 | {
48 | self = [super initWithFrame:frame];
49 | if (self) {
50 | [self setupNoticeViews];
51 | }
52 | return self;
53 | }
54 | - (instancetype)initWithCoder:(NSCoder *)aDecoder
55 | {
56 | self = [super initWithCoder:aDecoder];
57 | if (self) {
58 | [self setupNoticeViews];
59 | }
60 | return self;
61 | }
62 |
63 | - (void)setupNoticeViews
64 | {
65 | self.clipsToBounds = YES;
66 | _stayInterval = 2;
67 | [self addGestureRecognizer:[self createTapGesture]];
68 | }
69 |
70 | - (void)layoutSubviews
71 | {
72 | [super layoutSubviews];
73 | if (_needTryRoll) {
74 | [self reloadDataAndStartRoll];
75 | _needTryRoll = NO;
76 | }
77 |
78 | }
79 |
80 |
81 |
82 | - (void)registerClass:(nullable Class)cellClass forCellReuseIdentifier:(NSString *)identifier
83 | {
84 | [self.cellClsDict setObject:NSStringFromClass(cellClass) forKey:identifier];
85 | }
86 |
87 | - (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
88 | {
89 | [self.cellClsDict setObject:nib forKey:identifier];
90 | }
91 |
92 | - (__kindof GYNoticeViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier
93 | {
94 | for (GYNoticeViewCell *cell in self.reuseCells) {
95 |
96 | if ([cell.reuseIdentifier isEqualToString:identifier]) {
97 | // NSLog(@"finded reuse cell: %p", cell);
98 | return cell;
99 | }
100 | }
101 |
102 | id cellClass = self.cellClsDict[identifier];
103 | if ([cellClass isKindOfClass:[UINib class]]) {
104 | UINib *nib = (UINib *)cellClass;
105 |
106 | NSArray *arr = [nib instantiateWithOwner:nil options:nil];
107 | GYNoticeViewCell *cell = [arr firstObject];
108 | [cell setValue:identifier forKeyPath:@"reuseIdentifier"];
109 | return cell;
110 | }else
111 | {
112 | Class cellCls = NSClassFromString(self.cellClsDict[identifier]);
113 | GYNoticeViewCell *cell = [[cellCls alloc] initWithReuseIdentifier:identifier];
114 | return cell;
115 | }
116 |
117 | }
118 |
119 |
120 | #pragma mark- rolling
121 | - (void)layoutCurrentCellAndWillShowCell
122 | {
123 | int count = (int)[self.dataSource numberOfRowsForRollingNoticeView:self];
124 | if (_cIdx > count - 1) {
125 | _cIdx = 0;
126 | }
127 |
128 | int willShowIndex = _cIdx + 1;
129 | if (willShowIndex > count - 1) {
130 | willShowIndex = 0;
131 | }
132 | // NSLog(@">>>>%d", _cIdx);
133 |
134 | float w = self.frame.size.width;
135 | float h = self.frame.size.height;
136 |
137 | // NSLog(@"count: %d, _cIdx:%d willShowIndex: %d", count, _cIdx, willShowIndex);
138 |
139 | if (!(w > 0 && h > 0)) {
140 | _needTryRoll = YES;
141 | return;
142 | }
143 | if (!_currentCell) {
144 | // 第一次没有currentcell
145 | // currentcell is null at first time
146 | _currentCell = [self.dataSource rollingNoticeView:self cellAtIndex:_cIdx];
147 | _currentCell.frame = CGRectMake(0, 0, w, h);
148 | [self addSubview:_currentCell];
149 | return;
150 | }
151 |
152 |
153 |
154 | _willShowCell = [self.dataSource rollingNoticeView:self cellAtIndex:willShowIndex];
155 | _willShowCell.frame = CGRectMake(0, h, w, h);
156 | [self addSubview:_willShowCell];
157 |
158 |
159 | if (GYRollingDebugLog) {
160 | NSLog(@"_currentCell %p", _currentCell);
161 | NSLog(@"_willShowCell %p", _willShowCell);
162 | }
163 |
164 | [self.reuseCells removeObject:_currentCell];
165 | [self.reuseCells removeObject:_willShowCell];
166 |
167 |
168 | }
169 |
170 | - (void)reloadDataAndStartRoll
171 | {
172 | [self stopRoll];
173 |
174 | NSInteger count = [self.dataSource numberOfRowsForRollingNoticeView:self];
175 | if (count < 1) {
176 | return;
177 | }
178 |
179 | [self layoutCurrentCellAndWillShowCell];
180 |
181 | if (count && count < 2) {
182 | return;
183 | }
184 |
185 |
186 | _timer = [NSTimer scheduledTimerWithTimeInterval:_stayInterval target:self selector:@selector(timerHandle) userInfo:nil repeats:YES];
187 | NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
188 | [runLoop addTimer:_timer forMode:NSRunLoopCommonModes];
189 | [self resume];
190 | }
191 |
192 | - (void)stopRoll
193 | {
194 | if (_timer) {
195 | [_timer invalidate];
196 | _timer = nil;
197 | }
198 |
199 | _status = GYRollingNoticeViewStatusIdle;
200 | _isAnimating = NO;
201 | _cIdx = 0;
202 | [_currentCell removeFromSuperview];
203 | [_willShowCell removeFromSuperview];
204 | _currentCell = nil;
205 | _willShowCell = nil;
206 | [self.reuseCells removeAllObjects];
207 | }
208 |
209 | - (void)pause
210 | {
211 | if (_timer) {
212 | [_timer setFireDate:[NSDate distantFuture]];
213 | _status = GYRollingNoticeViewStatusPause;
214 | }
215 | }
216 | - (void)resume
217 | {
218 | if (_timer) {
219 | [_timer setFireDate:[NSDate distantPast]];
220 | _status = GYRollingNoticeViewStatusWorking;
221 | }
222 | }
223 |
224 | - (void)timerHandle
225 | {
226 | // NSLog(@"-----------------------------------");
227 |
228 | if (self.isAnimating) return;
229 |
230 | [self layoutCurrentCellAndWillShowCell];
231 |
232 |
233 | float w = self.frame.size.width;
234 | float h = self.frame.size.height;
235 |
236 | self.isAnimating = YES;
237 |
238 | kGYNotiWeakSelf(self);
239 | [UIView animateWithDuration:0.5 animations:^{
240 | kGYNotiStrongSelf(self);
241 |
242 | self.currentCell.frame = CGRectMake(0, -h, w, h);
243 | self.willShowCell.frame = CGRectMake(0, 0, w, h);
244 | } completion:^(BOOL finished) {
245 | kGYNotiStrongSelf(self);
246 |
247 | // fixed bug: reload data when animate running
248 | if (self.currentCell && self.willShowCell) {
249 | [self.reuseCells addObject:self.currentCell];
250 | [self.currentCell removeFromSuperview];
251 | self.currentCell = self.willShowCell;
252 | }
253 | self.isAnimating = NO;
254 |
255 | self -> _cIdx ++;
256 | }];
257 | }
258 |
259 |
260 | - (void)handleCellTapAction
261 | {
262 | if ([self.delegate respondsToSelector:@selector(didClickRollingNoticeView:forIndex:)]) {
263 | [self.delegate didClickRollingNoticeView:self forIndex:self.currentIndex];
264 | }
265 | }
266 |
267 | - (UITapGestureRecognizer *)createTapGesture
268 | {
269 | return [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleCellTapAction)];
270 | }
271 |
272 | - (void)touchesBegan:(NSSet *)touches withEvent:(nullable UIEvent *)event{}
273 |
274 |
275 | #pragma mark-
276 |
277 | - (int)currentIndex {
278 | int count = (int)[self.dataSource numberOfRowsForRollingNoticeView:self];
279 | if (_cIdx > count - 1) {
280 | _cIdx = 0;
281 | }
282 | return _cIdx;
283 | }
284 |
285 |
286 | #pragma mark- lazy
287 | - (NSMutableDictionary *)cellClsDict
288 | {
289 | if (nil == _cellClsDict) {
290 | _cellClsDict = [[NSMutableDictionary alloc]init];
291 | }
292 | return _cellClsDict;
293 | }
294 |
295 | - (NSMutableArray *)reuseCells
296 | {
297 | if (nil == _reuseCells) {
298 | _reuseCells = [[NSMutableArray alloc]init];
299 | }
300 | return _reuseCells;
301 | }
302 |
303 |
304 | @end
305 |
--------------------------------------------------------------------------------
/RollingNotice.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 48;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 916CCC9E1FDA34330070CAF3 /* CustomNoticeCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 916CCC9D1FDA34330070CAF3 /* CustomNoticeCell.m */; };
11 | 916CCCA01FDA343F0070CAF3 /* CustomNoticeCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 916CCC9F1FDA343F0070CAF3 /* CustomNoticeCell.xib */; };
12 | 919DB80E1FE0F44600029F63 /* DemoCell2.m in Sources */ = {isa = PBXBuildFile; fileRef = 919DB80D1FE0F44600029F63 /* DemoCell2.m */; };
13 | 919DB8111FE0F84400029F63 /* DemoCell3.m in Sources */ = {isa = PBXBuildFile; fileRef = 919DB8101FE0F84400029F63 /* DemoCell3.m */; };
14 | 919DB8131FE0F84E00029F63 /* DemoCell3.xib in Resources */ = {isa = PBXBuildFile; fileRef = 919DB8121FE0F84E00029F63 /* DemoCell3.xib */; };
15 | 91BA83E321194E8D002D2F85 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91BA83E121194E8D002D2F85 /* SecondViewController.m */; };
16 | 91BA83E421194E8D002D2F85 /* SecondViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 91BA83E221194E8D002D2F85 /* SecondViewController.xib */; };
17 | 91FFD87C1FD52A36004A1A27 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 91FFD87B1FD52A36004A1A27 /* AppDelegate.m */; };
18 | 91FFD87F1FD52A36004A1A27 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91FFD87E1FD52A36004A1A27 /* ViewController.m */; };
19 | 91FFD8821FD52A36004A1A27 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 91FFD8801FD52A36004A1A27 /* Main.storyboard */; };
20 | 91FFD8841FD52A36004A1A27 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 91FFD8831FD52A36004A1A27 /* Assets.xcassets */; };
21 | 91FFD8871FD52A36004A1A27 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 91FFD8851FD52A36004A1A27 /* LaunchScreen.storyboard */; };
22 | 91FFD88A1FD52A36004A1A27 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 91FFD8891FD52A36004A1A27 /* main.m */; };
23 | 91FFD8931FD52A6F004A1A27 /* GYRollingNoticeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91FFD8921FD52A6F004A1A27 /* GYRollingNoticeView.m */; };
24 | 91FFD8961FD52A96004A1A27 /* GYNoticeViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 91FFD8951FD52A96004A1A27 /* GYNoticeViewCell.m */; };
25 | B911E5C92447331000A758F5 /* ThirdViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B911E5C82447331000A758F5 /* ThirdViewController.m */; };
26 | B9C7FE0F2447121D0006323D /* DemoCodeAutoLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = B9C7FE0E2447121D0006323D /* DemoCodeAutoLayout.m */; };
27 | /* End PBXBuildFile section */
28 |
29 | /* Begin PBXFileReference section */
30 | 916CCC9C1FDA34330070CAF3 /* CustomNoticeCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomNoticeCell.h; sourceTree = ""; };
31 | 916CCC9D1FDA34330070CAF3 /* CustomNoticeCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomNoticeCell.m; sourceTree = ""; };
32 | 916CCC9F1FDA343F0070CAF3 /* CustomNoticeCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CustomNoticeCell.xib; sourceTree = ""; };
33 | 919DB80C1FE0F44600029F63 /* DemoCell2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoCell2.h; sourceTree = ""; };
34 | 919DB80D1FE0F44600029F63 /* DemoCell2.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoCell2.m; sourceTree = ""; };
35 | 919DB80F1FE0F84400029F63 /* DemoCell3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoCell3.h; sourceTree = ""; };
36 | 919DB8101FE0F84400029F63 /* DemoCell3.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoCell3.m; sourceTree = ""; };
37 | 919DB8121FE0F84E00029F63 /* DemoCell3.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DemoCell3.xib; sourceTree = ""; };
38 | 91BA83E021194E8D002D2F85 /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; };
39 | 91BA83E121194E8D002D2F85 /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; };
40 | 91BA83E221194E8D002D2F85 /* SecondViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SecondViewController.xib; sourceTree = ""; };
41 | 91FFD8771FD52A36004A1A27 /* RollingNotice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RollingNotice.app; sourceTree = BUILT_PRODUCTS_DIR; };
42 | 91FFD87A1FD52A36004A1A27 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
43 | 91FFD87B1FD52A36004A1A27 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
44 | 91FFD87D1FD52A36004A1A27 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
45 | 91FFD87E1FD52A36004A1A27 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
46 | 91FFD8811FD52A36004A1A27 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
47 | 91FFD8831FD52A36004A1A27 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
48 | 91FFD8861FD52A36004A1A27 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
49 | 91FFD8881FD52A36004A1A27 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
50 | 91FFD8891FD52A36004A1A27 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
51 | 91FFD8911FD52A6F004A1A27 /* GYRollingNoticeView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GYRollingNoticeView.h; sourceTree = ""; };
52 | 91FFD8921FD52A6F004A1A27 /* GYRollingNoticeView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GYRollingNoticeView.m; sourceTree = ""; };
53 | 91FFD8941FD52A96004A1A27 /* GYNoticeViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GYNoticeViewCell.h; sourceTree = ""; };
54 | 91FFD8951FD52A96004A1A27 /* GYNoticeViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GYNoticeViewCell.m; sourceTree = ""; };
55 | B911E5C72447331000A758F5 /* ThirdViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ThirdViewController.h; sourceTree = ""; };
56 | B911E5C82447331000A758F5 /* ThirdViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ThirdViewController.m; sourceTree = ""; };
57 | B9C7FE0D2447121D0006323D /* DemoCodeAutoLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoCodeAutoLayout.h; sourceTree = ""; };
58 | B9C7FE0E2447121D0006323D /* DemoCodeAutoLayout.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoCodeAutoLayout.m; sourceTree = ""; };
59 | /* End PBXFileReference section */
60 |
61 | /* Begin PBXFrameworksBuildPhase section */
62 | 91FFD8741FD52A36004A1A27 /* Frameworks */ = {
63 | isa = PBXFrameworksBuildPhase;
64 | buildActionMask = 2147483647;
65 | files = (
66 | );
67 | runOnlyForDeploymentPostprocessing = 0;
68 | };
69 | /* End PBXFrameworksBuildPhase section */
70 |
71 | /* Begin PBXGroup section */
72 | 91FFD86E1FD52A36004A1A27 = {
73 | isa = PBXGroup;
74 | children = (
75 | 91FFD8791FD52A36004A1A27 /* RollingNotice */,
76 | 91FFD8781FD52A36004A1A27 /* Products */,
77 | );
78 | sourceTree = "";
79 | };
80 | 91FFD8781FD52A36004A1A27 /* Products */ = {
81 | isa = PBXGroup;
82 | children = (
83 | 91FFD8771FD52A36004A1A27 /* RollingNotice.app */,
84 | );
85 | name = Products;
86 | sourceTree = "";
87 | };
88 | 91FFD8791FD52A36004A1A27 /* RollingNotice */ = {
89 | isa = PBXGroup;
90 | children = (
91 | 91FFD8901FD52A3F004A1A27 /* GYRollingNoticeView */,
92 | 91FFD87A1FD52A36004A1A27 /* AppDelegate.h */,
93 | 91FFD87B1FD52A36004A1A27 /* AppDelegate.m */,
94 | 91FFD87D1FD52A36004A1A27 /* ViewController.h */,
95 | 91FFD87E1FD52A36004A1A27 /* ViewController.m */,
96 | 91BA83E021194E8D002D2F85 /* SecondViewController.h */,
97 | 91BA83E121194E8D002D2F85 /* SecondViewController.m */,
98 | 91BA83E221194E8D002D2F85 /* SecondViewController.xib */,
99 | B911E5C72447331000A758F5 /* ThirdViewController.h */,
100 | B911E5C82447331000A758F5 /* ThirdViewController.m */,
101 | 916CCC9C1FDA34330070CAF3 /* CustomNoticeCell.h */,
102 | 916CCC9D1FDA34330070CAF3 /* CustomNoticeCell.m */,
103 | 916CCC9F1FDA343F0070CAF3 /* CustomNoticeCell.xib */,
104 | 919DB80C1FE0F44600029F63 /* DemoCell2.h */,
105 | 919DB80D1FE0F44600029F63 /* DemoCell2.m */,
106 | 919DB80F1FE0F84400029F63 /* DemoCell3.h */,
107 | 919DB8101FE0F84400029F63 /* DemoCell3.m */,
108 | 919DB8121FE0F84E00029F63 /* DemoCell3.xib */,
109 | B9C7FE0D2447121D0006323D /* DemoCodeAutoLayout.h */,
110 | B9C7FE0E2447121D0006323D /* DemoCodeAutoLayout.m */,
111 | 91FFD8801FD52A36004A1A27 /* Main.storyboard */,
112 | 91FFD8831FD52A36004A1A27 /* Assets.xcassets */,
113 | 91FFD8851FD52A36004A1A27 /* LaunchScreen.storyboard */,
114 | 91FFD8881FD52A36004A1A27 /* Info.plist */,
115 | 91FFD8891FD52A36004A1A27 /* main.m */,
116 | );
117 | path = RollingNotice;
118 | sourceTree = "";
119 | };
120 | 91FFD8901FD52A3F004A1A27 /* GYRollingNoticeView */ = {
121 | isa = PBXGroup;
122 | children = (
123 | 91FFD8911FD52A6F004A1A27 /* GYRollingNoticeView.h */,
124 | 91FFD8921FD52A6F004A1A27 /* GYRollingNoticeView.m */,
125 | 91FFD8941FD52A96004A1A27 /* GYNoticeViewCell.h */,
126 | 91FFD8951FD52A96004A1A27 /* GYNoticeViewCell.m */,
127 | );
128 | path = GYRollingNoticeView;
129 | sourceTree = "";
130 | };
131 | /* End PBXGroup section */
132 |
133 | /* Begin PBXNativeTarget section */
134 | 91FFD8761FD52A36004A1A27 /* RollingNotice */ = {
135 | isa = PBXNativeTarget;
136 | buildConfigurationList = 91FFD88D1FD52A36004A1A27 /* Build configuration list for PBXNativeTarget "RollingNotice" */;
137 | buildPhases = (
138 | 91FFD8731FD52A36004A1A27 /* Sources */,
139 | 91FFD8741FD52A36004A1A27 /* Frameworks */,
140 | 91FFD8751FD52A36004A1A27 /* Resources */,
141 | );
142 | buildRules = (
143 | );
144 | dependencies = (
145 | );
146 | name = RollingNotice;
147 | productName = RollingNotice;
148 | productReference = 91FFD8771FD52A36004A1A27 /* RollingNotice.app */;
149 | productType = "com.apple.product-type.application";
150 | };
151 | /* End PBXNativeTarget section */
152 |
153 | /* Begin PBXProject section */
154 | 91FFD86F1FD52A36004A1A27 /* Project object */ = {
155 | isa = PBXProject;
156 | attributes = {
157 | LastUpgradeCheck = 0940;
158 | ORGANIZATIONNAME = qm;
159 | TargetAttributes = {
160 | 91FFD8761FD52A36004A1A27 = {
161 | CreatedOnToolsVersion = 9.1;
162 | ProvisioningStyle = Automatic;
163 | };
164 | };
165 | };
166 | buildConfigurationList = 91FFD8721FD52A36004A1A27 /* Build configuration list for PBXProject "RollingNotice" */;
167 | compatibilityVersion = "Xcode 8.0";
168 | developmentRegion = en;
169 | hasScannedForEncodings = 0;
170 | knownRegions = (
171 | en,
172 | Base,
173 | );
174 | mainGroup = 91FFD86E1FD52A36004A1A27;
175 | productRefGroup = 91FFD8781FD52A36004A1A27 /* Products */;
176 | projectDirPath = "";
177 | projectRoot = "";
178 | targets = (
179 | 91FFD8761FD52A36004A1A27 /* RollingNotice */,
180 | );
181 | };
182 | /* End PBXProject section */
183 |
184 | /* Begin PBXResourcesBuildPhase section */
185 | 91FFD8751FD52A36004A1A27 /* Resources */ = {
186 | isa = PBXResourcesBuildPhase;
187 | buildActionMask = 2147483647;
188 | files = (
189 | 919DB8131FE0F84E00029F63 /* DemoCell3.xib in Resources */,
190 | 91FFD8871FD52A36004A1A27 /* LaunchScreen.storyboard in Resources */,
191 | 91BA83E421194E8D002D2F85 /* SecondViewController.xib in Resources */,
192 | 91FFD8841FD52A36004A1A27 /* Assets.xcassets in Resources */,
193 | 916CCCA01FDA343F0070CAF3 /* CustomNoticeCell.xib in Resources */,
194 | 91FFD8821FD52A36004A1A27 /* Main.storyboard in Resources */,
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | };
198 | /* End PBXResourcesBuildPhase section */
199 |
200 | /* Begin PBXSourcesBuildPhase section */
201 | 91FFD8731FD52A36004A1A27 /* Sources */ = {
202 | isa = PBXSourcesBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | 91BA83E321194E8D002D2F85 /* SecondViewController.m in Sources */,
206 | 916CCC9E1FDA34330070CAF3 /* CustomNoticeCell.m in Sources */,
207 | B9C7FE0F2447121D0006323D /* DemoCodeAutoLayout.m in Sources */,
208 | 91FFD8961FD52A96004A1A27 /* GYNoticeViewCell.m in Sources */,
209 | 919DB80E1FE0F44600029F63 /* DemoCell2.m in Sources */,
210 | B911E5C92447331000A758F5 /* ThirdViewController.m in Sources */,
211 | 91FFD8931FD52A6F004A1A27 /* GYRollingNoticeView.m in Sources */,
212 | 91FFD87F1FD52A36004A1A27 /* ViewController.m in Sources */,
213 | 91FFD88A1FD52A36004A1A27 /* main.m in Sources */,
214 | 919DB8111FE0F84400029F63 /* DemoCell3.m in Sources */,
215 | 91FFD87C1FD52A36004A1A27 /* AppDelegate.m in Sources */,
216 | );
217 | runOnlyForDeploymentPostprocessing = 0;
218 | };
219 | /* End PBXSourcesBuildPhase section */
220 |
221 | /* Begin PBXVariantGroup section */
222 | 91FFD8801FD52A36004A1A27 /* Main.storyboard */ = {
223 | isa = PBXVariantGroup;
224 | children = (
225 | 91FFD8811FD52A36004A1A27 /* Base */,
226 | );
227 | name = Main.storyboard;
228 | sourceTree = "";
229 | };
230 | 91FFD8851FD52A36004A1A27 /* LaunchScreen.storyboard */ = {
231 | isa = PBXVariantGroup;
232 | children = (
233 | 91FFD8861FD52A36004A1A27 /* Base */,
234 | );
235 | name = LaunchScreen.storyboard;
236 | sourceTree = "";
237 | };
238 | /* End PBXVariantGroup section */
239 |
240 | /* Begin XCBuildConfiguration section */
241 | 91FFD88B1FD52A36004A1A27 /* Debug */ = {
242 | isa = XCBuildConfiguration;
243 | buildSettings = {
244 | ALWAYS_SEARCH_USER_PATHS = NO;
245 | CLANG_ANALYZER_NONNULL = YES;
246 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
247 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
248 | CLANG_CXX_LIBRARY = "libc++";
249 | CLANG_ENABLE_MODULES = YES;
250 | CLANG_ENABLE_OBJC_ARC = YES;
251 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
252 | CLANG_WARN_BOOL_CONVERSION = YES;
253 | CLANG_WARN_COMMA = YES;
254 | CLANG_WARN_CONSTANT_CONVERSION = YES;
255 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
256 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
257 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
258 | CLANG_WARN_EMPTY_BODY = YES;
259 | CLANG_WARN_ENUM_CONVERSION = YES;
260 | CLANG_WARN_INFINITE_RECURSION = YES;
261 | CLANG_WARN_INT_CONVERSION = YES;
262 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
263 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
264 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
265 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
266 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
267 | CLANG_WARN_STRICT_PROTOTYPES = YES;
268 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
269 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
270 | CLANG_WARN_UNREACHABLE_CODE = YES;
271 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
272 | CODE_SIGN_IDENTITY = "iPhone Developer";
273 | COPY_PHASE_STRIP = NO;
274 | DEBUG_INFORMATION_FORMAT = dwarf;
275 | ENABLE_STRICT_OBJC_MSGSEND = YES;
276 | ENABLE_TESTABILITY = YES;
277 | GCC_C_LANGUAGE_STANDARD = gnu11;
278 | GCC_DYNAMIC_NO_PIC = NO;
279 | GCC_NO_COMMON_BLOCKS = YES;
280 | GCC_OPTIMIZATION_LEVEL = 0;
281 | GCC_PREPROCESSOR_DEFINITIONS = (
282 | "DEBUG=1",
283 | "$(inherited)",
284 | );
285 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
286 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
287 | GCC_WARN_UNDECLARED_SELECTOR = YES;
288 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
289 | GCC_WARN_UNUSED_FUNCTION = YES;
290 | GCC_WARN_UNUSED_VARIABLE = YES;
291 | IPHONEOS_DEPLOYMENT_TARGET = 11.1;
292 | MTL_ENABLE_DEBUG_INFO = YES;
293 | ONLY_ACTIVE_ARCH = YES;
294 | SDKROOT = iphoneos;
295 | };
296 | name = Debug;
297 | };
298 | 91FFD88C1FD52A36004A1A27 /* Release */ = {
299 | isa = XCBuildConfiguration;
300 | buildSettings = {
301 | ALWAYS_SEARCH_USER_PATHS = NO;
302 | CLANG_ANALYZER_NONNULL = YES;
303 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
304 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
305 | CLANG_CXX_LIBRARY = "libc++";
306 | CLANG_ENABLE_MODULES = YES;
307 | CLANG_ENABLE_OBJC_ARC = YES;
308 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
309 | CLANG_WARN_BOOL_CONVERSION = YES;
310 | CLANG_WARN_COMMA = YES;
311 | CLANG_WARN_CONSTANT_CONVERSION = YES;
312 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_NON_LITERAL_NULL_CONVERSION = YES;
320 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
321 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
322 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
323 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
324 | CLANG_WARN_STRICT_PROTOTYPES = YES;
325 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
326 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
327 | CLANG_WARN_UNREACHABLE_CODE = YES;
328 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
329 | CODE_SIGN_IDENTITY = "iPhone Developer";
330 | COPY_PHASE_STRIP = NO;
331 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
332 | ENABLE_NS_ASSERTIONS = NO;
333 | ENABLE_STRICT_OBJC_MSGSEND = YES;
334 | GCC_C_LANGUAGE_STANDARD = gnu11;
335 | GCC_NO_COMMON_BLOCKS = YES;
336 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
337 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
338 | GCC_WARN_UNDECLARED_SELECTOR = YES;
339 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
340 | GCC_WARN_UNUSED_FUNCTION = YES;
341 | GCC_WARN_UNUSED_VARIABLE = YES;
342 | IPHONEOS_DEPLOYMENT_TARGET = 11.1;
343 | MTL_ENABLE_DEBUG_INFO = NO;
344 | SDKROOT = iphoneos;
345 | VALIDATE_PRODUCT = YES;
346 | };
347 | name = Release;
348 | };
349 | 91FFD88E1FD52A36004A1A27 /* Debug */ = {
350 | isa = XCBuildConfiguration;
351 | buildSettings = {
352 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
353 | CODE_SIGN_STYLE = Automatic;
354 | DEVELOPMENT_TEAM = 27LXXFK99P;
355 | INFOPLIST_FILE = RollingNotice/Info.plist;
356 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
357 | PRODUCT_BUNDLE_IDENTIFIER = com.qmcaifu.RollingNotice;
358 | PRODUCT_NAME = "$(TARGET_NAME)";
359 | TARGETED_DEVICE_FAMILY = "1,2";
360 | };
361 | name = Debug;
362 | };
363 | 91FFD88F1FD52A36004A1A27 /* Release */ = {
364 | isa = XCBuildConfiguration;
365 | buildSettings = {
366 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
367 | CODE_SIGN_STYLE = Automatic;
368 | DEVELOPMENT_TEAM = 27LXXFK99P;
369 | INFOPLIST_FILE = RollingNotice/Info.plist;
370 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
371 | PRODUCT_BUNDLE_IDENTIFIER = com.qmcaifu.RollingNotice;
372 | PRODUCT_NAME = "$(TARGET_NAME)";
373 | TARGETED_DEVICE_FAMILY = "1,2";
374 | };
375 | name = Release;
376 | };
377 | /* End XCBuildConfiguration section */
378 |
379 | /* Begin XCConfigurationList section */
380 | 91FFD8721FD52A36004A1A27 /* Build configuration list for PBXProject "RollingNotice" */ = {
381 | isa = XCConfigurationList;
382 | buildConfigurations = (
383 | 91FFD88B1FD52A36004A1A27 /* Debug */,
384 | 91FFD88C1FD52A36004A1A27 /* Release */,
385 | );
386 | defaultConfigurationIsVisible = 0;
387 | defaultConfigurationName = Release;
388 | };
389 | 91FFD88D1FD52A36004A1A27 /* Build configuration list for PBXNativeTarget "RollingNotice" */ = {
390 | isa = XCConfigurationList;
391 | buildConfigurations = (
392 | 91FFD88E1FD52A36004A1A27 /* Debug */,
393 | 91FFD88F1FD52A36004A1A27 /* Release */,
394 | );
395 | defaultConfigurationIsVisible = 0;
396 | defaultConfigurationName = Release;
397 | };
398 | /* End XCConfigurationList section */
399 | };
400 | rootObject = 91FFD86F1FD52A36004A1A27 /* Project object */;
401 | }
402 |
--------------------------------------------------------------------------------