├── .DS_Store
├── .swiftpm
└── xcode
│ ├── package.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── stewart.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ └── stewart.xcuserdatad
│ └── xcschemes
│ └── xcschememanagement.plist
├── .travis.yml
├── Example
├── AppleTv
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── App Icon & Top Shelf Image.brandassets
│ │ │ ├── App Icon - App Store.imagestack
│ │ │ │ ├── Back.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Front.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Middle.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ ├── App Icon.imagestack
│ │ │ │ ├── Back.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Front.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Middle.imagestacklayer
│ │ │ │ │ ├── Content.imageset
│ │ │ │ │ └── Contents.json
│ │ │ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ ├── Top Shelf Image Wide.imageset
│ │ │ │ └── Contents.json
│ │ │ └── Top Shelf Image.imageset
│ │ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ └── LaunchImage.launchimage
│ │ │ └── Contents.json
│ ├── Base.lproj
│ │ └── Main.storyboard
│ ├── Info.plist
│ └── ViewController.swift
├── Podfile
├── Podfile.lock
├── Pods
│ ├── Local Podspecs
│ │ └── SwiftTickerView.podspec.json
│ ├── Manifest.lock
│ ├── Pods.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcuserdata
│ │ │ └── stewart.xcuserdatad
│ │ │ └── xcschemes
│ │ │ ├── Pods-SwiftTickerView_Example.xcscheme
│ │ │ ├── Pods-SwiftTickerView_Tests.xcscheme
│ │ │ ├── Pods-appletv.xcscheme
│ │ │ ├── Pods-appletvTests.xcscheme
│ │ │ ├── SwiftTickerView-iOS.xcscheme
│ │ │ ├── SwiftTickerView-tvOS.xcscheme
│ │ │ └── xcschememanagement.plist
│ └── Target Support Files
│ │ ├── Pods-SwiftTickerView_Example
│ │ ├── Pods-SwiftTickerView_Example-Info.plist
│ │ ├── Pods-SwiftTickerView_Example-acknowledgements.markdown
│ │ ├── Pods-SwiftTickerView_Example-acknowledgements.plist
│ │ ├── Pods-SwiftTickerView_Example-dummy.m
│ │ ├── Pods-SwiftTickerView_Example-frameworks.sh
│ │ ├── Pods-SwiftTickerView_Example-umbrella.h
│ │ ├── Pods-SwiftTickerView_Example.debug.xcconfig
│ │ ├── Pods-SwiftTickerView_Example.modulemap
│ │ └── Pods-SwiftTickerView_Example.release.xcconfig
│ │ ├── Pods-SwiftTickerView_Tests
│ │ ├── Pods-SwiftTickerView_Tests-Info.plist
│ │ ├── Pods-SwiftTickerView_Tests-acknowledgements.markdown
│ │ ├── Pods-SwiftTickerView_Tests-acknowledgements.plist
│ │ ├── Pods-SwiftTickerView_Tests-dummy.m
│ │ ├── Pods-SwiftTickerView_Tests-umbrella.h
│ │ ├── Pods-SwiftTickerView_Tests.debug.xcconfig
│ │ ├── Pods-SwiftTickerView_Tests.modulemap
│ │ └── Pods-SwiftTickerView_Tests.release.xcconfig
│ │ ├── Pods-appletv
│ │ ├── Pods-appletv-Info.plist
│ │ ├── Pods-appletv-acknowledgements.markdown
│ │ ├── Pods-appletv-acknowledgements.plist
│ │ ├── Pods-appletv-dummy.m
│ │ ├── Pods-appletv-frameworks.sh
│ │ ├── Pods-appletv-umbrella.h
│ │ ├── Pods-appletv.debug.xcconfig
│ │ ├── Pods-appletv.modulemap
│ │ └── Pods-appletv.release.xcconfig
│ │ ├── Pods-appletvTests
│ │ ├── Pods-appletvTests-Info.plist
│ │ ├── Pods-appletvTests-acknowledgements.markdown
│ │ ├── Pods-appletvTests-acknowledgements.plist
│ │ ├── Pods-appletvTests-dummy.m
│ │ ├── Pods-appletvTests-umbrella.h
│ │ ├── Pods-appletvTests.debug.xcconfig
│ │ ├── Pods-appletvTests.modulemap
│ │ └── Pods-appletvTests.release.xcconfig
│ │ ├── SwiftTickerView-iOS
│ │ ├── SwiftTickerView-iOS-Info.plist
│ │ ├── SwiftTickerView-iOS-dummy.m
│ │ ├── SwiftTickerView-iOS-prefix.pch
│ │ ├── SwiftTickerView-iOS-umbrella.h
│ │ ├── SwiftTickerView-iOS.modulemap
│ │ └── SwiftTickerView-iOS.xcconfig
│ │ └── SwiftTickerView-tvOS
│ │ ├── SwiftTickerView-tvOS-Info.plist
│ │ ├── SwiftTickerView-tvOS-dummy.m
│ │ ├── SwiftTickerView-tvOS-prefix.pch
│ │ ├── SwiftTickerView-tvOS-umbrella.h
│ │ ├── SwiftTickerView-tvOS.modulemap
│ │ └── SwiftTickerView-tvOS.xcconfig
├── SwiftTickerView.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── SwiftTickerView-Example.xcscheme
│ └── xcuserdata
│ │ └── stewart.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── SwiftTickerView.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ └── stewart.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
├── SwiftTickerView
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ ├── LaunchScreen.xib
│ │ └── Main.storyboard
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── NodeView.xib
│ ├── TickerProvider.swift
│ └── ViewController.swift
├── Tests
│ ├── Info.plist
│ └── Tests.swift
├── appletvTests
│ ├── Info.plist
│ └── appletvTests.swift
└── appletvUITests
│ ├── Info.plist
│ └── appletvUITests.swift
├── LICENSE
├── Package.swift
├── README.md
├── Sources
└── SwiftTickerView
│ ├── .gitkeep
│ ├── DefaultConditionBehaviour.swift
│ ├── Renderer.swift
│ ├── SwiftTickerItemDecorator.swift
│ └── SwiftTickerView.swift
├── SwiftTickerView.podspec
└── _Pods.xcodeproj
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EMart86/SwiftTickerView/3229ba4e4c8283a7fd1601064d2f857f03544179/.DS_Store
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/xcuserdata/stewart.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EMart86/SwiftTickerView/3229ba4e4c8283a7fd1601064d2f857f03544179/.swiftpm/xcode/package.xcworkspace/xcuserdata/stewart.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/.swiftpm/xcode/xcuserdata/stewart.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SwiftTickerView.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # references:
2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/
3 | # * https://github.com/supermarin/xcpretty#usage
4 |
5 | osx_image: xcode10.0
6 | language: swift
7 | # cache: cocoapods
8 | # podfile: Example/Podfile
9 | # before_install:
10 | # - gem install cocoapods # Since Travis is not always on latest version
11 | # - pod install --project-directory=Example
12 | script:
13 | - pod lib lint --allow-warnings
14 |
--------------------------------------------------------------------------------
/Example/AppleTv/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // appletv
4 | //
5 | // Created by Martin Eberl on 22.01.18.
6 | // Copyright © 2018 CocoaPods. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // 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.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // 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.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // 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.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // 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.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv"
5 | }
6 | ],
7 | "info" : {
8 | "version" : 1,
9 | "author" : "xcode"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv"
5 | }
6 | ],
7 | "info" : {
8 | "version" : 1,
9 | "author" : "xcode"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv"
5 | }
6 | ],
7 | "info" : {
8 | "version" : 1,
9 | "author" : "xcode"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "assets" : [
3 | {
4 | "size" : "1280x768",
5 | "idiom" : "tv",
6 | "filename" : "App Icon - App Store.imagestack",
7 | "role" : "primary-app-icon"
8 | },
9 | {
10 | "size" : "400x240",
11 | "idiom" : "tv",
12 | "filename" : "App Icon.imagestack",
13 | "role" : "primary-app-icon"
14 | },
15 | {
16 | "size" : "2320x720",
17 | "idiom" : "tv",
18 | "filename" : "Top Shelf Image Wide.imageset",
19 | "role" : "top-shelf-image-wide"
20 | },
21 | {
22 | "size" : "1920x720",
23 | "idiom" : "tv",
24 | "filename" : "Top Shelf Image.imageset",
25 | "role" : "top-shelf-image"
26 | }
27 | ],
28 | "info" : {
29 | "version" : 1,
30 | "author" : "xcode"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Assets.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "landscape",
5 | "idiom" : "tv",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "9.0",
8 | "scale" : "1x"
9 | }
10 | ],
11 | "info" : {
12 | "version" : 1,
13 | "author" : "xcode"
14 | }
15 | }
--------------------------------------------------------------------------------
/Example/AppleTv/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
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 |
--------------------------------------------------------------------------------
/Example/AppleTv/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 | UIMainStoryboardFile
22 | Main
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Example/AppleTv/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SwiftTickerView
4 | //
5 | // Created by eberl_ma@gmx.at on 08/15/2017.
6 | // Copyright (c) 2017 eberl_ma@gmx.at. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftTickerView
11 |
12 | class ViewController: UIViewController {
13 | fileprivate let labelIdentifier = "TextMessage"
14 | @IBOutlet weak var tickerView: SwiftTickerView!
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 | // Do any additional setup after loading the view, typically from a nib.
19 |
20 | tickerView.contentProvider = TickerProvider()
21 | tickerView.viewProvider = self
22 | tickerView.separator = "+++"
23 | tickerView.registerNodeView(UILabel.self, for: labelIdentifier)
24 | tickerView.render = Renderer.rightToLeft
25 | tickerView.tickerDelegate = self
26 | }
27 |
28 | override func viewWillAppear(_ animated: Bool) {
29 | super.viewWillAppear(animated)
30 | tickerView.start()
31 | }
32 |
33 | override func viewWillDisappear(_ animated: Bool) {
34 | super.viewWillDisappear(animated)
35 | tickerView.stop()
36 | }
37 | }
38 |
39 | extension ViewController: SwiftTickerDelegate {
40 | func tickerView(willResume ticker: SwiftTickerView) {}
41 | func tickerView(willStart ticker: SwiftTickerView) {}
42 | func tickerView(willStop ticker: SwiftTickerView) {}
43 | func tickerView(didPress view: UIView, content: Any?) {}
44 | }
45 |
46 | extension ViewController: SwiftTickerViewProvider {
47 | func tickerView(_ tickerView: SwiftTickerView, prepareSeparator separator: UIView) {
48 | if let separator = separator as? UILabel {
49 | separator.textColor = .white
50 | }
51 | }
52 |
53 | func tickerView(_ tickerView: SwiftTickerView, viewFor: Any) -> (UIView, reuseIdentifier: String?) {
54 | if let text = viewFor as? String,
55 | let label = tickerView.dequeReusableNodeView(for: labelIdentifier) as? UILabel {
56 | label.text = text
57 | label.sizeToFit()
58 | label.textColor = .white
59 | return (label, reuseIdentifier: labelIdentifier)
60 | }
61 | return (UIView(), reuseIdentifier: nil)
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | use_frameworks!
2 |
3 | target 'SwiftTickerView_Example' do
4 | pod 'SwiftTickerView', :path => '../'
5 |
6 | target 'SwiftTickerView_Tests' do
7 | inherit! :search_paths
8 |
9 |
10 | end
11 | end
12 |
13 | target 'appletv' do
14 | pod 'SwiftTickerView', :path => '../'
15 |
16 | target 'appletvTests' do
17 | inherit! :search_paths
18 |
19 |
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/Example/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - SwiftTickerView (1.5.0)
3 |
4 | DEPENDENCIES:
5 | - SwiftTickerView (from `../`)
6 |
7 | EXTERNAL SOURCES:
8 | SwiftTickerView:
9 | :path: "../"
10 |
11 | SPEC CHECKSUMS:
12 | SwiftTickerView: 80aa186bf9cfbea31e9daa367d8b84823e4ef809
13 |
14 | PODFILE CHECKSUM: 0913893b3c3ed3f27b9a63d863d7215ddc13a471
15 |
16 | COCOAPODS: 1.7.5
17 |
--------------------------------------------------------------------------------
/Example/Pods/Local Podspecs/SwiftTickerView.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "SwiftTickerView",
3 | "version": "1.5.0",
4 | "summary": "A simple news ticker view",
5 | "swift_versions": "4.2",
6 | "description": "A swift ticker, written in swift. The one, with those '+++' separators ;)",
7 | "homepage": "https://github.com/EMart86/SwiftTickerView",
8 | "license": {
9 | "type": "MIT",
10 | "file": "LICENSE"
11 | },
12 | "authors": {
13 | "Martin Eberl": "eberl_ma@gmx.at"
14 | },
15 | "source": {
16 | "git": "https://github.com/EMart86/SwiftTickerView.git",
17 | "tag": "1.5.0"
18 | },
19 | "platforms": {
20 | "ios": "9.0",
21 | "tvos": "9.0"
22 | },
23 | "source_files": "Sources/SwiftTickerView/*",
24 | "swift_version": "4.2"
25 | }
26 |
--------------------------------------------------------------------------------
/Example/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - SwiftTickerView (1.5.0)
3 |
4 | DEPENDENCIES:
5 | - SwiftTickerView (from `../`)
6 |
7 | EXTERNAL SOURCES:
8 | SwiftTickerView:
9 | :path: "../"
10 |
11 | SPEC CHECKSUMS:
12 | SwiftTickerView: 80aa186bf9cfbea31e9daa367d8b84823e4ef809
13 |
14 | PODFILE CHECKSUM: 0913893b3c3ed3f27b9a63d863d7215ddc13a471
15 |
16 | COCOAPODS: 1.7.5
17 |
--------------------------------------------------------------------------------
/Example/Pods/Pods.xcodeproj/xcuserdata/stewart.xcuserdatad/xcschemes/Pods-SwiftTickerView_Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Example/Pods/Pods.xcodeproj/xcuserdata/stewart.xcuserdatad/xcschemes/Pods-SwiftTickerView_Tests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Example/Pods/Pods.xcodeproj/xcuserdata/stewart.xcuserdatad/xcschemes/Pods-appletv.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Example/Pods/Pods.xcodeproj/xcuserdata/stewart.xcuserdatad/xcschemes/Pods-appletvTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Example/Pods/Pods.xcodeproj/xcuserdata/stewart.xcuserdatad/xcschemes/SwiftTickerView-iOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Example/Pods/Pods.xcodeproj/xcuserdata/stewart.xcuserdatad/xcschemes/SwiftTickerView-tvOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Example/Pods/Pods.xcodeproj/xcuserdata/stewart.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Pods-SwiftTickerView_Example.xcscheme
8 |
9 | isShown
10 |
11 | orderHint
12 | 3
13 |
14 | Pods-SwiftTickerView_Tests.xcscheme
15 |
16 | isShown
17 |
18 | orderHint
19 | 4
20 |
21 | Pods-appletv.xcscheme
22 |
23 | isShown
24 |
25 | orderHint
26 | 1
27 |
28 | Pods-appletvTests.xcscheme
29 |
30 | isShown
31 |
32 | orderHint
33 | 2
34 |
35 | SwiftTickerView-iOS.xcscheme
36 |
37 | isShown
38 |
39 | orderHint
40 | 5
41 |
42 | SwiftTickerView-tvOS.xcscheme
43 |
44 | isShown
45 |
46 | orderHint
47 | 6
48 |
49 |
50 | SuppressBuildableAutocreation
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Example/Pods-SwiftTickerView_Example-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Example/Pods-SwiftTickerView_Example-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## SwiftTickerView
5 |
6 | Copyright (c) 2019 Martin Eberl
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
26 | Generated by CocoaPods - https://cocoapods.org
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Example/Pods-SwiftTickerView_Example-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | Copyright (c) 2019 Martin Eberl <eberl_ma@gmx.at>
18 |
19 | Permission is hereby granted, free of charge, to any person obtaining a copy
20 | of this software and associated documentation files (the "Software"), to deal
21 | in the Software without restriction, including without limitation the rights
22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23 | copies of the Software, and to permit persons to whom the Software is
24 | furnished to do so, subject to the following conditions:
25 |
26 | The above copyright notice and this permission notice shall be included in
27 | all copies or substantial portions of the Software.
28 |
29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
35 | THE SOFTWARE.
36 |
37 | License
38 | MIT
39 | Title
40 | SwiftTickerView
41 | Type
42 | PSGroupSpecifier
43 |
44 |
45 | FooterText
46 | Generated by CocoaPods - https://cocoapods.org
47 | Title
48 |
49 | Type
50 | PSGroupSpecifier
51 |
52 |
53 | StringsTable
54 | Acknowledgements
55 | Title
56 | Acknowledgements
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Example/Pods-SwiftTickerView_Example-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_SwiftTickerView_Example : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_SwiftTickerView_Example
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Example/Pods-SwiftTickerView_Example-frameworks.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -u
4 | set -o pipefail
5 |
6 | function on_error {
7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
8 | }
9 | trap 'on_error $LINENO' ERR
10 |
11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
13 | # frameworks to, so exit 0 (signalling the script phase was successful).
14 | exit 0
15 | fi
16 |
17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
19 |
20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
22 |
23 | # Used as a return value for each invocation of `strip_invalid_archs` function.
24 | STRIP_BINARY_RETVAL=0
25 |
26 | # This protects against multiple targets copying the same framework dependency at the same time. The solution
27 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
28 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
29 |
30 | # Copies and strips a vendored framework
31 | install_framework()
32 | {
33 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
34 | local source="${BUILT_PRODUCTS_DIR}/$1"
35 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
36 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
37 | elif [ -r "$1" ]; then
38 | local source="$1"
39 | fi
40 |
41 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
42 |
43 | if [ -L "${source}" ]; then
44 | echo "Symlinked..."
45 | source="$(readlink "${source}")"
46 | fi
47 |
48 | # Use filter instead of exclude so missing patterns don't throw errors.
49 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
50 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
51 |
52 | local basename
53 | basename="$(basename -s .framework "$1")"
54 | binary="${destination}/${basename}.framework/${basename}"
55 |
56 | if ! [ -r "$binary" ]; then
57 | binary="${destination}/${basename}"
58 | elif [ -L "${binary}" ]; then
59 | echo "Destination binary is symlinked..."
60 | dirname="$(dirname "${binary}")"
61 | binary="${dirname}/$(readlink "${binary}")"
62 | fi
63 |
64 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
65 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
66 | strip_invalid_archs "$binary"
67 | fi
68 |
69 | # Resign the code if required by the build settings to avoid unstable apps
70 | code_sign_if_enabled "${destination}/$(basename "$1")"
71 |
72 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
73 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
74 | local swift_runtime_libs
75 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
76 | for lib in $swift_runtime_libs; do
77 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
78 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
79 | code_sign_if_enabled "${destination}/${lib}"
80 | done
81 | fi
82 | }
83 |
84 | # Copies and strips a vendored dSYM
85 | install_dsym() {
86 | local source="$1"
87 | if [ -r "$source" ]; then
88 | # Copy the dSYM into a the targets temp dir.
89 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
90 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
91 |
92 | local basename
93 | basename="$(basename -s .framework.dSYM "$source")"
94 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
95 |
96 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
97 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
98 | strip_invalid_archs "$binary"
99 | fi
100 |
101 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
102 | # Move the stripped file into its final destination.
103 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
104 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
105 | else
106 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
107 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
108 | fi
109 | fi
110 | }
111 |
112 | # Copies the bcsymbolmap files of a vendored framework
113 | install_bcsymbolmap() {
114 | local bcsymbolmap_path="$1"
115 | local destination="${BUILT_PRODUCTS_DIR}"
116 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
117 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
118 | }
119 |
120 | # Signs a framework with the provided identity
121 | code_sign_if_enabled() {
122 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
123 | # Use the current code_sign_identity
124 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
125 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
126 |
127 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
128 | code_sign_cmd="$code_sign_cmd &"
129 | fi
130 | echo "$code_sign_cmd"
131 | eval "$code_sign_cmd"
132 | fi
133 | }
134 |
135 | # Strip invalid architectures
136 | strip_invalid_archs() {
137 | binary="$1"
138 | # Get architectures for current target binary
139 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
140 | # Intersect them with the architectures we are building for
141 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
142 | # If there are no archs supported by this binary then warn the user
143 | if [[ -z "$intersected_archs" ]]; then
144 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
145 | STRIP_BINARY_RETVAL=0
146 | return
147 | fi
148 | stripped=""
149 | for arch in $binary_archs; do
150 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then
151 | # Strip non-valid architectures in-place
152 | lipo -remove "$arch" -output "$binary" "$binary"
153 | stripped="$stripped $arch"
154 | fi
155 | done
156 | if [[ "$stripped" ]]; then
157 | echo "Stripped $binary of architectures:$stripped"
158 | fi
159 | STRIP_BINARY_RETVAL=1
160 | }
161 |
162 |
163 | if [[ "$CONFIGURATION" == "Debug" ]]; then
164 | install_framework "${BUILT_PRODUCTS_DIR}/SwiftTickerView-iOS/SwiftTickerView.framework"
165 | fi
166 | if [[ "$CONFIGURATION" == "Release" ]]; then
167 | install_framework "${BUILT_PRODUCTS_DIR}/SwiftTickerView-iOS/SwiftTickerView.framework"
168 | fi
169 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
170 | wait
171 | fi
172 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Example/Pods-SwiftTickerView_Example-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_SwiftTickerView_ExampleVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_SwiftTickerView_ExampleVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Example/Pods-SwiftTickerView_Example.debug.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-iOS"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-iOS/SwiftTickerView.framework/Headers"
5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftTickerView"
7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Example/Pods-SwiftTickerView_Example.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_SwiftTickerView_Example {
2 | umbrella header "Pods-SwiftTickerView_Example-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Example/Pods-SwiftTickerView_Example.release.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-iOS"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-iOS/SwiftTickerView.framework/Headers"
5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftTickerView"
7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Tests/Pods-SwiftTickerView_Tests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Tests/Pods-SwiftTickerView_Tests-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 | Generated by CocoaPods - https://cocoapods.org
4 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Tests/Pods-SwiftTickerView_Tests-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | Generated by CocoaPods - https://cocoapods.org
18 | Title
19 |
20 | Type
21 | PSGroupSpecifier
22 |
23 |
24 | StringsTable
25 | Acknowledgements
26 | Title
27 | Acknowledgements
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Tests/Pods-SwiftTickerView_Tests-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_SwiftTickerView_Tests : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_SwiftTickerView_Tests
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Tests/Pods-SwiftTickerView_Tests-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_SwiftTickerView_TestsVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_SwiftTickerView_TestsVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Tests/Pods-SwiftTickerView_Tests.debug.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-iOS"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-iOS/SwiftTickerView.framework/Headers"
4 | OTHER_LDFLAGS = $(inherited) -framework "SwiftTickerView"
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
8 | PODS_ROOT = ${SRCROOT}/Pods
9 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Tests/Pods-SwiftTickerView_Tests.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_SwiftTickerView_Tests {
2 | umbrella header "Pods-SwiftTickerView_Tests-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-SwiftTickerView_Tests/Pods-SwiftTickerView_Tests.release.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-iOS"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-iOS/SwiftTickerView.framework/Headers"
4 | OTHER_LDFLAGS = $(inherited) -framework "SwiftTickerView"
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
8 | PODS_ROOT = ${SRCROOT}/Pods
9 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletv/Pods-appletv-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletv/Pods-appletv-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## SwiftTickerView
5 |
6 | Copyright (c) 2019 Martin Eberl
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
26 | Generated by CocoaPods - https://cocoapods.org
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletv/Pods-appletv-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | Copyright (c) 2019 Martin Eberl <eberl_ma@gmx.at>
18 |
19 | Permission is hereby granted, free of charge, to any person obtaining a copy
20 | of this software and associated documentation files (the "Software"), to deal
21 | in the Software without restriction, including without limitation the rights
22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23 | copies of the Software, and to permit persons to whom the Software is
24 | furnished to do so, subject to the following conditions:
25 |
26 | The above copyright notice and this permission notice shall be included in
27 | all copies or substantial portions of the Software.
28 |
29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
35 | THE SOFTWARE.
36 |
37 | License
38 | MIT
39 | Title
40 | SwiftTickerView
41 | Type
42 | PSGroupSpecifier
43 |
44 |
45 | FooterText
46 | Generated by CocoaPods - https://cocoapods.org
47 | Title
48 |
49 | Type
50 | PSGroupSpecifier
51 |
52 |
53 | StringsTable
54 | Acknowledgements
55 | Title
56 | Acknowledgements
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletv/Pods-appletv-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_appletv : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_appletv
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletv/Pods-appletv-frameworks.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -u
4 | set -o pipefail
5 |
6 | function on_error {
7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
8 | }
9 | trap 'on_error $LINENO' ERR
10 |
11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
13 | # frameworks to, so exit 0 (signalling the script phase was successful).
14 | exit 0
15 | fi
16 |
17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
19 |
20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
22 |
23 | # Used as a return value for each invocation of `strip_invalid_archs` function.
24 | STRIP_BINARY_RETVAL=0
25 |
26 | # This protects against multiple targets copying the same framework dependency at the same time. The solution
27 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
28 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
29 |
30 | # Copies and strips a vendored framework
31 | install_framework()
32 | {
33 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
34 | local source="${BUILT_PRODUCTS_DIR}/$1"
35 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
36 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
37 | elif [ -r "$1" ]; then
38 | local source="$1"
39 | fi
40 |
41 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
42 |
43 | if [ -L "${source}" ]; then
44 | echo "Symlinked..."
45 | source="$(readlink "${source}")"
46 | fi
47 |
48 | # Use filter instead of exclude so missing patterns don't throw errors.
49 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
50 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
51 |
52 | local basename
53 | basename="$(basename -s .framework "$1")"
54 | binary="${destination}/${basename}.framework/${basename}"
55 |
56 | if ! [ -r "$binary" ]; then
57 | binary="${destination}/${basename}"
58 | elif [ -L "${binary}" ]; then
59 | echo "Destination binary is symlinked..."
60 | dirname="$(dirname "${binary}")"
61 | binary="${dirname}/$(readlink "${binary}")"
62 | fi
63 |
64 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
65 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
66 | strip_invalid_archs "$binary"
67 | fi
68 |
69 | # Resign the code if required by the build settings to avoid unstable apps
70 | code_sign_if_enabled "${destination}/$(basename "$1")"
71 |
72 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
73 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
74 | local swift_runtime_libs
75 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
76 | for lib in $swift_runtime_libs; do
77 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
78 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
79 | code_sign_if_enabled "${destination}/${lib}"
80 | done
81 | fi
82 | }
83 |
84 | # Copies and strips a vendored dSYM
85 | install_dsym() {
86 | local source="$1"
87 | if [ -r "$source" ]; then
88 | # Copy the dSYM into a the targets temp dir.
89 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
90 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
91 |
92 | local basename
93 | basename="$(basename -s .framework.dSYM "$source")"
94 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
95 |
96 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
97 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
98 | strip_invalid_archs "$binary"
99 | fi
100 |
101 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
102 | # Move the stripped file into its final destination.
103 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
104 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
105 | else
106 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
107 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
108 | fi
109 | fi
110 | }
111 |
112 | # Copies the bcsymbolmap files of a vendored framework
113 | install_bcsymbolmap() {
114 | local bcsymbolmap_path="$1"
115 | local destination="${BUILT_PRODUCTS_DIR}"
116 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
117 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
118 | }
119 |
120 | # Signs a framework with the provided identity
121 | code_sign_if_enabled() {
122 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
123 | # Use the current code_sign_identity
124 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
125 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
126 |
127 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
128 | code_sign_cmd="$code_sign_cmd &"
129 | fi
130 | echo "$code_sign_cmd"
131 | eval "$code_sign_cmd"
132 | fi
133 | }
134 |
135 | # Strip invalid architectures
136 | strip_invalid_archs() {
137 | binary="$1"
138 | # Get architectures for current target binary
139 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
140 | # Intersect them with the architectures we are building for
141 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
142 | # If there are no archs supported by this binary then warn the user
143 | if [[ -z "$intersected_archs" ]]; then
144 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
145 | STRIP_BINARY_RETVAL=0
146 | return
147 | fi
148 | stripped=""
149 | for arch in $binary_archs; do
150 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then
151 | # Strip non-valid architectures in-place
152 | lipo -remove "$arch" -output "$binary" "$binary"
153 | stripped="$stripped $arch"
154 | fi
155 | done
156 | if [[ "$stripped" ]]; then
157 | echo "Stripped $binary of architectures:$stripped"
158 | fi
159 | STRIP_BINARY_RETVAL=1
160 | }
161 |
162 |
163 | if [[ "$CONFIGURATION" == "Debug" ]]; then
164 | install_framework "${BUILT_PRODUCTS_DIR}/SwiftTickerView-tvOS/SwiftTickerView.framework"
165 | fi
166 | if [[ "$CONFIGURATION" == "Release" ]]; then
167 | install_framework "${BUILT_PRODUCTS_DIR}/SwiftTickerView-tvOS/SwiftTickerView.framework"
168 | fi
169 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
170 | wait
171 | fi
172 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletv/Pods-appletv-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_appletvVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_appletvVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletv/Pods-appletv.debug.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-tvOS"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-tvOS/SwiftTickerView.framework/Headers"
5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftTickerView"
7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletv/Pods-appletv.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_appletv {
2 | umbrella header "Pods-appletv-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletv/Pods-appletv.release.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-tvOS"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-tvOS/SwiftTickerView.framework/Headers"
5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftTickerView"
7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletvTests/Pods-appletvTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletvTests/Pods-appletvTests-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 | Generated by CocoaPods - https://cocoapods.org
4 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletvTests/Pods-appletvTests-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | Generated by CocoaPods - https://cocoapods.org
18 | Title
19 |
20 | Type
21 | PSGroupSpecifier
22 |
23 |
24 | StringsTable
25 | Acknowledgements
26 | Title
27 | Acknowledgements
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletvTests/Pods-appletvTests-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_appletvTests : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_appletvTests
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletvTests/Pods-appletvTests-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_appletvTestsVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_appletvTestsVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletvTests/Pods-appletvTests.debug.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-tvOS"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-tvOS/SwiftTickerView.framework/Headers"
4 | OTHER_LDFLAGS = $(inherited) -framework "SwiftTickerView"
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
8 | PODS_ROOT = ${SRCROOT}/Pods
9 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletvTests/Pods-appletvTests.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_appletvTests {
2 | umbrella header "Pods-appletvTests-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-appletvTests/Pods-appletvTests.release.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-tvOS"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-tvOS/SwiftTickerView.framework/Headers"
4 | OTHER_LDFLAGS = $(inherited) -framework "SwiftTickerView"
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
8 | PODS_ROOT = ${SRCROOT}/Pods
9 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-iOS/SwiftTickerView-iOS-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.5.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-iOS/SwiftTickerView-iOS-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_SwiftTickerView_iOS : NSObject
3 | @end
4 | @implementation PodsDummy_SwiftTickerView_iOS
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-iOS/SwiftTickerView-iOS-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-iOS/SwiftTickerView-iOS-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double SwiftTickerViewVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char SwiftTickerViewVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-iOS/SwiftTickerView-iOS.modulemap:
--------------------------------------------------------------------------------
1 | framework module SwiftTickerView {
2 | umbrella header "SwiftTickerView-iOS-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-iOS/SwiftTickerView-iOS.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-iOS
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
4 | PODS_BUILD_DIR = ${BUILD_DIR}
5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
6 | PODS_ROOT = ${SRCROOT}
7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-tvOS/SwiftTickerView-tvOS-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.5.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-tvOS/SwiftTickerView-tvOS-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_SwiftTickerView_tvOS : NSObject
3 | @end
4 | @implementation PodsDummy_SwiftTickerView_tvOS
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-tvOS/SwiftTickerView-tvOS-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-tvOS/SwiftTickerView-tvOS-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double SwiftTickerViewVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char SwiftTickerViewVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-tvOS/SwiftTickerView-tvOS.modulemap:
--------------------------------------------------------------------------------
1 | framework module SwiftTickerView {
2 | umbrella header "SwiftTickerView-tvOS-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/SwiftTickerView-tvOS/SwiftTickerView-tvOS.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftTickerView-tvOS
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
4 | PODS_BUILD_DIR = ${BUILD_DIR}
5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
6 | PODS_ROOT = ${SRCROOT}
7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView.xcodeproj/xcshareddata/xcschemes/SwiftTickerView-Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
67 |
68 |
78 |
80 |
86 |
87 |
88 |
89 |
90 |
91 |
97 |
99 |
105 |
106 |
107 |
108 |
110 |
111 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView.xcodeproj/xcuserdata/stewart.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | AppleTv.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 7
11 |
12 | SwiftTickerView-Example.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 0
16 |
17 | appletv.xcscheme_^#shared#^_
18 |
19 | orderHint
20 | 8
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView.xcworkspace/xcuserdata/stewart.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EMart86/SwiftTickerView/3229ba4e4c8283a7fd1601064d2f857f03544179/Example/SwiftTickerView.xcworkspace/xcuserdata/stewart.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Example/SwiftTickerView/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SwiftTickerView
4 | //
5 | // Created by eberl_ma@gmx.at on 08/15/2017.
6 | // Copyright (c) 2017 eberl_ma@gmx.at. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | private func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // 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.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // 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.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // 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.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
46 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView/Images.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" : "ios-marketing",
45 | "size" : "1024x1024",
46 | "scale" : "1x"
47 | }
48 | ],
49 | "info" : {
50 | "version" : 1,
51 | "author" : "xcode"
52 | }
53 | }
--------------------------------------------------------------------------------
/Example/SwiftTickerView/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView/NodeView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView/TickerProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TickerProvider.swift
3 | // SwiftTickerView
4 | //
5 | // Created by Martin Eberl on 15.08.17.
6 | // Copyright © 2017 CocoaPods. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import SwiftTickerView
11 |
12 | final class TickerProvider: SwiftTickerProviderProtocol {
13 | private let superContent = [["A", "B", "C"],
14 | ["D", "E", "F"],
15 | ["G", "H", "I"],
16 | ["J", "K", "L"],
17 | ["M", "N", "O"],
18 | ["P", "Q", "R"],
19 | ["S", "T", "U"],
20 | ["V", "W", "X"],
21 | ["Y", "Z"]]
22 | private var content: [String]
23 | private var contentIndex = 0
24 | private var index = 0
25 |
26 | init() {
27 | content = superContent[contentIndex]
28 | }
29 |
30 | var hasContent = true
31 | var nextObject: Any {
32 | if index >= content.count {
33 | index = 0
34 | }
35 | let next = content[index]
36 | index += 1
37 | return next
38 | }
39 |
40 | func updateContent() {
41 | if !superContent.indices.contains(contentIndex) {
42 | index = 0
43 | contentIndex = 0
44 | }
45 | let next = superContent[contentIndex]
46 | contentIndex += 1
47 | index = 0
48 | content = next
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Example/SwiftTickerView/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SwiftTickerView
4 | //
5 | // Created by eberl_ma@gmx.at on 08/15/2017.
6 | // Copyright (c) 2017 eberl_ma@gmx.at. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftTickerView
11 |
12 | class ViewController: UIViewController {
13 | fileprivate let labelIdentifier = "TextMessage"
14 | private let tickerContentProvider = TickerProvider()
15 | @IBOutlet weak var tickerView: SwiftTickerView!
16 |
17 | @IBOutlet weak var slider: UISlider!
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 | // Do any additional setup after loading the view, typically from a nib.
22 |
23 | // setupTickerView(tickerView, dataSet: ["A", "B", "C"])
24 |
25 | tickerView.contentProvider = tickerContentProvider
26 | tickerView.viewProvider = self
27 | tickerView.separator = "+++"
28 | tickerView.render = Renderer.leftToRight
29 | tickerView.render = Renderer.bottomToTopStopAtCenter(holdForSeconds: -1)
30 | // tickerView.render = Renderer(initials: [SwiftTickerItemDecorators.prepareAtLeftInnerBorder(),
31 | // SwiftTickerItemDecorators.alignItemsAboveEachOther(),
32 | // SwiftTickerItemDecorators.centerVertical()],
33 | // updates: [SwiftTickerItemDecorators.updateY(+)],
34 | // shouldAddNewNode: { current, _, offset in
35 | // current.frame.minY > offset
36 | // }, shouldRemoveNode: { current, tickerView in
37 | // current.frame.minY > tickerView.frame.maxY
38 | // })
39 | // tickerView.render = Renderer.bottomToTop.customize(with: SwiftTickerItemDecorators.prepareAtLeftInnerBorder())*/
40 | // tickerView.add(decorator: .ignoreFirstSeparator)
41 | tickerView.registerNodeView(UILabel.self, for: labelIdentifier)
42 | tickerView.tickerDelegate = self
43 | tickerView.reloadData()
44 | }
45 |
46 | override func viewWillAppear(_ animated: Bool) {
47 | super.viewWillAppear(animated)
48 | tickerView.start()
49 | }
50 |
51 | override func viewWillDisappear(_ animated: Bool) {
52 | super.viewWillDisappear(animated)
53 | tickerView.stop()
54 | }
55 |
56 | @IBAction func onValueChange(_ sender: Any) {
57 | tickerView.pixelPerSecond = CGFloat(slider.value)
58 | }
59 |
60 | @IBAction func onButtonClicked() {
61 | tickerContentProvider.updateContent()
62 | }
63 |
64 | @IBAction func updateContentAndReload(_ sender: Any) {
65 | tickerContentProvider.updateContent()
66 | tickerView.reloadData()
67 | }
68 |
69 | func setupTickerView(_ tickerView: SwiftTickerView, dataSet: [String]) {
70 | tickerView.contentProvider = tickerContentProvider
71 | tickerView.viewProvider = self
72 | tickerView.separator = "..."
73 | tickerView.add(decorator: .ignoreFirstSeparator)
74 | tickerView.distanceBetweenNodes = 10
75 | tickerView.render = Renderer.rightToLeft
76 | tickerView.registerNodeView(UILabel.self, for: labelIdentifier)
77 | tickerView.tickerDelegate = self
78 | }
79 |
80 | }
81 |
82 | extension ViewController: SwiftTickerDelegate {
83 | func tickerView(willResume ticker: SwiftTickerView) {}
84 | func tickerView(willStart ticker: SwiftTickerView) {}
85 | func tickerView(willStop ticker: SwiftTickerView) {}
86 | func tickerView(didPress view: UIView, content: Any?) {}
87 | }
88 |
89 | extension ViewController: SwiftTickerViewProvider {
90 | func tickerView(_ tickerView: SwiftTickerView, prepareSeparator separator: UIView) {
91 | if let separator = separator as? UILabel {
92 | separator.textColor = .white
93 | }
94 | }
95 |
96 | func tickerView(_ tickerView: SwiftTickerView, viewFor: Any) -> (UIView, reuseIdentifier: String?) {
97 | if let text = viewFor as? String,
98 | let label = tickerView.dequeReusableNodeView(for: labelIdentifier) as? UILabel {
99 | label.text = text
100 | label.sizeToFit()
101 | label.textColor = .white
102 | return (label, reuseIdentifier: labelIdentifier)
103 | }
104 | return (UIView(), reuseIdentifier: nil)
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/Example/Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Example/Tests/Tests.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import XCTest
3 | import SwiftTickerView
4 |
5 | class Tests: XCTestCase {
6 |
7 | override func setUp() {
8 | super.setUp()
9 | // Put setup code here. This method is called before the invocation of each test method in the class.
10 | }
11 |
12 | override func tearDown() {
13 | // Put teardown code here. This method is called after the invocation of each test method in the class.
14 | super.tearDown()
15 | }
16 |
17 | func testExample() {
18 | // This is an example of a functional test case.
19 | XCTAssert(true, "Pass")
20 | }
21 |
22 | func testPerformanceExample() {
23 | // This is an example of a performance test case.
24 | self.measure() {
25 | // Put the code you want to measure the time of here.
26 | }
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/Example/appletvTests/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 |
--------------------------------------------------------------------------------
/Example/appletvTests/appletvTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // appletvTests.swift
3 | // appletvTests
4 | //
5 | // Created by Martin Eberl on 22.01.18.
6 | // Copyright © 2018 CocoaPods. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import appletv
11 |
12 | class appletvTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measure {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Example/appletvUITests/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 |
--------------------------------------------------------------------------------
/Example/appletvUITests/appletvUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // appletvUITests.swift
3 | // appletvUITests
4 | //
5 | // Created by Martin Eberl on 22.01.18.
6 | // Copyright © 2018 CocoaPods. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class appletvUITests: XCTestCase {
12 |
13 | override func setUp() {
14 | super.setUp()
15 |
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 |
18 | // In UI tests it is usually best to stop immediately when a failure occurs.
19 | continueAfterFailure = false
20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
21 | XCUIApplication().launch()
22 |
23 | // 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.
24 | }
25 |
26 | override func tearDown() {
27 | // Put teardown code here. This method is called after the invocation of each test method in the class.
28 | super.tearDown()
29 | }
30 |
31 | func testExample() {
32 | // Use recording to get started writing UI tests.
33 | // Use XCTAssert and related functions to verify your tests produce the correct results.
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2019 Martin Eberl
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.1
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "SwiftTickerView",
8 | products: [
9 | .library(name: "SwiftTickerView", targets: ["SwiftTickerView"]),
10 | ],
11 | dependencies: [
12 | ],
13 | targets: [
14 | .target(name: "SwiftTickerView", dependencies: [])
15 | ]
16 | )
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SwiftTickerView
2 |
3 | [](https://travis-ci.org/EMart86/SwiftTickerView)
4 | [](http://cocoapods.org/pods/SwiftTickerView)
5 | [](http://cocoapods.org/pods/SwiftTickerView)
6 | [](http://cocoapods.org/pods/SwiftTickerView)
7 |
8 | 
9 | I'll definately have to update this gif, it doesn't look that crappy anymore!
10 |
11 | ## 1.5.0
12 |
13 | ### Following new Render decorators are vailable:
14 | * ```initialRenderer(closure: (UIView, UIView?, SwiftTickerView, CGFloat) -> Void)```
15 | positon your node view wherever you want them to be placed
16 | * ```updateRenderer(closure: (UIView, CGFloat) -> Void)```
17 | use this to customize your rendering option for e.g. to fade in the items or fade out
18 | * ```bottomToTopStopAtCenter(holdForSeconds seconds: TimeInterval)```
19 | this can be used to create the mostly in TV used Ticker where the Ticker node appears at the bottom, when reaching center stayes there for some time and continues to the top
20 |
21 | ## 1.4.3
22 |
23 | - Add support for iOS 9
24 |
25 | ## 1.4.2
26 |
27 | ### Fixes
28 | - Fixes ignoreSeparator on startup when calling reloadData #5
29 |
30 | ## 1.4.1
31 |
32 | ### Fixes
33 | - Fix center vertical and horizontal
34 |
35 | ## 1.4.0
36 |
37 | ### Customize the Renderer easily by adding a new decorators:
38 | ```Renderer.topToBottom.customize(with: SwiftTickerItemDecorators.prepareAtBottomInnerBorder(with: 8))```
39 |
40 | ### Following new Render decorators are vailable:
41 | * ```prepareAtTopInnerBorder()```
42 | * ```prepareAtTopOuterBorder()```
43 | * ```prepareAtBottomInnerBorder()```
44 | * ```prepareAtBottomOuterBorder()```
45 | * ```prepareAtLeftInnerBorder()```
46 | * ```prepareAtLeftOuterBorder()```
47 | * ```prepareAtRightInnerBorder()```
48 | * ```prepareAtRightOuterBorder()```
49 |
50 | ### Implement your own inital or update Render decorator by implementing the ```InitialRenderer & SwiftTickerItemDecorator``` or ```UpdateRenderer & SwiftTickerItemDecorator```
51 |
52 | ### Following new Ticker decorator is available:
53 | * ```ignoreFirstSeparator```
54 | Add a decorator to the TickerView by calling ```tickerView.add(.ignoreFirstSeparator)```
55 |
56 | ### Renamings
57 | * ```SwiftTickerView.Renderer.rightToLeft``` renamed to ```Renderer.rightToLeft```
58 | * ```SwiftTickerView.Renderer.leftToRight``` renamed to ```Renderer.leftToRight```
59 | * ```SwiftTickerView.Renderer.topToBottom``` renamed to ```Renderer.topToBottom```
60 | * ```SwiftTickerView.Renderer.bottomToTop``` renamed to ```Renderer.bottomToTop```
61 |
62 | ## 1.3.0
63 |
64 | * You can now implement your own renderer
65 |
66 | ### Renamings
67 | * renamed ```direction``` to ```renderer```
68 | * ```Direction.horizontalRightToLeft``` renamed to ```SwiftTickerView.Renderer.rightToLeft```
69 | * ```Direction.horizontalLeftToRight``` renamed to ```SwiftTickerView.Renderer.leftToRight```
70 | * ```Direction.verticalTopToBottom``` renamed to ```SwiftTickerView.Renderer.topToBottom```
71 | * ```Direction.verticalBottomToTop``` renamed to ```SwiftTickerView.Renderer.bottomToTop```
72 |
73 | ## 1.2.2
74 |
75 | * Now supports TV OS
76 | * Performance improvements
77 |
78 | ## Example
79 |
80 | To run the example project, clone the repo, and run `pod install` from the Example directory first.
81 |
82 | ## Requirements
83 |
84 | SwiftTickerView is available through [CocoaPods](http://cocoapods.org). To install
85 | it, simply add the following line to your Podfile:
86 |
87 | ```ruby
88 | pod 'SwiftTickerView'
89 | ```
90 |
91 | ## Setup
92 |
93 | You can eigther embed the SwiftTickerView within an Storyboard or a Xib View, or instantiate the View just like any other view:
94 |
95 | ```swift
96 | let tickerView = SwiftTickerView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 30))
97 | ```
98 |
99 | Use the separator property to simply create those textual separators or set a separator view class or nib to create those separator views. Also implement the viewProvider protocol to manipulate the separator view and the node view on demand
100 | ```swift
101 | tickerView.separator = "+++"
102 | tickerView.viewProvider = self
103 | ...
104 | ```
105 |
106 | Register also some custom node views to be able to load them more easily
107 | ```swift
108 | tickerView.registerNodeView(UILabel.self, for: labelIdentifier)
109 | ```
110 |
111 | If you want some callbacks on if the user stopped the ticker view (yes, the user can stop the view by tapping on the ticker view), implement the tickerDelegate and don't forget to asign it to the ticker view. You will also be able to determine the content, which the user has selected.
112 | ```swift
113 | tickerView.tickerDelegate = self
114 | ```
115 |
116 | This ticker view is designed to be able to support arabic and hebrew aswell as the other languages. Simply use the direction property, to determine if you want the content to run from left to right, from right to left, from top to bottom or from bottom to top:
117 | ```swift
118 | tickerView.renderer = SwiftTickerView.Renderer.rightToLeft
119 | ```
120 |
121 | You can manage the velocity of the content to run across the display. You can alter this value at runtime aswell to increase or slow down the ticker view:
122 | ```swift
123 | tickerView.pixelPerSecond = 60 //default is 60
124 | ```
125 |
126 | Don't forget to start the tickerview, otherwhise it's not working:
127 | ```swift
128 | tickerView.start()
129 | ```
130 |
131 | And last but not least, implement the contentProvider property to provide your content!
132 |
133 | Btw, in the viewProvider protocol, the view node view creation function has to return a tuple with a view parameter and an optional reuseIdentifier parameter. Use this parameter to store it and reuse it for later usage:
134 | ```swift
135 | func tickerView(_ tickerView: SwiftTickerView, viewFor: Any) -> (UIView, reuseIdentifier: String?) {
136 | if let text = viewFor as? String,
137 | let label = tickerView.dequeReusableNodeView(for: labelIdentifier) as? UILabel {
138 | label.text = text
139 | label.sizeToFit()
140 | label.textColor = .white
141 | return (label, reuseIdentifier: labelIdentifier)
142 | }
143 | return (UIView(), reuseIdentifier: nil)
144 | }
145 |
146 | func tickerView(_ tickerView: SwiftTickerView, prepareSeparator separator: UIView) {
147 | if let separator = separator as? UILabel {
148 | separator.textColor = .white
149 | }
150 | }
151 | ```
152 |
153 | ## Author
154 |
155 | Martin Eberl, eberl_ma@gmx.at
156 |
157 | ## License
158 |
159 | SwiftTickerView is available under the MIT license. See the LICENSE file for more info.
160 |
--------------------------------------------------------------------------------
/Sources/SwiftTickerView/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EMart86/SwiftTickerView/3229ba4e4c8283a7fd1601064d2f857f03544179/Sources/SwiftTickerView/.gitkeep
--------------------------------------------------------------------------------
/Sources/SwiftTickerView/DefaultConditionBehaviour.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Default.swift
3 | // SwiftTickerView-iOS
4 | //
5 | // Created by Martin Eberl on 02.03.19.
6 | //
7 |
8 | import UIKit
9 |
10 | public class DefaultConditionBehaviour: Condition {
11 | weak var nodeView: UIView?
12 | var condition: ((UIView, SwiftTickerView, DefaultConditionBehaviour) -> Bool)
13 |
14 | init(condition: @escaping ((UIView, SwiftTickerView, DefaultConditionBehaviour) -> Bool)) {
15 | self.condition = condition
16 | }
17 |
18 | public func meets(nodeView: UIView, tickerView: SwiftTickerView) -> Bool {
19 | return condition(nodeView, tickerView, self)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Sources/SwiftTickerView/Renderer.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | open class Renderer: SwiftTickerContentRenderer {
4 | public typealias ShouldAddNewNode = ((UIView, SwiftTickerView, CGFloat) -> Bool)
5 | public typealias ShouldRemoveNode = ((UIView, SwiftTickerView) -> Bool)
6 |
7 | /**
8 | Add inital render decorator for customizing the initial position of the node content
9 |
10 | - Parameter initial: Must conform to the InitialRenderer and SwiftTickerItemDecorator protocol
11 | */
12 | open func customize(with initial: SwiftTickerItemDecorator & InitialRenderer) -> Renderer {
13 | initials.append(initial)
14 | return self
15 | }
16 |
17 | /**
18 | Add update render decorator for customizing the updated position of the node content
19 |
20 | - Parameter update: Must conform to the UpdateRenderer and SwiftTickerItemDecorator protocol
21 | */
22 | open func customize(with update: SwiftTickerItemDecorator & UpdateRenderer) -> Renderer {
23 | updates.append(update)
24 | return self
25 | }
26 |
27 | /**
28 | Add condition decorator for customizing the condition to do something at a certain point
29 |
30 | - Parameter condition: A tuple with the first iteme being a closure that indicates the condition and a second item beind a closure that indicates the action
31 | */
32 | open func customize(with condition: (condition: Condition, then: Action)) -> Renderer {
33 | when = when ?? []
34 | when?.append(condition)
35 | return self
36 | }
37 |
38 | /**
39 | Renders the content from right to left and centered vertically in the ticker view, starting at the right border.
40 | */
41 | public static var rightToLeft = Renderer(initials: [SwiftTickerItemDecorators.alignItemsLeftToEachOther(),
42 | SwiftTickerItemDecorators.prepareAtRightOuterBorder(),
43 | SwiftTickerItemDecorators.centerVertical()],
44 | updates: [SwiftTickerItemDecorators.updateX(-)],
45 | shouldAddNewNode: { current, tickerView, offset in
46 | if current.frame.maxX == -CGFloat.infinity {
47 | return false
48 | }
49 | return tickerView.frame.width - current.frame.maxX > offset
50 | }, shouldRemoveNode: { current, _ in
51 | current.frame.maxX < 0
52 | })
53 |
54 | /**
55 | Renders the content from left to right and centered vertically in the ticker view, starting at the left border.
56 | */
57 | public static var leftToRight = Renderer(initials: [SwiftTickerItemDecorators.alignItemsRightToEachOther(),
58 | SwiftTickerItemDecorators.prepareAtLeftOuterBorder(),
59 | SwiftTickerItemDecorators.centerVertical()],
60 | updates: [SwiftTickerItemDecorators.updateX(+)],
61 | shouldAddNewNode: { current, _, offset in
62 | current.frame.minX > offset
63 | }, shouldRemoveNode: { current, tickerView in
64 | current.frame.minX > tickerView.frame.maxX
65 | })
66 |
67 | /**
68 | Renders the content bottom to top and centered horizontally in the ticker view, starting at the bottom border.
69 | */
70 | public static var bottomToTop = Renderer(initials: [SwiftTickerItemDecorators.alignItemsBelowEachOther(),
71 | SwiftTickerItemDecorators.prepareAtBottomOuterBorder(),
72 | SwiftTickerItemDecorators.centerHorizontal()],
73 | updates: [SwiftTickerItemDecorators.updateY(-)],
74 | shouldAddNewNode: { current, tickerView, offset in
75 | tickerView.frame.height - current.frame.maxY > offset
76 | }, shouldRemoveNode: { current, _ in
77 | current.frame.maxY < 0
78 | })
79 |
80 | /**
81 | Renders the content top to bottom and centered horizontally in the ticker view, starting at the top border.
82 | */
83 | public static var topToBottom = Renderer(initials: [SwiftTickerItemDecorators.centerHorizontal(),
84 | SwiftTickerItemDecorators.alignItemsAboveEachOther(),
85 | SwiftTickerItemDecorators.prepareAtTopOuterBorder()],
86 | updates: [SwiftTickerItemDecorators.updateY(+)],
87 | shouldAddNewNode: { current, _, offset in
88 | current.frame.minY > offset
89 | }, shouldRemoveNode: { current, tickerView in
90 | current.frame.minY > tickerView.frame.maxY
91 | })
92 |
93 | private class CustomTimer {
94 | private var block: ((Timer) -> Void)? = nil
95 | private weak var timer: Timer?
96 |
97 | func schedule(with interval: TimeInterval, repeats: Bool, block: @escaping ((Timer) -> Void)) {
98 | if #available(iOS 10.0, tvOS 10.0, *) {
99 | Timer.scheduledTimer(withTimeInterval: interval, repeats: repeats, block: block)
100 | } else {
101 | self.block = block
102 | timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(timerFired(_:)), userInfo: nil, repeats: repeats)
103 | }
104 | }
105 |
106 | @objc private func timerFired(_ sender: Any) {
107 | guard let timer = timer else {
108 | return
109 | }
110 | block?(timer)
111 | }
112 | }
113 |
114 | /**
115 | Renders the content bottom to top with the first item startin out of the bounds and moving each item up.
116 | When the current item reaches the center, it stops for given ammounts of seconds. Thereafter it continues.
117 | This behaviour is ment to be used on modern news tickers
118 |
119 | - Parameter holdForSeconds: use this option to let the user see the ticker node when centered in the view for ammount of seconds. Value has to be positive
120 | */
121 | public static func bottomToTopStopAtCenter(holdForSeconds seconds: TimeInterval) -> Renderer {
122 | return Renderer(initials: [SwiftTickerItemDecorators.prepareAtBottomOuterBorder(force: true),
123 | SwiftTickerItemDecorators.prepareAtLeftInnerBorder()],
124 | updates: [SwiftTickerItemDecorators.updateY(-)],
125 | when: [(
126 | condition: DefaultConditionBehaviour(condition: { node, tickerView, behaviour in
127 | func isInVerticalCenter(node: UIView, tickerView: SwiftTickerView, allowedOffset: CGFloat = 5) -> Bool {
128 | let tickerCenter = tickerView.bounds.midY
129 | let nodeCenter = node.frame.minY + node.frame.height / 2
130 | return abs(tickerCenter - nodeCenter) < 5
131 | }
132 |
133 | guard behaviour.nodeView != node else {
134 | if !isInVerticalCenter(node: node, tickerView: tickerView) {
135 | behaviour.nodeView = nil
136 | }
137 | return false
138 | }
139 | if isInVerticalCenter(node: node, tickerView: tickerView) {
140 | behaviour.nodeView = node
141 | return true
142 | }
143 | behaviour.nodeView = nil
144 | return false
145 | }),
146 | then: { _, tickerView in
147 | tickerView.stop()
148 | CustomTimer().schedule(with: max(0, seconds), repeats: false, block: { _ in
149 | tickerView.start()
150 | })
151 | return .return
152 | }
153 | )],
154 | shouldAddNewNode: { current, _, _ in
155 | current.frame.maxY < 0
156 | }, shouldRemoveNode: { current, tickerView in
157 | current.frame.maxY < 0
158 | })
159 | }
160 |
161 | private var initials: [InitialRenderer & SwiftTickerItemDecorator]
162 | private var updates: [UpdateRenderer & SwiftTickerItemDecorator]
163 | private var when: [(condition: Condition, then: Action)]?
164 | private let shouldAddNewNode: ShouldAddNewNode
165 | private let shouldRemoveNode: ShouldRemoveNode
166 | private var last: UIView?
167 |
168 | /**
169 | Renderer constructor
170 |
171 | - Parameter initials: An array of InitialRenderer and SwiftTickerItemDecorator for defining the start position of each ticker node view
172 | - Parameter updates: An array of UpdateRenderer and SwiftTickerItemDecorator for defining the updated position of each ticker node view
173 | - Parameter shouldAddNewNode: Closure if a new node view should be added
174 | - Parameter shouldRemoveNode: Closure if a given new node view should be removed
175 | */
176 | public init(initials: [InitialRenderer & SwiftTickerItemDecorator],
177 | updates: [UpdateRenderer & SwiftTickerItemDecorator],
178 | when: [(condition: Condition, then: Action)]? = nil,
179 | shouldAddNewNode: @escaping ShouldAddNewNode,
180 | shouldRemoveNode: @escaping ShouldRemoveNode) {
181 | self.initials = initials
182 | self.updates = updates
183 | self.when = when
184 | self.shouldAddNewNode = shouldAddNewNode
185 | self.shouldRemoveNode = shouldRemoveNode
186 | }
187 |
188 | open func tickerViewUpdate(_ tickerView: SwiftTickerView, render nodeView: UIView, offset: CGFloat) {
189 | updates.forEach { $0.updateWith(current: nodeView, offset: offset) }
190 | guard let when = when else {
191 | return
192 | }
193 | for whenCondition in when {
194 | if whenCondition.condition.meets(nodeView: nodeView, tickerView: tickerView) {
195 | switch whenCondition.then(self, tickerView) {
196 | case .return:
197 | return
198 | case .break:
199 | break
200 | case .continue:
201 | continue
202 | }
203 | }
204 | }
205 | }
206 |
207 | open func tickerViewShouldAddNext(_ tickerView: SwiftTickerView, current nodeView: UIView) -> Bool {
208 | return shouldAddNewNode(nodeView, tickerView, tickerView.distanceBetweenNodes)
209 | }
210 |
211 | open func tickerViewShouldRemove(_ tickerView: SwiftTickerView, nodeView: UIView) -> Bool {
212 | return shouldRemoveNode(nodeView, tickerView)
213 | }
214 |
215 | open func tickerView(_ tickerView: SwiftTickerView, render nodeView: UIView, with identifier: String) {
216 | initials.forEach {
217 | $0.updateWith(current: nodeView,
218 | last: last?.superview != nil ? last : nil,
219 | tickerView: tickerView,
220 | offset: tickerView.distanceBetweenNodes) }
221 | last = nodeView
222 | }
223 | }
224 |
--------------------------------------------------------------------------------
/Sources/SwiftTickerView/SwiftTickerItemDecorator.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | public struct SwiftTickerItemDecorators {
4 | // MARK: - Initial Renderer
5 |
6 | /**
7 | InitialRendererClosure
8 |
9 | Used in the initialRendere(closure:) method
10 |
11 | - Parameter node: the newly added view
12 | - Parameter last: the previously added view. This is optional, because when there hasn't been any nodes added, this parameter is nil. You can use this parameter, to align your new node alongside this node
13 | - Parameter tickerView: the SwiftTicker view
14 | - Parameter offset: the default offset between nodes
15 | */
16 | public typealias InitialRendererClosure = ((UIView, UIView?, SwiftTickerView, CGFloat) -> Void)
17 |
18 | /**
19 | InitialRenderer
20 |
21 | Use this option, if you want the Ticker Nodes to be completely customizable initialized
22 |
23 | - Parameter closure: InitialRendererClosure
24 | */
25 | public static func initialRenderer(closure: @escaping InitialRendererClosure) -> SwiftTickerItemDecorator & InitialRenderer {
26 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
27 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
28 | closure(current, last, tickerView, offset)
29 | }
30 |
31 | init(closure: @escaping InitialRendererClosure) {
32 | self.closure = closure
33 | }
34 |
35 | let closure: InitialRendererClosure
36 |
37 | }
38 | return Anonymous(closure: closure)
39 | }
40 |
41 | /**
42 | InitialRenderer
43 |
44 | Aligns the items left to each other
45 |
46 | This is used in the rightToLeft Rendering option
47 |
48 | - Parameter customOffset: A custom offset to each item
49 | */
50 | public static func alignItemsLeftToEachOther(with customOffset: CGFloat? = nil) -> SwiftTickerItemDecorator & InitialRenderer {
51 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
52 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
53 | guard let last = last else {
54 | return
55 | }
56 | var frame = current.frame
57 | frame.origin.x = last.frame.maxX + (customOffset ?? offset)
58 | current.frame = frame
59 | }
60 |
61 | init(customOffset: CGFloat? = nil) {
62 | self.customOffset = customOffset
63 | }
64 |
65 | let customOffset: CGFloat?
66 |
67 | }
68 | return Anonymous(customOffset: customOffset)
69 | }
70 |
71 | /**
72 | InitialRenderer
73 |
74 | Aligns the items right to each other
75 |
76 | This is used in the leftToRight Rendering option
77 |
78 | - Parameter customOffset: A custom offset to each item
79 | */
80 |
81 | public static func alignItemsRightToEachOther(with customOffset: CGFloat? = nil) -> SwiftTickerItemDecorator & InitialRenderer {
82 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
83 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
84 | guard let last = last else {
85 | return
86 | }
87 | var frame = current.frame
88 | frame.origin.x = last.frame.minX - (customOffset ?? offset) - frame.width
89 | current.frame = frame
90 | }
91 |
92 | init(customOffset: CGFloat? = nil) {
93 | self.customOffset = customOffset
94 | }
95 |
96 | let customOffset: CGFloat?
97 |
98 | }
99 | return Anonymous(customOffset: customOffset)
100 | }
101 |
102 | /**
103 | InitialRenderer
104 |
105 | Aligns the items below each other
106 |
107 | This is used in the bottomToTop Rendering option
108 |
109 | - Parameter customOffset: A custom offset to each item
110 | */
111 |
112 | public static func alignItemsBelowEachOther(with customOffset: CGFloat? = nil) -> SwiftTickerItemDecorator & InitialRenderer {
113 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
114 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
115 | guard let last = last else {
116 | return
117 | }
118 | var frame = current.frame
119 | frame.origin.y = last.frame.maxY + (customOffset ?? offset)
120 | current.frame = frame
121 | }
122 |
123 | init(customOffset: CGFloat? = nil) {
124 | self.customOffset = customOffset
125 | }
126 |
127 | let customOffset: CGFloat?
128 |
129 | }
130 | return Anonymous(customOffset: customOffset)
131 | }
132 |
133 | /**
134 | InitialRenderer
135 |
136 | Aligns the items above each other
137 |
138 | This is used in the topToBottom Rendering option
139 |
140 | - Parameter customOffset: A custom offset to each item
141 | */
142 |
143 | public static func alignItemsAboveEachOther(with customOffset: CGFloat? = nil) -> SwiftTickerItemDecorator & InitialRenderer {
144 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
145 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
146 | guard let last = last else {
147 | return
148 | }
149 | var frame = current.frame
150 | frame.origin.y = last.frame.minY - (customOffset ?? offset) - frame.height
151 | current.frame = frame
152 | }
153 |
154 | init(customOffset: CGFloat? = nil) {
155 | self.customOffset = customOffset
156 | }
157 |
158 | let customOffset: CGFloat?
159 |
160 | }
161 | return Anonymous(customOffset: customOffset)
162 | }
163 |
164 | /**
165 | InitialRenderer
166 |
167 | Aligns the first item at the right border so that it is not visible in the beginning
168 |
169 | This is used in the rightToLeft Rendering option
170 |
171 | - Parameter customOffset: A custom offset to the border
172 | - Parameter force: This forces this Initial Renderer to be executed
173 | */
174 | public static func prepareAtRightOuterBorder(with customOffset: CGFloat? = nil, force: Bool = false) -> SwiftTickerItemDecorator & InitialRenderer {
175 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
176 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
177 | if last == nil || force {
178 | var frame = current.frame
179 | frame.origin.x = tickerView.frame.maxX + (customOffset ?? 0)
180 | current.frame = frame
181 | }
182 | }
183 |
184 | init(customOffset: CGFloat? = nil, force: Bool = false) {
185 | self.customOffset = customOffset
186 | self.force = force
187 | }
188 |
189 | let customOffset: CGFloat?
190 | private let force: Bool
191 | }
192 | return Anonymous(customOffset: customOffset, force: force)
193 | }
194 |
195 | /**
196 | InitialRenderer
197 |
198 | Aligns the first item at the right border so that it is visible in the beginning
199 |
200 | - Parameter customOffset: A custom offset to the border
201 | - Parameter force: This forces this Initial Renderer to be executed
202 | */
203 | public static func prepareAtRightInnerBorder(with customOffset: CGFloat? = nil, force: Bool = false) -> SwiftTickerItemDecorator & InitialRenderer {
204 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
205 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
206 | if last == nil || force {
207 | var frame = current.frame
208 | frame.origin.x = tickerView.frame.maxX - frame.width - (customOffset ?? 0)
209 | current.frame = frame
210 | }
211 | }
212 |
213 | init(customOffset: CGFloat? = nil, force: Bool = false) {
214 | self.customOffset = customOffset
215 | self.force = force
216 | }
217 |
218 | let customOffset: CGFloat?
219 | private let force: Bool
220 | }
221 | return Anonymous(customOffset: customOffset, force: force)
222 | }
223 |
224 | /**
225 | InitialRenderer
226 |
227 | Aligns the first item at the left border so that it is not visible in the beginning
228 |
229 | This is used in the leftToRight Rendering option
230 |
231 | - Parameter customOffset: A custom offset to the border
232 | - Parameter force: This forces this Initial Renderer to be executed
233 | */
234 | public static func prepareAtLeftOuterBorder(with customOffset: CGFloat? = nil, force: Bool = false) -> SwiftTickerItemDecorator & InitialRenderer {
235 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
236 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
237 | if last == nil || force {
238 | var frame = current.frame
239 | frame.origin.x = -frame.width - (customOffset ?? 0)
240 | current.frame = frame
241 | }
242 | }
243 |
244 | init(customOffset: CGFloat? = nil, force: Bool = false) {
245 | self.customOffset = customOffset
246 | self.force = force
247 | }
248 |
249 | let customOffset: CGFloat?
250 | private let force: Bool
251 | }
252 | return Anonymous(customOffset: customOffset, force: force)
253 | }
254 |
255 | /**
256 | InitialRenderer
257 |
258 | Aligns the first item at the left border so that it is visible in the beginning
259 |
260 | - Parameter customOffset: A custom offset to the border
261 | - Parameter force: This forces this Initial Renderer to be executed
262 | */
263 | public static func prepareAtLeftInnerBorder(with customOffset: CGFloat? = nil, force: Bool = false) -> SwiftTickerItemDecorator & InitialRenderer {
264 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
265 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
266 | if last == nil || force {
267 | var frame = current.frame
268 | frame.origin.x = customOffset ?? offset
269 | current.frame = frame
270 | }
271 | }
272 |
273 | init(customOffset: CGFloat? = nil, force: Bool = false) {
274 | self.customOffset = customOffset
275 | self.force = force
276 | }
277 |
278 | let customOffset: CGFloat?
279 | private let force: Bool
280 | }
281 | return Anonymous(customOffset: customOffset, force: force)
282 | }
283 |
284 | /**
285 | InitialRenderer
286 |
287 | Aligns the first item at the bottom border so that it is not visible in the beginning
288 |
289 | This is used in the bottomToTop Rendering option
290 |
291 | - Parameter customOffset: A custom offset to the border
292 | - Parameter force: This forces this Initial Renderer to be executed
293 | */
294 | public static func prepareAtBottomOuterBorder(with customOffset: CGFloat? = nil, force: Bool = false) -> SwiftTickerItemDecorator & InitialRenderer {
295 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
296 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
297 | if last == nil || force {
298 | var frame = current.frame
299 | frame.origin.y = tickerView.bounds.maxY + (customOffset ?? 0)
300 | current.frame = frame
301 | }
302 | }
303 |
304 | init(customOffset: CGFloat? = nil, force: Bool = false) {
305 | self.customOffset = customOffset
306 | self.force = force
307 | }
308 |
309 | let customOffset: CGFloat?
310 | private let force: Bool
311 | }
312 | return Anonymous(customOffset: customOffset, force: force)
313 | }
314 |
315 | /**
316 | InitialRenderer
317 |
318 | Aligns the first item at the left border so that it is visible in the beginning
319 |
320 | - Parameter customOffset: A custom offset to the border
321 | - Parameter force: This forces this Initial Renderer to be executed
322 | */
323 | public static func prepareAtBottomInnerBorder(with customOffset: CGFloat? = nil, force: Bool = false) -> SwiftTickerItemDecorator & InitialRenderer {
324 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
325 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
326 | if last == nil || force {
327 | var frame = current.frame
328 | frame.origin.y = tickerView.frame.height - frame.height - (customOffset ?? 0)
329 | current.frame = frame
330 | }
331 | }
332 |
333 | init(customOffset: CGFloat? = nil, force: Bool = false) {
334 | self.customOffset = customOffset
335 | self.force = force
336 | }
337 |
338 | let customOffset: CGFloat?
339 | private let force: Bool
340 | }
341 | return Anonymous(customOffset: customOffset, force: force)
342 | }
343 |
344 | /**
345 | InitialRenderer
346 |
347 | Aligns the first item at the top border so that it is not visible in the beginning
348 |
349 | This is used in the topToBottom Rendering option
350 |
351 | - Parameter customOffset: A custom offset to the border
352 | - Parameter force: This forces this Initial Renderer to be executed
353 | */
354 | public static func prepareAtTopOuterBorder(with customOffset: CGFloat? = nil, force: Bool = false) -> SwiftTickerItemDecorator & InitialRenderer {
355 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
356 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
357 | if last == nil || force {
358 | var frame = current.frame
359 | frame.origin.y = -frame.height + (customOffset ?? 0)
360 | current.frame = frame
361 | }
362 | }
363 |
364 | init(customOffset: CGFloat? = nil, force: Bool = false) {
365 | self.customOffset = customOffset
366 | self.force = force
367 | }
368 |
369 | let customOffset: CGFloat?
370 | private let force: Bool
371 | }
372 | return Anonymous(customOffset: customOffset, force: force)
373 | }
374 |
375 | /**
376 | InitialRenderer
377 |
378 | Aligns the first item at top border so that it is visible in the beginning
379 |
380 | - Parameter customOffset: A custom offset to the border
381 | - Parameter force: This forces this Initial Renderer to be executed
382 | */
383 | public static func prepareAtTopInnerBorder(with customOffset: CGFloat? = nil, force: Bool = false) -> SwiftTickerItemDecorator & InitialRenderer {
384 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
385 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
386 | if last == nil || force {
387 | var frame = current.frame
388 | frame.origin.y = customOffset ?? 0
389 | current.frame = frame
390 | }
391 | }
392 |
393 | init(customOffset: CGFloat? = nil, force: Bool = false) {
394 | self.customOffset = customOffset
395 | self.force = force
396 | }
397 |
398 | let customOffset: CGFloat?
399 | private let force: Bool
400 | }
401 | return Anonymous(customOffset: customOffset, force: force)
402 | }
403 |
404 | /**
405 | InitialRenderer
406 |
407 | Aligns the items vertically centered in the view
408 |
409 | This is used in the leftToRight and rightToLeft Rendering option
410 |
411 | - Parameter customOffset: A custom offset from the vertical center
412 | */
413 | public static func centerVertical(with offset: CGFloat? = nil) -> SwiftTickerItemDecorator & InitialRenderer {
414 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
415 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
416 | var frame = current.frame
417 | frame.origin.y = ((tickerView.frame.height - frame.height) / 2) + (customOffset ?? 0)
418 | current.frame = frame
419 | }
420 |
421 | init(customOffset: CGFloat? = nil) {
422 | self.customOffset = customOffset
423 | }
424 |
425 | let customOffset: CGFloat?
426 | }
427 | return Anonymous(customOffset: offset)
428 | }
429 |
430 | /**
431 | InitialRenderer
432 |
433 | Aligns the items horizontally centered in the view
434 |
435 | This is used in the topToBottom and bottomToTop Rendering option
436 |
437 | - Parameter customOffset: A custom offset from the horizontal center
438 | */
439 | public static func centerHorizontal(with offset: CGFloat? = nil) -> SwiftTickerItemDecorator & InitialRenderer {
440 | struct Anonymous: SwiftTickerItemDecorator, InitialRenderer {
441 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat) {
442 | var frame = current.frame
443 | frame.origin.x = ((tickerView.frame.width - frame.width) / 2) + (customOffset ?? 0)
444 | current.frame = frame
445 | }
446 |
447 | init(customOffset: CGFloat? = nil) {
448 | self.customOffset = customOffset
449 | }
450 |
451 | let customOffset: CGFloat?
452 | }
453 | return Anonymous(customOffset: offset)
454 | }
455 |
456 | // /**
457 | // UpdateRenderer
458 | //
459 | // Updates the x position of the view
460 | //
461 | // This is used in the leftToRight and rightToLeft Rendering option
462 | //
463 | // - Parameter function: Use an oparator eg (+, -, *, /,...)
464 | // */
465 | // public static func accellerateX(_ function: @escaping (CGFloat, CGFloat, to finalSpeed: ) -> CGFloat) -> SwiftTickerItemDecorator & UpdateRenderer {
466 | // struct Anonymous: SwiftTickerItemDecorator, UpdateRenderer {
467 | // func updateWith(current: UIView, offset: CGFloat) {
468 | // var frame = current.frame
469 | // frame.origin.x = function(frame.origin.x, offset)
470 | // current.frame = frame
471 | // }
472 | //
473 | // init(_ function: @escaping (CGFloat, CGFloat) -> CGFloat) {
474 | // self.function = function
475 | // }
476 | //
477 | // let function: (CGFloat, CGFloat) -> CGFloat
478 | // }
479 | // return Anonymous(function)
480 | // }
481 |
482 | // MARK: - Update Renderer
483 |
484 | /**
485 | UpdateRendererClosure
486 |
487 | Used in the initialRendere(closure:) method
488 |
489 | - Parameter node: the node view, that shall be updated
490 | - Parameter offset: the calculated offset, you can use this to calculate the next position or implement your own update position logic
491 | */
492 | public typealias UpdateRendererClosure = ((UIView, CGFloat) -> Void)
493 |
494 | /**
495 | UpdateRenderer
496 |
497 | Use this option, if you want the Ticker Nodes to be completely customizable updated
498 |
499 | - Parameter closure: InitialRendererClosure
500 | */
501 | public static func updateRenderer(closure: @escaping UpdateRendererClosure) -> SwiftTickerItemDecorator & UpdateRenderer {
502 | struct Anonymous: SwiftTickerItemDecorator, UpdateRenderer {
503 | func updateWith(current: UIView, offset: CGFloat) {
504 | closure(current, offset)
505 | }
506 |
507 | init(closure: @escaping UpdateRendererClosure) {
508 | self.closure = closure
509 | }
510 |
511 | let closure: UpdateRendererClosure
512 | }
513 | return Anonymous(closure: closure)
514 | }
515 |
516 | /**
517 | UpdateRenderer
518 |
519 | Updates the x position of the view
520 |
521 | This is used in the leftToRight and rightToLeft Rendering option
522 |
523 | - Parameter function: Use an oparator eg (+, -, *, /,...)
524 | */
525 | public static func updateX(_ function: @escaping (CGFloat, CGFloat) -> CGFloat) -> SwiftTickerItemDecorator & UpdateRenderer {
526 | struct Anonymous: SwiftTickerItemDecorator, UpdateRenderer {
527 | func updateWith(current: UIView, offset: CGFloat) {
528 | var frame = current.frame
529 | frame.origin.x = function(current.frame.origin.x, offset)
530 | current.frame = frame
531 | }
532 |
533 | init(_ function: @escaping (CGFloat, CGFloat) -> CGFloat) {
534 | self.function = function
535 | }
536 |
537 | let function: (CGFloat, CGFloat) -> CGFloat
538 | }
539 | return Anonymous(function)
540 | }
541 |
542 | /**
543 | UpdateRenderer
544 |
545 | Updates the y position of the view
546 |
547 | This is used in the topToBottom and bottomToTop Rendering option
548 |
549 | - Parameter function: Use an oparator eg (+, -, *, /,...)
550 | */
551 | public static func updateY(_ function: @escaping (CGFloat, CGFloat) -> CGFloat) -> SwiftTickerItemDecorator & UpdateRenderer {
552 | struct Anonymous: SwiftTickerItemDecorator, UpdateRenderer {
553 | func updateWith(current: UIView, offset: CGFloat) {
554 | var frame = current.frame
555 | frame.origin.y = function(current.frame.origin.y, offset)
556 | current.frame = frame
557 | }
558 |
559 | init(_ function: @escaping (CGFloat, CGFloat) -> CGFloat) {
560 | self.function = function
561 | }
562 |
563 | let function: (CGFloat, CGFloat) -> CGFloat
564 | }
565 | return Anonymous(function)
566 | }
567 | }
568 |
--------------------------------------------------------------------------------
/Sources/SwiftTickerView/SwiftTickerView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftTickerView.swift
3 | // Pods
4 | //
5 | // Created by Martin Eberl on 15.08.17.
6 | //
7 | //
8 |
9 | import UIKit
10 |
11 | public protocol SwiftTickerProviderProtocol {
12 | var hasContent: Bool { get }
13 | var nextObject: Any { get }
14 | }
15 |
16 | public protocol SwiftTickerDelegate: class {
17 | func tickerView(willResume ticker: SwiftTickerView)
18 | func tickerView(willStart ticker: SwiftTickerView)
19 | func tickerView(willStop ticker: SwiftTickerView)
20 | func tickerView(didPress view: UIView, content: Any?)
21 | // func tickerViewDidStartDragging(_ ticker: SwiftTickerView)
22 | // func tickerViewDidEndDragging(_ ticker: SwiftTickerView)
23 | }
24 |
25 | public protocol SwiftTickerViewProvider {
26 | func tickerView(_ tickerView: SwiftTickerView, prepareSeparator separator: UIView)
27 | func tickerView(_ tickerView: SwiftTickerView, viewFor: Any) -> (UIView, reuseIdentifier: String?)
28 | }
29 |
30 | public protocol SwiftTickerContentRenderer {
31 | func tickerView(_ tickerView: SwiftTickerView, render nodeView: UIView, with identifier: String)
32 | func tickerViewUpdate(_ tickerView: SwiftTickerView, render nodeView: UIView, offset: CGFloat)
33 | func tickerViewShouldAddNext(_ tickerView: SwiftTickerView, current nodeView: UIView) -> Bool
34 | func tickerViewShouldRemove(_ tickerView: SwiftTickerView, nodeView: UIView) -> Bool
35 | }
36 |
37 | public protocol InitialRenderer {
38 | func updateWith(current: UIView, last: UIView?, tickerView: SwiftTickerView, offset: CGFloat)
39 | }
40 |
41 | public protocol UpdateRenderer {
42 | func updateWith(current: UIView, offset: CGFloat)
43 | }
44 |
45 | public protocol Condition {
46 | func meets(nodeView: UIView, tickerView: SwiftTickerView) -> Bool
47 | }
48 |
49 | public enum ReturnBehavior {
50 | case `continue`
51 | case `return`
52 | case `break`
53 | }
54 |
55 | public typealias Action = (Renderer, SwiftTickerView) -> ReturnBehavior
56 |
57 | public protocol SwiftTickerItemDecorator { }
58 |
59 | open class SwiftTickerView: UIView {
60 | private let separatorIdentifier = "SeparatorIdentifier"
61 | private let dontReuseIdentifier = "DontReuseIdentifier"
62 |
63 | public enum Decorator: SwiftTickerItemDecorator {
64 | case ignoreFirstSeparator
65 | case draggingEnabled
66 | }
67 |
68 | private var isDragging = false {
69 | didSet {
70 | guard oldValue != isDragging else {
71 | return
72 | }
73 | if isDragging {
74 | wasRunningBeforeDragging = isRunning
75 | stop()
76 | // tickerDelegate?.tickerViewDidStartDragging(self)
77 | } else {
78 | if wasRunningBeforeDragging {
79 | resume()
80 | }
81 | // tickerDelegate?.tickerViewDidEndDragging(self)
82 | }
83 | }
84 | }
85 |
86 | private var decorators = [Decorator]()
87 |
88 | /**
89 | Assign a custom renderer to allow the content to be rendered on the ticker view.
90 | Default is rightToLeft
91 | */
92 | public var render: SwiftTickerContentRenderer = Renderer.rightToLeft {
93 | didSet {
94 | guard isRunning else {
95 | return
96 | }
97 | stop()
98 | resume()
99 | }
100 | }
101 |
102 | /**
103 | Set a custom pixelPerSeconds to increase or decrease the update interval of the content.
104 | Default is 60
105 | WARNING: The more you increase this value, the more it looks stuttering
106 | */
107 | public var pixelPerSecond: CGFloat = 60 {
108 | didSet {
109 | guard pixelPerSecond > 0 else {
110 | stop()
111 | return
112 | }
113 | renewDisplayLink()
114 | }
115 | }
116 |
117 | /**
118 | Asign a custom separator
119 | */
120 | public var separator: String?
121 | private var separatorView: UIView.Type?
122 | private var separatorNib: UINib?
123 |
124 | /**
125 | Use this as offset between the items rendered on the ticker view
126 | Default is 8 pixel
127 | */
128 | public var distanceBetweenNodes: CGFloat = 8
129 |
130 | /**
131 | Determine if the tickerview is rendering the content or has been stopped
132 | */
133 | private var wasRunningBeforeDragging = false
134 | public private(set) var isRunning = false
135 |
136 | private var lastNodeWasSeparator = false
137 | private var displayLink: CADisplayLink?
138 | private var nodeViews = [(key: String, view: UIView, content: Any?)]()
139 | private var reusableSeparatorViews = [(key: String, view: UIView)]()
140 | private var reusableNodeViews = [(key: String, view: UIView)]()
141 | private var registeredNodeViews = [String: Any]()
142 |
143 | /**
144 | Asign a custom content provider.
145 | */
146 | public var contentProvider: SwiftTickerProviderProtocol?
147 | /**
148 | Asign a custom view provider
149 | */
150 | public var viewProvider: SwiftTickerViewProvider?
151 | /**
152 | Asign a custom delegate
153 | */
154 | public weak var tickerDelegate: SwiftTickerDelegate?
155 |
156 | @IBOutlet public weak var button: UIButton!
157 |
158 | open override func awakeFromNib() {
159 | super.awakeFromNib()
160 |
161 | setupUI()
162 | }
163 |
164 | required public init?(coder aDecoder: NSCoder) {
165 | super.init(coder: aDecoder)
166 | }
167 |
168 | public override init(frame: CGRect) {
169 | super.init(frame: frame)
170 |
171 | setupUI()
172 | }
173 |
174 | deinit {
175 | displayLink?.invalidate()
176 | }
177 |
178 | /**
179 | Adds a decorator to the tickerview
180 |
181 | - Parameter decorator: a protocol to customize the view behavior
182 | */
183 | open func add(decorator: Decorator) {
184 | guard !decorators.contains(decorator) else {
185 | return
186 | }
187 |
188 | decorators.append(decorator)
189 | apply(decorator: decorator)
190 | }
191 |
192 | /**
193 | Starts the ticker view rendering
194 | */
195 | open func start() {
196 | tickerDelegate?.tickerView(willStart: self)
197 | if isRunning {
198 | renewDisplayLink()
199 | } else {
200 | resume()
201 | }
202 | }
203 |
204 | /**
205 | Stops the ticker from rendering the content
206 | */
207 | open func stop() {
208 | guard isRunning else {
209 | return
210 | }
211 |
212 | tickerDelegate?.tickerView(willStop: self)
213 | isRunning = false
214 | displayLink?.isPaused = true
215 | }
216 |
217 | /**
218 | Sets a custom separator view that will be created during runtime
219 |
220 | - Parameter separator: custom separator view type
221 | */
222 | open func registerView(for separator: UIView.Type) {
223 | separatorView = separator
224 | }
225 |
226 | /**
227 | Sets a separator nip that will be created during runtime
228 |
229 | - Parameter separator: custom separator nib
230 | */
231 | open func registerNib(for separator: UINib) {
232 | separatorNib = separator
233 | }
234 |
235 | /**
236 | Register a nodeview view type for a specific identifier, that can be dequed during runtime
237 |
238 | - Parameter nodeView: custom node view type
239 |
240 | - Parameter identifier: reused identifier
241 | */
242 | open func registerNodeView(_ nodeView: UIView.Type, for identifier: String) {
243 | registeredNodeViews[identifier] = nodeView
244 | }
245 |
246 | /**
247 | Register a nodeview view nib for a specific identifier, that can be dequed during runtime
248 |
249 | - Parameter nodeView: custom node view nib
250 |
251 | - Parameter identifier: reused identifier
252 | */
253 | open func registerNodeViewNib(_ nodeView: UINib, for identifier: String) {
254 | registeredNodeViews[identifier] = nodeView
255 | }
256 |
257 | /**
258 | Returns a dequed separator. If there is nothing to deque and a 'separator' e.g. '+++' is given, a label is being instantiated of if a 'separatorView' type is given, it will be instantiated of if a 'separatorNib' is given, the nib will be instantiated
259 |
260 | - Return: dequed or created separator view
261 | */
262 | open func dequeueReusableSeparator() -> UIView? {
263 | if let index = reusableSeparatorViews.firstIndex(where: { $0.key == separatorIdentifier }) {
264 | let view = reusableSeparatorViews[index].view
265 | reusableSeparatorViews.remove(at: index)
266 | return view
267 | } else if let separator = separator {
268 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
269 | label.text = separator
270 | label.numberOfLines = 1
271 | label.sizeToFit()
272 | return label
273 | } else if let separatorView = separatorView {
274 | return separatorView.init(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
275 | } else if let separatorNib = separatorNib {
276 | return separatorNib.instantiate(withOwner: nil, options: nil).first as? UIView
277 | }
278 | return nil
279 | }
280 |
281 | /**
282 | Returns a dequed node view by the given identifier. If there is nothing to deque and a 'nodeView' type is given, it will be instantiated of if a nib is given, the nib will be instantiated
283 |
284 | - Return: dequed or created separator view
285 | */
286 | open func dequeReusableNodeView(for identifier: String) -> UIView? {
287 | if let index = reusableNodeViews.firstIndex(where: { $0.key == identifier }) {
288 | let view = reusableNodeViews[index].view
289 | reusableNodeViews.remove(at: index)
290 | return view
291 | }
292 |
293 | guard let any = registeredNodeViews[identifier] else {
294 | return nil
295 | }
296 |
297 | if let anyclass = any as? UIView.Type {
298 | return anyclass.init(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
299 | } else if let nib = any as? UINib {
300 | return nib.instantiate(withOwner: nil, options: nil).first as? UIView
301 | }
302 |
303 | return nil
304 | }
305 |
306 | /**
307 | Clears all nodes from the ticker view. If the view is still running, it will instantly start to render the content if provided
308 |
309 | WARNING: use carefully. If the ticker view is still running, this may look edgy
310 | */
311 | open func reloadData() {
312 | nodeViews.forEach {
313 | removeNode($0.view)
314 | }
315 | decorators.forEach { [weak self] decorator in
316 | self?.apply(decorator: decorator)
317 | }
318 | while addNewNodeIfNeeded() {
319 | }
320 | }
321 |
322 | //MARK: - Private
323 |
324 | private func setupUI() {
325 | NotificationCenter.default.addObserver(self,
326 | selector: #selector(application(didBecomeActive:)),
327 | name: UIApplication.didBecomeActiveNotification,
328 | object: nil)
329 |
330 | NotificationCenter.default.addObserver(self,
331 | selector: #selector(application(willResignActive:)),
332 | name: UIApplication.willResignActiveNotification,
333 | object: nil)
334 |
335 | if button == nil {
336 | let button = UIButton(frame: bounds)
337 | addSubview(button)
338 | self.button = button
339 | }
340 |
341 | button.addTarget(self,
342 | action: #selector(button(touchedDown:)),
343 | for: .touchDown)
344 | button.addTarget(self,
345 | action: #selector(button(touchedUpInside:with:)),
346 | for: .touchUpInside)
347 | button.addTarget(self,
348 | action: #selector(button(touchedUpOutside:)),
349 | for: .touchUpOutside)
350 |
351 | let panGestureRecognizer = UIPanGestureRecognizer(target: self,
352 | action: #selector(panDetected(_:)))
353 | button.addGestureRecognizer(panGestureRecognizer)
354 | }
355 |
356 | @objc private func panDetected(_ sender: UIPanGestureRecognizer) {
357 | if !isDragging {
358 | isDragging = true
359 | }
360 | //
361 | // switch sender.state {
362 | // case .changed:
363 | // let velocity = sender.velocity(in: self)
364 | // case .ended:
365 | // }
366 | //
367 |
368 | }
369 |
370 | @objc private func application(willResignActive application: UIApplication) {
371 | stop()
372 | }
373 |
374 | @objc private func application(didBecomeActive application: UIApplication) {
375 | start()
376 | }
377 |
378 | @objc private func button(touchedDown button: UIButton) {
379 | stop()
380 | }
381 |
382 | @objc private func button(touchedUpInside button: UIButton, with event: UIEvent) {
383 | guard let origin = event.allTouches?.first?.location(in: self) else {
384 | return
385 | }
386 | let rect = CGRect(origin: origin, size: CGSize(width: 1, height: 1))
387 | if let view = nodeViews.first(where: {
388 | $0.key != separatorIdentifier && $0.view.frame.intersects(rect)
389 | }) {
390 | tickerDelegate?.tickerView(didPress: view.view, content: view.content)
391 | }
392 | start()
393 | }
394 |
395 | @objc private func button(touchedUpOutside button: UIButton) {
396 | resume()
397 | isDragging = false
398 | }
399 |
400 | private func renewDisplayLink() {
401 | guard pixelPerSecond > 0 else {
402 | return
403 | }
404 | guard displayLink == nil else {
405 | displayLink?.isPaused = false
406 | if #available(iOS 10.0, tvOS 10.0, *) {
407 | displayLink?.preferredFramesPerSecond = Int(pixelPerSecond)
408 | } else {
409 | displayLink?.frameInterval = Int(pixelPerSecond/60)
410 | }
411 | return
412 | }
413 |
414 | displayLink = CADisplayLink(target: self,
415 | selector: #selector(rendering))
416 | if #available(iOS 10.0, tvOS 10.0, *) {
417 | displayLink?.preferredFramesPerSecond = Int(pixelPerSecond)
418 | } else {
419 | displayLink?.frameInterval = Int(pixelPerSecond/60)
420 | }
421 | displayLink?.add(to: .main, forMode: RunLoop.Mode.common)
422 | }
423 |
424 | private func apply(decorator: Decorator) {
425 | switch decorator {
426 | case .ignoreFirstSeparator:
427 | if !isRunning {
428 | lastNodeWasSeparator = true
429 | }
430 | case .draggingEnabled:
431 | break
432 | }
433 | }
434 |
435 | private func resume() {
436 | guard !isRunning,
437 | let contentProvider = contentProvider,
438 | contentProvider.hasContent else { return }
439 |
440 | tickerDelegate?.tickerView(willResume: self)
441 | isRunning = true
442 |
443 | renewDisplayLink()
444 | }
445 |
446 | @objc private func rendering() {
447 | guard isRunning else {
448 | return
449 | }
450 | updateTickerNodeViewPosition()
451 | }
452 |
453 | private func update(node: UIView, offset: CGFloat) {
454 | render.tickerViewUpdate(self, render: node, offset: offset)
455 | }
456 |
457 | private func viewIsOutOfBounds(_ nodeView: UIView?) -> Bool {
458 | guard let nodeView = nodeView else {
459 | return false
460 | }
461 |
462 | return render.tickerViewShouldRemove(self, nodeView: nodeView)
463 | }
464 |
465 | private var shouldAddView: Bool {
466 | guard let nodeView = nodeViews.last else {
467 | return true
468 | }
469 |
470 | return render.tickerViewShouldAddNext(self, current: nodeView.view)
471 | }
472 |
473 | private func removeNodeIfNeeded(_ nodeView: UIView?) {
474 | guard let nodeView = nodeView else { return }
475 |
476 | if viewIsOutOfBounds(nodeView) {
477 | removeNode(nodeView)
478 | }
479 | }
480 |
481 | private func removeNode(_ nodeView: UIView) {
482 | if let index = nodeViews.firstIndex(where: { $0.view === nodeView }) {
483 | let nodeView = nodeViews[index]
484 | if nodeView.key == separatorIdentifier {
485 | reusableSeparatorViews.append((nodeView.key, nodeView.view))
486 | } else if nodeView.key != dontReuseIdentifier {
487 | reusableNodeViews.append((nodeView.key, nodeView.view))
488 | }
489 | nodeViews.remove(at: index)
490 | nodeView.view.removeFromSuperview()
491 | }
492 | }
493 |
494 | @discardableResult private func addNewNodeIfNeeded() -> Bool {
495 | guard shouldAddView else {
496 | return false
497 | }
498 | addNode()
499 | return true
500 | }
501 |
502 | private var hasSepatator: Bool {
503 | return separator != nil || separatorNib != nil || separatorView != nil
504 | }
505 |
506 | private func addNode() {
507 | if hasSepatator && !lastNodeWasSeparator {
508 | lastNodeWasSeparator = true
509 | let separator = dequeueReusableSeparator()
510 | if let separator = separator {
511 | viewProvider?.tickerView(self, prepareSeparator: separator)
512 | addNode(separator,
513 | for: separatorIdentifier,
514 | content: nil)
515 | }
516 | return
517 | }
518 | lastNodeWasSeparator = false
519 |
520 | if let content = contentProvider?.nextObject,
521 | let nodeView = viewProvider?.tickerView(self, viewFor: content) {
522 | addNode(nodeView.0,
523 | for: nodeView.reuseIdentifier ?? dontReuseIdentifier,
524 | content: content)
525 | }
526 | }
527 |
528 | private func addNode(_ nodeView: UIView?, for identifier: String, content: Any?) {
529 | guard let nodeView = nodeView else {
530 | return
531 | }
532 |
533 | addSubview(nodeView)
534 | render.tickerView(self, render: nodeView, with: identifier)
535 | nodeViews.append((identifier, nodeView, content))
536 | }
537 |
538 | private var framesPerSecond: Int {
539 | guard let displayLink = displayLink,
540 | displayLink.duration > 0 else {
541 | return 0
542 | }
543 | return Int(round(1000 / displayLink.duration)/1000)
544 | }
545 |
546 | fileprivate func updateTickerNodeViewPosition() {
547 | let offset = pixelPerSecond / CGFloat(framesPerSecond)
548 | guard offset != CGFloat.infinity, offset != -CGFloat.infinity else {
549 | return
550 | }
551 | nodeViews.forEach { [weak self] in
552 | self?.update(node: $0.view, offset: offset)
553 | }
554 |
555 | removeNodeIfNeeded(nodeViews.first?.view)
556 | addNewNodeIfNeeded()
557 | }
558 | }
559 |
--------------------------------------------------------------------------------
/SwiftTickerView.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod lib lint SwiftTickerView.podspec' to ensure this is a
3 | # valid spec before submitting.
4 | #
5 | # Any lines starting with a # are optional, but their use is encouraged
6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
7 | #
8 |
9 | Pod::Spec.new do |s|
10 | s.name = 'SwiftTickerView'
11 | s.version = '1.5.0'
12 | s.summary = 'A simple news ticker view'
13 | s.swift_version = '4.2'
14 |
15 | s.description = <<-DESC
16 | A swift ticker, written in swift. The one, with those '+++' separators ;)
17 | DESC
18 |
19 | s.homepage = 'https://github.com/EMart86/SwiftTickerView'
20 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
21 | s.license = { :type => 'MIT', :file => 'LICENSE' }
22 | s.author = { 'Martin Eberl' => 'eberl_ma@gmx.at' }
23 | s.source = { :git => 'https://github.com/EMart86/SwiftTickerView.git', :tag => s.version.to_s }
24 | # s.social_media_url = 'https://twitter.com/'
25 |
26 | s.ios.deployment_target = '9.0'
27 | s.tvos.deployment_target = '9.0'
28 |
29 | s.source_files = 'Sources/SwiftTickerView/*'
30 | end
31 |
--------------------------------------------------------------------------------
/_Pods.xcodeproj:
--------------------------------------------------------------------------------
1 | Example/Pods/Pods.xcodeproj
--------------------------------------------------------------------------------