Compare commits

Invalid templates have been ignored

1 invalid template(s) found .github/PULL_REQUEST_TEMPLATE.md: 'about' is required

..

87 Commits

Author SHA1 Message Date
iON1k fb7397a961
Merge pull request #2 from TouchInstinct/feature/swift_4_2
Feature/swift 4 2
2018-10-15 16:40:09 +03:00
Anton Popkov a691ba2010 Merge branch 'master' of github.com:xmartlabs/XLPagerTabStrip 2018-10-15 16:31:23 +03:00
Martin Barreto 73ffb21720
Merge pull request #626 from xmartlabs/fix/travis
Update xcode version in Travis config
2018-09-28 11:35:19 -03:00
Mathias Claassen 813e74e466 Update xcode version in Travis config 2018-09-28 11:32:36 -03:00
Martin Barreto f664c9c21c
Merge pull request #580 from dotkebi/readme
# modifiy `README.md` example code
2018-09-28 11:31:02 -03:00
Martin Barreto f0a0c37c76
Merge pull request #612 from ikesyo/update-example-postcell
[Example] Update PostCell to use contentView
2018-09-28 11:29:45 -03:00
Martin Barreto 8f3afd76e4
Merge pull request #614 from ikesyo/patch-1
Fix typo in README
2018-09-28 11:28:57 -03:00
Alexander Khitev 56acdd9401 updated to Swift 4.2 and added swift version to podspec (#617) 2018-09-28 11:02:48 -03:00
Sho Ikeda 7fedf7172a
Fix typo in README 2018-09-10 23:44:43 +09:00
Sho Ikeda 4ad6b8ac56 [Example] Update PostCell to use contentView
We need to place subviews onto UITableViewCell's contentView (to use `UITableViewCell.insetsContentViewsToSafeArea`).
2018-09-05 11:43:05 +09:00
Myoung-jin, Ko 17e7cc1c0a # modifiy `README.md` example code
by swift 4.1 syntax

* UIView.animate
* CGAffineTransform
2018-05-18 12:07:44 +09:00
Myoung-jin, Ko 8a5b93556c # modifiy `README.md` example code
by swift 4.1 syntax

* UIColor.whiteColor() -> UIColor.white
* UIFont.systemFontOfSize(18) -> UIFont.systemFont(ofSize: 18)
2018-05-18 11:12:37 +09:00
Martin Barreto 1619ad4fe1
Update README.md 2018-04-10 14:58:55 -03:00
Martin Barreto 7268f0afec
Merge pull request #500 from ykws/example/495
Add Example Youtube with Label
2018-04-10 14:47:16 -03:00
Martin Barreto 2f2afb62d9
Merge pull request #563 from 432daiki/fix/UIScrollViewDelegate-typo
fix UIScrollViewDelegate typo
2018-04-10 14:25:43 -03:00
Martin Barreto 7647974075
Merge pull request #506 from DenHeadless/patch-1
Fix compilation of the project when using Xcode 9 new build system and CocoaPods
2018-04-10 14:25:11 -03:00
Martin Barreto 2351f06987
Merge pull request #570 from Nixsm/master
Removing deprecated flatMap
2018-04-10 14:22:33 -03:00
Martin Barreto 372e819812
Update .travis.yml 2018-04-10 13:58:17 -03:00
Martin Barreto b56f4ad7e1
Merge pull request #566 from danielpetroianu/8.0.1_deploymentversion_fix
fix deployment target - framework should require iOS 8.0
2018-04-10 13:37:09 -03:00
Nixsm 95f96be31d Removing deprecated flatMap 2018-04-06 11:07:34 -03:00
Daniel Petroianu 3f7b234593 fix deployment target - framework should require iOS 8.0 - broken in 9bcd7cc559 2018-04-03 23:16:29 +03:00
432daiki 83735ac5a5 fix typo 2018-03-30 15:36:43 +09:00
Martin Barreto 04f02d9148 8.0.1 version 2018-03-28 17:51:53 -03:00
Martin Barreto 64a8ef8920
Merge pull request #540 from CodeStage/feature/accessibility
Accessibility traits + labels
2018-03-28 15:27:01 -03:00
Martin Barreto 04212ea5e7
Merge branch 'master' into feature/accessibility 2018-03-28 15:25:18 -03:00
AlexanderGCX a974e6b11a Accessibility for ButtonBarPagerTabStripViewController ButtonBarViewCells (#323)
* add proper accessibility information to ButtonBarPagerTabStripViewController

* mark BarButton as header for accessibility
2018-03-28 15:19:56 -03:00
Martin Barreto 2964d27c44 fix #558 2018-03-28 14:48:14 -03:00
Skye Book 5f398ceb89 docfix for assertion 2018-03-28 14:30:49 -03:00
Ryoga Kitagawa 1896e6873d Fix IndicatorInfo's initializers. 2018-03-28 14:28:14 -03:00
Christian König d0b0d76725 Added accessibility traits 2018-02-10 11:12:48 +01:00
Denys Telezhkin 4fe566f187
Fix compilation of the project when using Xcode 9 new build system and CocoaPods
With current podspec, one .xib file is getting picked up as a source, and is getting into Xcode Compile Sources build step in CocoaPods generated project. 

New build system is more strict than the old one, and prohibits this by saying:

```
error: unexpected duplicate task: CompileXIB /Path-To-Project/Pods/XLPagerTabStrip/Sources/ButtonCell.xib (in target 'XLPagerTabStrip')
```

This behavior is described in [this CocoaPods issue](https://github.com/CocoaPods/CocoaPods/issues/7079).

This PR changes source_files search path from being * to more specific code-related one *.{h,m,swift}, thus picking only sources into sources.

This fix can be verified by installing XLPagerTabStrip, trying to build with new Build System - it will fail. Then you can remove ButtonCell.xib file from Pods -> XLPagerTabStrip -> Compile Sources build phase and this time project will build successfully.
2017-12-14 16:05:40 +02:00
Yoshiyuki Kawashima ae722325b0 Add Example Youtube with Label
Put image above title text

fixes #495
2017-12-08 21:57:24 +09:00
Alexey Gerasimov 9bf01d7d0e
Merge pull request #1 from scoreyou/fix/reloadLayout
IndexPaths duplication on reload fixed
2017-12-06 17:19:21 +03:00
Alexey Gerasimov 2b9877dc68 IndexPaths duplication on reload fixed 2017-12-06 17:18:40 +03:00
pera ce3a0034d3
Merge pull request #391 from xmartlabs/feature/indicator-custom-info
Allow customization for indicators, #378
2017-11-16 12:00:09 -03:00
pera a98448beb2
Merge branch 'master' into feature/indicator-custom-info 2017-11-16 11:57:41 -03:00
Skye Book 248b2cbe5a deledate -> delegate 2017-10-28 17:44:00 -03:00
Martin Barreto 5be0da1c43
Merge pull request #476 from lowki93/feature/Swift4
fix swift 4 version
2017-10-28 17:42:51 -03:00
Kévin Budain 9bcd7cc559 fix swift 4 version 2017-10-25 11:01:42 -04:00
Martin Barreto 835570c855 Merge pull request #454 from mlequeux/master
Proper Bundle loading when linking with static libraries
2017-10-11 10:13:29 -03:00
Martin Barreto 30b9e41f0c Merge pull request #461 from 432daiki/insert_child_5
Insert child_5 into childViewControllers
2017-10-11 10:06:43 -03:00
Martin Barreto 44cefabc12 minor improvement to get pod version from cocoapods repository 2017-10-05 14:50:46 -03:00
pera b67f31b237 Merge pull request #394 from xmartlabs/swift4
Added support for swift 4
2017-10-05 14:19:45 -03:00
pera 342bdecce7 Updated README, CHANGELOG & podspec. 2017-10-05 14:17:18 -03:00
pera 07198bbb9b - Fixed warnings
- Updated to recommended project settings
- Fixed travis
2017-10-05 11:48:37 -03:00
432daiki 711a0cf6e4 Insert child_5 into childViewControllers 2017-10-05 09:53:13 +09:00
Martin Lequeux--Gruninger 3dc83770c3 Proper Bundle loading when linking with static XLPagerTabStrip 2017-09-25 11:51:45 +02:00
Federico Ojeda df0840af3c added support for swift 4 2017-06-07 15:03:44 -03:00
pera 6aede6891a Merge pull request #371 from xmartlabs/feature/swiftlint
Add swiftlint & fixes
2017-05-23 14:10:28 -03:00
pera 0b7dc7fe8c Upgrade travis 2017-05-23 13:28:58 -03:00
pera 21ca6cc08a Add swiftlint & fixes 2017-05-23 11:10:08 -03:00
pera 77da46e1fd Alternative to #378 2017-05-22 14:57:33 -03:00
pera a0c75eb245 Merge pull request #380 from xmartlabs/fix/weak-buttonBar
Fixes weak `buttonBarView`
2017-05-22 13:39:59 -03:00
pera 6d4b55ce79 Fixes weak `buttonBarView` 2017-05-22 11:00:10 -03:00
pera 89b5086ad1 Merge pull request #373 from xmartlabs/fix/issue-322
Fixes #322
2017-05-19 17:06:33 -03:00
pera 2089092533 Merge pull request #368 from xmartlabs/fix/issue-325
Fixes #325
2017-05-11 13:27:50 -03:00
pera 3f5b7b103e Fixes #322 2017-05-10 11:39:00 -03:00
pera e86bef5108 Fixes #325 2017-05-09 17:16:47 -03:00
pera 6c1cc20c9f Merge pull request #367 from xmartlabs/fix/issue-357
Fixes #357
2017-05-08 16:22:31 -03:00
pera 1bda17f09a Fixes #357 2017-05-08 16:21:08 -03:00
pera b77a9a72ce Fixed issue related to #338 2017-05-04 11:39:11 -03:00
pera 7ff9ed7554 Merge pull request #360 from kurebio/fix-scroll-direction
fix to always update lastContentOffset when scrolling
2017-05-03 17:05:44 -03:00
Miguel Revetria 7849d0cc96 Merge pull request #365 from hani-ibrahim/master
Adding `buttonBarMinimumInteritemSpacing`
2017-05-03 16:18:21 -03:00
Miguel Revetria 4c609a92b1 Fixed crash related to #338 2017-05-03 16:16:30 -03:00
pera 6a761b395c Merge pull request #330 from luvacu/selected-bar-vertical-alignment
Add option to set a different vertical alignment for selected bar
2017-05-03 12:59:41 -03:00
hani-ibrahim 2f2a4fc4de adding `buttonBarMinimumInteritemSpacing` 2017-05-03 13:41:18 +02:00
Miguel Revetria 6340728fa9 Update ISSUE_TEMPLATE.md 2017-05-02 16:27:31 -03:00
Miguel Revetria d1ae7d2175 Reload not visible cells when changing current child controller (#359) 2017-05-02 14:26:00 -03:00
d wat ccb76e2fa7 fix to always update lastContentOffset when scrolling 2017-04-29 10:40:55 +09:00
Luis Valdés d42269e5ab Add option to select a different vertical alignment for ButtonBar’s SelectedBar: top, middle or bottom (default). 2017-03-02 22:30:21 +00:00
Martin Barreto 4f2d9d9838 Update README.md 2017-01-27 15:57:57 -03:00
Martin Barreto 7f0ca677a4 Merge pull request #311 from xmartlabs/version/7.0.0
new 7.0.0 version
2017-01-27 13:48:20 -03:00
Martin Barreto 4431b20e0d new 7.0.0 version 2017-01-27 12:59:47 -03:00
Martin Barreto 7225a45c96 Merge pull request #310 from xmartlabs/fix/178
“TwitterPagerTabStripViewController crash on back navigation” fixed. …
2017-01-26 16:51:15 -03:00
Martin Barreto bf8edc820b “TwitterPagerTabStripViewController crash on back navigation” fixed. #178 2017-01-26 16:50:20 -03:00
Martin Barreto 3ecbb5665d Update README.md 2017-01-25 15:10:04 -03:00
Martin Barreto 87d6a5a96e Update README.md 2017-01-25 15:09:25 -03:00
Martin Barreto 14d0788779 Update README.md 2017-01-25 15:05:44 -03:00
Martin Barreto 93bbb990a5 minor fix 2017-01-25 14:46:21 -03:00
Martin Barreto 357d6c7bc6 Merge pull request #246 from abeyuya/fix/ButtonBarView-selectedBar-YPosition
update-selectedBar-yposition-when-use-autolayout
2017-01-25 14:26:06 -03:00
Martin Barreto 9da3e6c32b Merge pull request #280 from mt81/fix-buttonbarview-initializer
Public int(frame: collectionViewLayout:) in ButtonBarView
2017-01-25 14:18:06 -03:00
Martin Barreto 3f6534c494 Merge pull request #306 from xmartlabs/fix/274
fix #274
2017-01-24 19:44:18 -03:00
Martin Barreto 2514be218f fix #274 2017-01-24 19:43:34 -03:00
Martin Barreto 42d25afadf Merge pull request #305 from xmartlabs/issue/277
fix selected bar position issue.
2017-01-24 17:25:04 -03:00
Martin Barreto a4bbb9b209 fix selected bar position issue. 2017-01-24 16:33:08 -03:00
Matteo Ugolini 79a4ecc685 Public int(frame: collectionViewLayout:) in ButtonBarView 2016-12-01 12:51:50 -05:00
abeyuya 9bdd6acfbc update-selectedBar-yposition-when-use-autolayout 2016-10-04 14:00:26 +09:00
49 changed files with 1297 additions and 803 deletions

View File

@ -3,6 +3,7 @@ Before submitting issues ...
- Make sure you are using XLPagerTabStrip [latest release](https://github.com/xmartlabs/XLPagerTabStrip/releases) or master branch version. - Make sure you are using XLPagerTabStrip [latest release](https://github.com/xmartlabs/XLPagerTabStrip/releases) or master branch version.
- Make sure your Xcode version is the latest stable one. - Make sure your Xcode version is the latest stable one.
- Check if the issue was [already reported or fixed](https://github.com/xmartlabs/XLPagerTabStrip/issues?utf8=%E2%9C%93&q=is%3Aissue). We add labels to each issue in order to easily find related issues. If you found a match add a brief comment "I have the same problem" or "+1". - Check if the issue was [already reported or fixed](https://github.com/xmartlabs/XLPagerTabStrip/issues?utf8=%E2%9C%93&q=is%3Aissue). We add labels to each issue in order to easily find related issues. If you found a match add a brief comment "I have the same problem" or "+1".
- Please do not use the issue tracker for personal support requests. Stack Overflow is a better place for that where a wider community can help you!
When submitting issues, please provide the following information to help maintainers to fix the problem faster: When submitting issues, please provide the following information to help maintainers to fix the problem faster:

51
.swiftlint.yml Normal file
View File

@ -0,0 +1,51 @@
disabled_rules: # rule identifiers to exclude from running
# - colon
# - comma
# - control_statement
- line_length
- function_body_length
- identifier_name
- type_name
- large_tuple
opt_in_rules: # some rules are only opt-in
- empty_count
# Find all the available rules by running:
# swiftlint rules
excluded: # paths to ignore during linting. Takes precedence over `included`.
- Carthage
- Pods
- Source/ExcludedFolder
- Source/ExcludedFile.swift
# configurable rules can be customized from this configuration file
# binary rules can set their severity level
force_cast: warning # implicitly
force_try:
severity: warning # explicitly
# rules that have both warning and error levels, can set just the warning level
# implicitly
line_length: 200
# they can set both implicitly with an array
type_body_length:
- 300 # warning
- 400 # error
# or they can set both explicitly
file_length:
warning: 500
error: 1200
# naming rules can set warnings/errors for min_length and max_length
# additionally they can set excluded names
type_name:
min_length: 4 # only warning
max_length: # warning and error
warning: 40
error: 50
excluded: iPhone # excluded via string
identifier_name:
min_length: # only min_length
error: 4 # only error
excluded: # excluded via string array
- id
- URL
- GlobalAPIKey
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit, html, emoji)

View File

@ -1,7 +1,7 @@
language: objective-c language: objective-c
osx_image: xcode8 osx_image: xcode10
env: env:
- DESTINATION="OS=10.0,name=iPhone 6s" SCHEME="XLPagerTabStrip" SDK=iphonesimulator10.0 - DESTINATION="OS=12,name=iPhone 8" SCHEME="XLPagerTabStrip" SDK=iphonesimulator
before_install: before_install:
- brew update - brew update
#- brew outdated carthage || brew upgrade carthage #- brew outdated carthage || brew upgrade carthage

View File

@ -1,7 +1,21 @@
# Change Log # Change Log
All notable changes to XLPagerTabStrip will be documented in this file. All notable changes to XLPagerTabStrip will be documented in this file.
### [6.0.0](https://github.com/xmartlabs/XLPagerTabStrip/releases/tag/5.0.0) ### [8.0.1](https://github.com/xmartlabs/XLPagerTabStrip/releases/tag/8.0.1)
* Bug fixes and stability improvements.
* Support for iPhone X.
### [8.0.0](https://github.com/xmartlabs/XLPagerTabStrip/releases/tag/8.0.0)
* Xcode 9 support. (Swift 4)
* Bug fixes and stability improvements.
### [7.0.0](https://github.com/xmartlabs/XLPagerTabStrip/releases/tag/7.0.0)
* Bug fixes and stability improvements.
### [6.0.0](https://github.com/xmartlabs/XLPagerTabStrip/releases/tag/6.0.0)
* Swift 3 support * Swift 3 support
* **Breaking change**: Swiftified names of functions (you can see more details about it [here](https://github.com/xmartlabs/XLPagerTabStrip/Migration.md)) * **Breaking change**: Swiftified names of functions (you can see more details about it [here](https://github.com/xmartlabs/XLPagerTabStrip/Migration.md))

View File

@ -7,6 +7,9 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1F081A9E1FDABD1400B881EB /* YoutubeIconWithLabelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F081A9B1FDABD1400B881EB /* YoutubeIconWithLabelCell.swift */; };
1F081A9F1FDABD1400B881EB /* YoutubeIconWithLabelCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1F081A9C1FDABD1400B881EB /* YoutubeIconWithLabelCell.xib */; };
1F081AA01FDABD1400B881EB /* YoutubeWithLabelExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F081A9D1FDABD1400B881EB /* YoutubeWithLabelExampleViewController.swift */; };
285718181C568336004D7E7B /* DataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285718171C568336004D7E7B /* DataProvider.swift */; }; 285718181C568336004D7E7B /* DataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285718171C568336004D7E7B /* DataProvider.swift */; };
285DA2881C569AA2000908CA /* ChildExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285DA2861C569AA2000908CA /* ChildExampleViewController.swift */; }; 285DA2881C569AA2000908CA /* ChildExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285DA2861C569AA2000908CA /* ChildExampleViewController.swift */; };
285DA2891C569AA2000908CA /* TableChildExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285DA2871C569AA2000908CA /* TableChildExampleViewController.swift */; }; 285DA2891C569AA2000908CA /* TableChildExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285DA2871C569AA2000908CA /* TableChildExampleViewController.swift */; };
@ -78,6 +81,9 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1F081A9B1FDABD1400B881EB /* YoutubeIconWithLabelCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YoutubeIconWithLabelCell.swift; sourceTree = "<group>"; };
1F081A9C1FDABD1400B881EB /* YoutubeIconWithLabelCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = YoutubeIconWithLabelCell.xib; sourceTree = "<group>"; };
1F081A9D1FDABD1400B881EB /* YoutubeWithLabelExampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YoutubeWithLabelExampleViewController.swift; sourceTree = "<group>"; };
285718171C568336004D7E7B /* DataProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DataProvider.swift; path = Example/Helpers/DataProvider.swift; sourceTree = "<group>"; }; 285718171C568336004D7E7B /* DataProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DataProvider.swift; path = Example/Helpers/DataProvider.swift; sourceTree = "<group>"; };
285DA2861C569AA2000908CA /* ChildExampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ChildExampleViewController.swift; path = Example/ChildControllers/ChildExampleViewController.swift; sourceTree = "<group>"; }; 285DA2861C569AA2000908CA /* ChildExampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ChildExampleViewController.swift; path = Example/ChildControllers/ChildExampleViewController.swift; sourceTree = "<group>"; };
285DA2871C569AA2000908CA /* TableChildExampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TableChildExampleViewController.swift; path = Example/ChildControllers/TableChildExampleViewController.swift; sourceTree = "<group>"; }; 285DA2871C569AA2000908CA /* TableChildExampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TableChildExampleViewController.swift; path = Example/ChildControllers/TableChildExampleViewController.swift; sourceTree = "<group>"; };
@ -125,6 +131,17 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
1F081A9A1FDABD1400B881EB /* YoutubeWithLabel */ = {
isa = PBXGroup;
children = (
1F081A9B1FDABD1400B881EB /* YoutubeIconWithLabelCell.swift */,
1F081A9C1FDABD1400B881EB /* YoutubeIconWithLabelCell.xib */,
1F081A9D1FDABD1400B881EB /* YoutubeWithLabelExampleViewController.swift */,
);
name = YoutubeWithLabel;
path = Example/YoutubeWithLabel;
sourceTree = "<group>";
};
285718151C568285004D7E7B /* Helpers */ = { 285718151C568285004D7E7B /* Helpers */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -221,6 +238,7 @@
CB86ED6C1C4D6ED400DA463B /* Demo */ = { CB86ED6C1C4D6ED400DA463B /* Demo */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
1F081A9A1FDABD1400B881EB /* YoutubeWithLabel */,
285DA2911C5A5945000908CA /* Youtube */, 285DA2911C5A5945000908CA /* Youtube */,
285DA28E1C59C587000908CA /* Spotify */, 285DA28E1C59C587000908CA /* Spotify */,
285DA28A1C59210F000908CA /* Instagram */, 285DA28A1C59210F000908CA /* Instagram */,
@ -295,15 +313,15 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0720; LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0800; LastUpgradeCheck = 0900;
TargetAttributes = { TargetAttributes = {
28F828CB1C4B714D00330CF4 = { 28F828CB1C4B714D00330CF4 = {
CreatedOnToolsVersion = 7.2; CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0800; LastSwiftMigration = 0900;
}; };
28F828DF1C4B714D00330CF4 = { 28F828DF1C4B714D00330CF4 = {
CreatedOnToolsVersion = 7.2; CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0800; LastSwiftMigration = 0900;
TestTargetID = 28F828CB1C4B714D00330CF4; TestTargetID = 28F828CB1C4B714D00330CF4;
}; };
}; };
@ -358,6 +376,7 @@
CB86ED801C4D6F0D00DA463B /* Assets.xcassets in Resources */, CB86ED801C4D6F0D00DA463B /* Assets.xcassets in Resources */,
CB86ED941C4E89DD00DA463B /* PostCell.xib in Resources */, CB86ED941C4E89DD00DA463B /* PostCell.xib in Resources */,
CBA0A2021C5032E100C5748C /* Storyboard.storyboard in Resources */, CBA0A2021C5032E100C5748C /* Storyboard.storyboard in Resources */,
1F081A9F1FDABD1400B881EB /* YoutubeIconWithLabelCell.xib in Resources */,
CB86ED811C4D6F0D00DA463B /* LaunchScreen.storyboard in Resources */, CB86ED811C4D6F0D00DA463B /* LaunchScreen.storyboard in Resources */,
285DA2971C5A6A36000908CA /* YoutubeIconCell.xib in Resources */, 285DA2971C5A6A36000908CA /* YoutubeIconCell.xib in Resources */,
); );
@ -388,10 +407,12 @@
285718181C568336004D7E7B /* DataProvider.swift in Sources */, 285718181C568336004D7E7B /* DataProvider.swift in Sources */,
CB2125DE1C52A80E002DAF42 /* TwitterExampleViewController.swift in Sources */, CB2125DE1C52A80E002DAF42 /* TwitterExampleViewController.swift in Sources */,
285DA2891C569AA2000908CA /* TableChildExampleViewController.swift in Sources */, 285DA2891C569AA2000908CA /* TableChildExampleViewController.swift in Sources */,
1F081A9E1FDABD1400B881EB /* YoutubeIconWithLabelCell.swift in Sources */,
CBBD435F1C5274AE001A748E /* NavButtonBarExampleViewController.swift in Sources */, CBBD435F1C5274AE001A748E /* NavButtonBarExampleViewController.swift in Sources */,
CB71C6F31C4FDDCE008EC806 /* PostCell.swift in Sources */, CB71C6F31C4FDDCE008EC806 /* PostCell.swift in Sources */,
285DA2931C5A596B000908CA /* YoutubeExampleViewController.swift in Sources */, 285DA2931C5A596B000908CA /* YoutubeExampleViewController.swift in Sources */,
285DA2951C5A6A00000908CA /* YoutubeIconCell.swift in Sources */, 285DA2951C5A6A00000908CA /* YoutubeIconCell.swift in Sources */,
1F081AA01FDABD1400B881EB /* YoutubeWithLabelExampleViewController.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -438,14 +459,20 @@
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@ -484,14 +511,20 @@
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@ -528,7 +561,8 @@
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0; SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
}; };
name = Debug; name = Debug;
}; };
@ -543,7 +577,8 @@
PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.Example; PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.Example;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_VERSION = 3.0; SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
}; };
name = Release; name = Release;
}; };
@ -556,7 +591,8 @@
PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.ExampleUITests; PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.ExampleUITests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0; SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
TEST_TARGET_NAME = Example; TEST_TARGET_NAME = Example;
USES_XCTRUNNER = YES; USES_XCTRUNNER = YES;
}; };
@ -570,7 +606,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.ExampleUITests; PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.ExampleUITests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0; SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
TEST_TARGET_NAME = Example; TEST_TARGET_NAME = Example;
USES_XCTRUNNER = YES; USES_XCTRUNNER = YES;
}; };

View File

@ -12,15 +12,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch. // Override point for customization after application launch.
UITabBar.appearance().tintColor = UIColor.init(red: 0.027, green: 0.725, blue: 0.608, alpha: 1) UITabBar.appearance().tintColor = UIColor.init(red: 0.027, green: 0.725, blue: 0.608, alpha: 1)
UIApplication.shared.statusBarStyle = .lightContent UIApplication.shared.statusBarStyle = .lightContent
let _ = YoutubeExampleViewController(nibName: nil, bundle: nil) _ = YoutubeExampleViewController(nibName: nil, bundle: nil)
return true return true
} }
@ -46,6 +45,4 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
} }
} }

View File

@ -1,7 +1,7 @@
// BarExampleViewController.swift // BarExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -27,51 +27,50 @@ import XLPagerTabStrip
class BarExampleViewController: BarPagerTabStripViewController { class BarExampleViewController: BarPagerTabStripViewController {
var isReload = false var isReload = false
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) super.init(coder: aDecoder)
} }
override func viewDidLoad() { override func viewDidLoad() {
// set up style before super view did load is executed // set up style before super view did load is executed
settings.style.selectedBarBackgroundColor = .orange settings.style.selectedBarBackgroundColor = .orange
// - // -
super.viewDidLoad() super.viewDidLoad()
} }
// MARK: - PagerTabStripDataSource // MARK: - PagerTabStripDataSource
override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "Table View") let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "Table View")
let child_2 = ChildExampleViewController(itemInfo: "View") let child_2 = ChildExampleViewController(itemInfo: "View")
let child_3 = TableChildExampleViewController(style: .grouped, itemInfo: "Table View 2") let child_3 = TableChildExampleViewController(style: .grouped, itemInfo: "Table View 2")
let child_4 = ChildExampleViewController(itemInfo: "View 2") let child_4 = ChildExampleViewController(itemInfo: "View 2")
guard isReload else { guard isReload else {
return [child_1, child_2, child_3, child_4] return [child_1, child_2, child_3, child_4]
} }
var childViewControllers = [child_1, child_2, child_3, child_4] var childViewControllers = [child_1, child_2, child_3, child_4]
for (index, _) in childViewControllers.enumerated(){ for index in childViewControllers.indices {
let nElements = childViewControllers.count - index let nElements = childViewControllers.count - index
let n = (Int(arc4random()) % nElements) + index let n = (Int(arc4random()) % nElements) + index
if n != index{ if n != index {
swap(&childViewControllers[index], &childViewControllers[n]) childViewControllers.swapAt(index, n)
} }
} }
let nItems = 1 + (arc4random() % 4) let nItems = 1 + (arc4random() % 4)
return Array(childViewControllers.prefix(Int(nItems))) return Array(childViewControllers.prefix(Int(nItems)))
} }
override func reloadPagerTabStripView() { override func reloadPagerTabStripView() {
isReload = true isReload = true
if arc4random() % 2 == 0 { if arc4random() % 2 == 0 {
pagerBehaviour = .progressive(skipIntermediateViewControllers: arc4random() % 2 == 0, elasticIndicatorLimit: arc4random() % 2 == 0 ) pagerBehaviour = .progressive(skipIntermediateViewControllers: arc4random() % 2 == 0, elasticIndicatorLimit: arc4random() % 2 == 0 )
} } else {
else {
pagerBehaviour = .common(skipIntermediateViewControllers: arc4random() % 2 == 0) pagerBehaviour = .common(skipIntermediateViewControllers: arc4random() % 2 == 0)
} }
super.reloadPagerTabStripView() super.reloadPagerTabStripView()

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="SCa-L8-uTr"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="SCa-L8-uTr">
<device id="retina4_7" orientation="portrait"> <device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/> <adaptation id="fullscreen"/>
</device> </device>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/> <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="Navigation items with more than one left or right bar item" minToolsVersion="7.0"/> <capability name="Navigation items with more than one left or right bar item" minToolsVersion="7.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@ -20,7 +20,7 @@
<viewControllerLayoutGuide type="bottom" id="HdL-Q7-Anl"/> <viewControllerLayoutGuide type="bottom" id="HdL-Q7-Anl"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="BPt-hn-p4R"> <view key="view" contentMode="scaleToFill" id="BPt-hn-p4R">
<rect key="frame" x="0.0" y="64" width="375" height="554"/> <rect key="frame" x="0.0" y="0.0" width="375" height="554"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews> <subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="D5t-1q-KDh"> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="D5t-1q-KDh">
@ -201,14 +201,14 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="srh-qY-UAa" customClass="BarView" customModule="XLPagerTabStrip"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="srh-qY-UAa" customClass="BarView" customModule="XLPagerTabStrip">
<rect key="frame" x="0.0" y="0.0" width="375" height="5"/> <rect key="frame" x="0.0" y="20" width="375" height="5"/>
<color key="backgroundColor" red="0.029917803763441025" green="0.92659837372448983" blue="0.78518703254703159" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.029917803763441025" green="0.92659837372448983" blue="0.78518703254703159" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="5" id="EuL-ap-Nyh"/> <constraint firstAttribute="height" constant="5" id="EuL-ap-Nyh"/>
</constraints> </constraints>
</view> </view>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" alwaysBounceHorizontal="YES" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" bouncesZoom="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gaM-gk-dVJ"> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" alwaysBounceHorizontal="YES" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" bouncesZoom="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gaM-gk-dVJ">
<rect key="frame" x="0.0" y="5" width="375" height="492"/> <rect key="frame" x="0.0" y="25" width="375" height="472"/>
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</scrollView> </scrollView>
</subviews> </subviews>
@ -252,7 +252,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="PageTabController Types" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Wj6-fs-BjA"> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="PageTabController Types" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Wj6-fs-BjA">
<rect key="frame" x="15" y="0.0" width="345" height="43.5"/> <rect key="frame" x="16" y="0.0" width="343" height="43.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -276,7 +276,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Instagram Example" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="GIb-gr-QYX"> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Instagram Example" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="GIb-gr-QYX">
<rect key="frame" x="15" y="0.0" width="345" height="43.5"/> <rect key="frame" x="16" y="0.0" width="343" height="43.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -296,7 +296,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Youtube Example" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="68O-MH-NQl"> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Youtube Example" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="68O-MH-NQl">
<rect key="frame" x="15" y="0.0" width="345" height="43.5"/> <rect key="frame" x="16" y="0.0" width="343" height="43.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -308,15 +308,35 @@
<segue destination="Pux-pd-JeW" kind="presentation" id="QIG-fU-qdz"/> <segue destination="Pux-pd-JeW" kind="presentation" id="QIG-fU-qdz"/>
</connections> </connections>
</tableViewCell> </tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="bPv-uB-GeS" style="IBUITableViewCellStyleDefault" id="WB2-oq-b4x"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="yT9-cg-ta8" style="IBUITableViewCellStyleDefault" id="Vv0-op-FMh">
<rect key="frame" x="0.0" y="203" width="375" height="44"/> <rect key="frame" x="0.0" y="203" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Vv0-op-FMh" id="gmz-RN-PgI">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Youtube with Label Example" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="yT9-cg-ta8">
<rect key="frame" x="16" y="0.0" width="343" height="43.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
<connections>
<segue destination="wtp-ZI-nBV" kind="presentation" id="D5b-rl-ZDt"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="bPv-uB-GeS" style="IBUITableViewCellStyleDefault" id="WB2-oq-b4x">
<rect key="frame" x="0.0" y="247" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WB2-oq-b4x" id="2mV-U6-6pj"> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WB2-oq-b4x" id="2mV-U6-6pj">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/> <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Spotify Example" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="bPv-uB-GeS"> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Spotify Example" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="bPv-uB-GeS">
<rect key="frame" x="15" y="0.0" width="345" height="43.5"/> <rect key="frame" x="16" y="0.0" width="343" height="43.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -375,7 +395,7 @@
<viewControllerLayoutGuide type="bottom" id="MRO-1B-lmT"/> <viewControllerLayoutGuide type="bottom" id="MRO-1B-lmT"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="sAq-sJ-Hyx"> <view key="view" contentMode="scaleToFill" id="sAq-sJ-Hyx">
<rect key="frame" x="0.0" y="64" width="375" height="603"/> <rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="mzt-Sj-o9z" customClass="ButtonBarView" customModule="XLPagerTabStrip"> <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="mzt-Sj-o9z" customClass="ButtonBarView" customModule="XLPagerTabStrip">
@ -440,7 +460,7 @@
</tabBarItem> </tabBarItem>
<toolbarItems/> <toolbarItems/>
<navigationBar key="navigationBar" opaque="NO" contentMode="scaleToFill" translucent="NO" id="TRx-vY-PeE"> <navigationBar key="navigationBar" opaque="NO" contentMode="scaleToFill" translucent="NO" id="TRx-vY-PeE">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/> <rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<color key="barTintColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="barTintColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</navigationBar> </navigationBar>
@ -462,7 +482,7 @@
</tabBarItem> </tabBarItem>
<toolbarItems/> <toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="2I8-g6-D4S"> <navigationBar key="navigationBar" contentMode="scaleToFill" id="2I8-g6-D4S">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/> <rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<color key="barTintColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="barTintColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<textAttributes key="titleTextAttributes"> <textAttributes key="titleTextAttributes">
@ -492,10 +512,10 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zn6-8Q-9P3"> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zn6-8Q-9P3">
<rect key="frame" x="0.0" y="43" width="375" height="510"/> <rect key="frame" x="0.0" y="63" width="375" height="490"/>
</scrollView> </scrollView>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="FH0-FX-IMd" customClass="ButtonBarView" customModule="XLPagerTabStrip"> <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="FH0-FX-IMd" customClass="ButtonBarView" customModule="XLPagerTabStrip">
<rect key="frame" x="0.0" y="0.0" width="375" height="43"/> <rect key="frame" x="0.0" y="20" width="375" height="43"/>
<color key="backgroundColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="43" id="5Gm-jk-c1U"/> <constraint firstAttribute="height" constant="43" id="5Gm-jk-c1U"/>
@ -539,7 +559,7 @@
<viewControllerLayoutGuide type="bottom" id="64r-dM-ghd"/> <viewControllerLayoutGuide type="bottom" id="64r-dM-ghd"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="Eak-dg-otx"> <view key="view" contentMode="scaleToFill" id="Eak-dg-otx">
<rect key="frame" x="0.0" y="64" width="375" height="554"/> <rect key="frame" x="0.0" y="0.0" width="375" height="554"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews> <subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="A96-PT-Aon"> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="A96-PT-Aon">
@ -582,7 +602,7 @@
</tabBarItem> </tabBarItem>
<toolbarItems/> <toolbarItems/>
<navigationBar key="navigationBar" opaque="NO" contentMode="scaleToFill" translucent="NO" id="iMm-hr-oOU"> <navigationBar key="navigationBar" opaque="NO" contentMode="scaleToFill" translucent="NO" id="iMm-hr-oOU">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/> <rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<color key="barTintColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="barTintColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</navigationBar> </navigationBar>
@ -604,7 +624,7 @@
</tabBarItem> </tabBarItem>
<toolbarItems/> <toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="PUj-LI-AQ6"> <navigationBar key="navigationBar" contentMode="scaleToFill" id="PUj-LI-AQ6">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/> <rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<color key="barTintColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="barTintColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<textAttributes key="titleTextAttributes"> <textAttributes key="titleTextAttributes">
@ -630,7 +650,7 @@
<viewControllerLayoutGuide type="bottom" id="blo-XS-xG2"/> <viewControllerLayoutGuide type="bottom" id="blo-XS-xG2"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="Z8p-ri-ydp"> <view key="view" contentMode="scaleToFill" id="Z8p-ri-ydp">
<rect key="frame" x="0.0" y="64" width="375" height="554"/> <rect key="frame" x="0.0" y="0.0" width="375" height="554"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews> <subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QoM-XF-R9X"> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QoM-XF-R9X">
@ -666,7 +686,7 @@
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/> <simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/>
<nil key="simulatedBottomBarMetrics"/> <nil key="simulatedBottomBarMetrics"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="nn8-x2-liB"> <navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="nn8-x2-liB">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/> <rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<color key="barTintColor" red="0.086274509803921567" green="0.2627450980392157" blue="0.45490196078431372" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="barTintColor" red="0.086274509803921567" green="0.2627450980392157" blue="0.45490196078431372" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<textAttributes key="titleTextAttributes"> <textAttributes key="titleTextAttributes">
@ -676,7 +696,6 @@
</navigationBar> </navigationBar>
<nil name="viewControllers"/> <nil name="viewControllers"/>
<toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="4QH-2O-KOp"> <toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="4QH-2O-KOp">
<rect key="frame" x="0.0" y="556" width="600" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</toolbar> </toolbar>
<connections> <connections>
@ -695,7 +714,7 @@
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/> <simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/>
<nil key="simulatedBottomBarMetrics"/> <nil key="simulatedBottomBarMetrics"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="jNK-DV-g6h"> <navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="jNK-DV-g6h">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/> <rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="barTintColor" red="0.074509803921568626" green="0.078431372549019607" blue="0.078431372549019607" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="barTintColor" red="0.074509803921568626" green="0.078431372549019607" blue="0.078431372549019607" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -707,7 +726,6 @@
</navigationBar> </navigationBar>
<nil name="viewControllers"/> <nil name="viewControllers"/>
<toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="iuN-MC-o9b"> <toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="iuN-MC-o9b">
<rect key="frame" x="0.0" y="556" width="600" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</toolbar> </toolbar>
<connections> <connections>
@ -727,7 +745,7 @@
<viewControllerLayoutGuide type="bottom" id="pHS-02-a6v"/> <viewControllerLayoutGuide type="bottom" id="pHS-02-a6v"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="iXz-9N-5eX"> <view key="view" contentMode="scaleToFill" id="iXz-9N-5eX">
<rect key="frame" x="0.0" y="64" width="375" height="603"/> <rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="G0A-Qi-hkf"> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="G0A-Qi-hkf">
@ -793,7 +811,7 @@
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/> <simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/>
<nil key="simulatedBottomBarMetrics"/> <nil key="simulatedBottomBarMetrics"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" translucent="NO" id="eWp-ed-SXr"> <navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" translucent="NO" id="eWp-ed-SXr">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/> <rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="barTintColor" red="0.8666666666666667" green="0.0" blue="0.074509803921568626" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="barTintColor" red="0.8666666666666667" green="0.0" blue="0.074509803921568626" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -805,46 +823,16 @@
</navigationBar> </navigationBar>
<nil name="viewControllers"/> <nil name="viewControllers"/>
<toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="WZf-Dl-jiU"> <toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="WZf-Dl-jiU">
<rect key="frame" x="0.0" y="556" width="600" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</toolbar> </toolbar>
<connections> <connections>
<segue destination="btf-kb-vt1" kind="relationship" relationship="rootViewController" id="G6T-o8-6Hz"/> <segue destination="Y1C-8r-zKe" kind="relationship" relationship="rootViewController" id="Z69-15-Zno"/>
</connections> </connections>
</navigationController> </navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="eRh-1T-1Zf" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="eRh-1T-1Zf" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="-229" y="-2388"/> <point key="canvasLocation" x="-229" y="-2388"/>
</scene> </scene>
<!--View Controller-->
<scene sceneID="HE7-gr-1rR">
<objects>
<viewController id="btf-kb-vt1" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="EBh-30-wmN"/>
<viewControllerLayoutGuide type="bottom" id="oIy-xE-DmK"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="6rg-YN-XKC">
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mSA-qY-gR1">
<rect key="frame" x="164" y="266" width="46" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" title="Button"/>
<connections>
<segue destination="Y1C-8r-zKe" kind="show" id="7vG-sb-TIf"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
<navigationItem key="navigationItem" id="5x4-Tx-Dyl"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="EIg-eL-9rn" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="476" y="-2876"/>
</scene>
<!--Youtube Example View Controller--> <!--Youtube Example View Controller-->
<scene sceneID="9xA-v7-4VD"> <scene sceneID="9xA-v7-4VD">
<objects> <objects>
@ -854,7 +842,7 @@
<viewControllerLayoutGuide type="bottom" id="AoG-Am-Q4c"/> <viewControllerLayoutGuide type="bottom" id="AoG-Am-Q4c"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="yGV-Lf-LC4"> <view key="view" contentMode="scaleToFill" id="yGV-Lf-LC4">
<rect key="frame" x="0.0" y="64" width="375" height="603"/> <rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KX5-0N-ToU"> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KX5-0N-ToU">
@ -920,7 +908,114 @@
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="2AN-72-EPV" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="2AN-72-EPV" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="1264.8" y="-3152.4737631184412"/> <point key="canvasLocation" x="518" y="-2380"/>
</scene>
<!--Nav Controller-->
<scene sceneID="f4u-mf-lkq">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="wtp-ZI-nBV" customClass="NavController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<toolbarItems/>
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/>
<nil key="simulatedBottomBarMetrics"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" translucent="NO" id="vc1-jF-ATl">
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="barTintColor" red="0.86666666670000003" green="0.0" blue="0.074509803920000006" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<textAttributes key="titleTextAttributes">
<fontDescription key="fontDescription" type="system" weight="light" pointSize="16"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="textShadowColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</textAttributes>
</navigationBar>
<nil name="viewControllers"/>
<toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="ZXR-L3-Qqf">
<autoresizingMask key="autoresizingMask"/>
</toolbar>
<connections>
<segue destination="dFD-gP-LEB" kind="relationship" relationship="rootViewController" id="6KU-Mn-bfq"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="3ZF-Tp-4GF" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-230" y="-3067"/>
</scene>
<!--Youtube With Label Example View Controller-->
<scene sceneID="Q1j-np-84R">
<objects>
<viewController id="dFD-gP-LEB" customClass="YoutubeWithLabelExampleViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="nAm-L7-0C5"/>
<viewControllerLayoutGuide type="bottom" id="h18-Xb-G4o"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="srq-xV-ncW">
<rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OdC-5s-g0E">
<rect key="frame" x="0.0" y="70" width="375" height="533"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</scrollView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ye3-ds-RRe">
<rect key="frame" x="28" y="558" width="84" height="33"/>
<color key="backgroundColor" red="1" green="0.99997437" blue="0.99999129769999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="84" id="gxr-hQ-rJo"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="heavy" pointSize="17"/>
<state key="normal" title="CLOSE"/>
<connections>
<action selector="closeAction:" destination="dFD-gP-LEB" eventType="touchUpInside" id="tGE-Hd-oiU"/>
</connections>
</button>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="NF8-r2-llj" customClass="ButtonBarView" customModule="XLPagerTabStrip">
<rect key="frame" x="0.0" y="0.0" width="375" height="70"/>
<constraints>
<constraint firstAttribute="height" constant="70" id="eHr-qr-UnQ"/>
</constraints>
<inset key="scrollIndicatorInsets" minX="15" minY="0.0" maxX="15" maxY="0.0"/>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="10" minimumInteritemSpacing="10" id="NcL-oD-vkg">
<size key="itemSize" width="40" height="40"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
<cells/>
</collectionView>
</subviews>
<color key="backgroundColor" red="0.058823529409999999" green="0.062745098040000002" blue="0.062745098040000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="h18-Xb-G4o" firstAttribute="top" secondItem="Ye3-ds-RRe" secondAttribute="bottom" constant="12" id="8Vn-VD-e3K"/>
<constraint firstItem="Ye3-ds-RRe" firstAttribute="leading" secondItem="srq-xV-ncW" secondAttribute="leadingMargin" constant="12" id="PI1-vN-tQn"/>
<constraint firstItem="OdC-5s-g0E" firstAttribute="leading" secondItem="srq-xV-ncW" secondAttribute="leading" id="Yhg-Df-lY8"/>
<constraint firstItem="NF8-r2-llj" firstAttribute="top" secondItem="nAm-L7-0C5" secondAttribute="bottom" id="cGp-RS-hTW"/>
<constraint firstAttribute="trailing" secondItem="NF8-r2-llj" secondAttribute="trailing" id="diI-XY-ee6"/>
<constraint firstItem="h18-Xb-G4o" firstAttribute="top" secondItem="OdC-5s-g0E" secondAttribute="bottom" id="iOV-H7-dW1"/>
<constraint firstItem="NF8-r2-llj" firstAttribute="leading" secondItem="srq-xV-ncW" secondAttribute="leading" id="rDI-Ht-8Px"/>
<constraint firstItem="OdC-5s-g0E" firstAttribute="top" secondItem="NF8-r2-llj" secondAttribute="bottom" id="vlA-DF-8l2"/>
<constraint firstAttribute="trailing" secondItem="OdC-5s-g0E" secondAttribute="trailing" id="xNh-E4-YQz"/>
</constraints>
</view>
<toolbarItems/>
<navigationItem key="navigationItem" id="Ogr-CI-ZbI">
<barButtonItem key="leftBarButtonItem" title=" Home" id="2RO-X1-xjA"/>
<rightBarButtonItems>
<barButtonItem image="more_options" id="c1i-ZN-Neo">
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</barButtonItem>
<barButtonItem image="search" id="nYs-bs-onl">
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</barButtonItem>
</rightBarButtonItems>
</navigationItem>
<connections>
<outlet property="buttonBarView" destination="NF8-r2-llj" id="mQR-fl-D9w"/>
<outlet property="containerView" destination="OdC-5s-g0E" id="4MA-bD-Sxw"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Loe-25-w2Z" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="518" y="-3067"/>
</scene> </scene>
</scenes> </scenes>
<resources> <resources>

View File

@ -1,7 +1,7 @@
// ButtonBarExampleViewController.swift // ButtonBarExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -26,18 +26,18 @@ import Foundation
import XLPagerTabStrip import XLPagerTabStrip
class ButtonBarExampleViewController: ButtonBarPagerTabStripViewController { class ButtonBarExampleViewController: ButtonBarPagerTabStripViewController {
var isReload = false var isReload = false
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
buttonBarView.selectedBar.backgroundColor = .orange buttonBarView.selectedBar.backgroundColor = .orange
buttonBarView.backgroundColor = UIColor(red: 7/255, green: 185/255, blue: 155/255, alpha: 1) buttonBarView.backgroundColor = UIColor(red: 7/255, green: 185/255, blue: 155/255, alpha: 1)
} }
// MARK: - PagerTabStripDataSource // MARK: - PagerTabStripDataSource
override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "Table View") let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "Table View")
let child_2 = ChildExampleViewController(itemInfo: "View") let child_2 = ChildExampleViewController(itemInfo: "View")
@ -47,30 +47,29 @@ class ButtonBarExampleViewController: ButtonBarPagerTabStripViewController {
let child_6 = ChildExampleViewController(itemInfo: "View 3") let child_6 = ChildExampleViewController(itemInfo: "View 3")
let child_7 = TableChildExampleViewController(style: .grouped, itemInfo: "Table View 4") let child_7 = TableChildExampleViewController(style: .grouped, itemInfo: "Table View 4")
let child_8 = ChildExampleViewController(itemInfo: "View 4") let child_8 = ChildExampleViewController(itemInfo: "View 4")
guard isReload else { guard isReload else {
return [child_1, child_2, child_3, child_4, child_5, child_6, child_7, child_8] return [child_1, child_2, child_3, child_4, child_5, child_6, child_7, child_8]
} }
var childViewControllers = [child_1, child_2, child_3, child_4, child_6, child_7, child_8] var childViewControllers = [child_1, child_2, child_3, child_4, child_5, child_6, child_7, child_8]
for (index, _) in childViewControllers.enumerated(){ for index in childViewControllers.indices {
let nElements = childViewControllers.count - index let nElements = childViewControllers.count - index
let n = (Int(arc4random()) % nElements) + index let n = (Int(arc4random()) % nElements) + index
if n != index{ if n != index {
swap(&childViewControllers[index], &childViewControllers[n]) childViewControllers.swapAt(index, n)
} }
} }
let nItems = 1 + (arc4random() % 8) let nItems = 1 + (arc4random() % 8)
return Array(childViewControllers.prefix(Int(nItems))) return Array(childViewControllers.prefix(Int(nItems)))
} }
override func reloadPagerTabStripView() { override func reloadPagerTabStripView() {
isReload = true isReload = true
if arc4random() % 2 == 0 { if arc4random() % 2 == 0 {
pagerBehaviour = .progressive(skipIntermediateViewControllers: arc4random() % 2 == 0, elasticIndicatorLimit: arc4random() % 2 == 0 ) pagerBehaviour = .progressive(skipIntermediateViewControllers: arc4random() % 2 == 0, elasticIndicatorLimit: arc4random() % 2 == 0 )
} } else {
else {
pagerBehaviour = .common(skipIntermediateViewControllers: arc4random() % 2 == 0) pagerBehaviour = .common(skipIntermediateViewControllers: arc4random() % 2 == 0)
} }
super.reloadPagerTabStripView() super.reloadPagerTabStripView()

View File

@ -1,7 +1,7 @@
// ChildExampleViewController.swift // ChildExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -26,9 +26,9 @@ import Foundation
import XLPagerTabStrip import XLPagerTabStrip
class ChildExampleViewController: UIViewController, IndicatorInfoProvider { class ChildExampleViewController: UIViewController, IndicatorInfoProvider {
var itemInfo: IndicatorInfo = "View" var itemInfo: IndicatorInfo = "View"
init(itemInfo: IndicatorInfo) { init(itemInfo: IndicatorInfo) {
self.itemInfo = itemInfo self.itemInfo = itemInfo
super.init(nibName: nil, bundle: nil) super.init(nibName: nil, bundle: nil)
@ -37,23 +37,23 @@ class ChildExampleViewController: UIViewController, IndicatorInfoProvider {
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
let label = UILabel() let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false label.translatesAutoresizingMaskIntoConstraints = false
label.text = "XLPagerTabStrip" label.text = "XLPagerTabStrip"
view.addSubview(label) view.addSubview(label)
view.backgroundColor = .white view.backgroundColor = .white
view.addConstraint(NSLayoutConstraint(item: label, attribute: .centerX, relatedBy: .equal, toItem: view, attribute: .centerX, multiplier: 1, constant: 0)) view.addConstraint(NSLayoutConstraint(item: label, attribute: .centerX, relatedBy: .equal, toItem: view, attribute: .centerX, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: label, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: -50)) view.addConstraint(NSLayoutConstraint(item: label, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: -50))
} }
// MARK: - IndicatorInfoProvider // MARK: - IndicatorInfoProvider
func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo { func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
return itemInfo return itemInfo
} }

View File

@ -1,7 +1,7 @@
// TableChildExampleViewController.swift // TableChildExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -26,60 +26,61 @@ import Foundation
import XLPagerTabStrip import XLPagerTabStrip
class TableChildExampleViewController: UITableViewController, IndicatorInfoProvider { class TableChildExampleViewController: UITableViewController, IndicatorInfoProvider {
let cellIdentifier = "postCell" let cellIdentifier = "postCell"
var blackTheme = false var blackTheme = false
var itemInfo = IndicatorInfo(title: "View") var itemInfo = IndicatorInfo(title: "View")
init(style: UITableViewStyle, itemInfo: IndicatorInfo) { init(style: UITableViewStyle, itemInfo: IndicatorInfo) {
self.itemInfo = itemInfo self.itemInfo = itemInfo
super.init(style: style) super.init(style: style)
} }
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
tableView.register(UINib(nibName: "PostCell", bundle: Bundle.main), forCellReuseIdentifier: cellIdentifier) tableView.register(UINib(nibName: "PostCell", bundle: Bundle.main), forCellReuseIdentifier: cellIdentifier)
tableView.estimatedRowHeight = 60.0; tableView.estimatedRowHeight = 60.0
tableView.rowHeight = UITableViewAutomaticDimension tableView.rowHeight = UITableViewAutomaticDimension
tableView.allowsSelection = false tableView.allowsSelection = false
if blackTheme { if blackTheme {
tableView.backgroundColor = UIColor(red: 15/255.0, green: 16/255.0, blue: 16/255.0, alpha: 1.0) tableView.backgroundColor = UIColor(red: 15/255.0, green: 16/255.0, blue: 16/255.0, alpha: 1.0)
} }
} }
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
tableView.reloadData() tableView.reloadData()
} }
// MARK: - UITableViewDataSource // MARK: - UITableViewDataSource
override func numberOfSections(in tableView: UITableView) -> Int { override func numberOfSections(in tableView: UITableView) -> Int {
return 1 return 1
} }
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return DataProvider.sharedInstance.postsData.count return DataProvider.sharedInstance.postsData.count
} }
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! PostCell guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? PostCell,
let data = DataProvider.sharedInstance.postsData.object(at: indexPath.row) as! let data = DataProvider.sharedInstance.postsData.object(at: indexPath.row) as? NSDictionary else { return PostCell() }
NSDictionary
cell.configureWithData(data) cell.configureWithData(data)
if blackTheme { if blackTheme {
cell.changeStylToBlack() cell.changeStylToBlack()
} }
return cell return cell
} }
// MARK: - IndicatorInfoProvider // MARK: - IndicatorInfoProvider
func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo { func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
return itemInfo return itemInfo
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
// PostCell.swift // PostCell.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -25,28 +25,25 @@
import UIKit import UIKit
class PostCell: UITableViewCell { class PostCell: UITableViewCell {
@IBOutlet weak var userImage: UIImageView! @IBOutlet weak var userImage: UIImageView!
@IBOutlet weak var postName: UILabel! @IBOutlet weak var postName: UILabel!
@IBOutlet weak var postText: UILabel! @IBOutlet weak var postText: UILabel!
override func awakeFromNib() { override func awakeFromNib() {
super.awakeFromNib() super.awakeFromNib()
userImage.layer.cornerRadius = 10.0 userImage.layer.cornerRadius = 10.0
} }
func configureWithData(_ data: NSDictionary) {
func configureWithData(_ data: NSDictionary){
if let post = data["post"] as? NSDictionary, let user = post["user"] as? NSDictionary { if let post = data["post"] as? NSDictionary, let user = post["user"] as? NSDictionary {
postName.text = user["name"] as? String postName.text = user["name"] as? String
postText.text = post["text"] as? String postText.text = post["text"] as? String
userImage.image = UIImage(named: postName.text!.replacingOccurrences(of: " ", with: "_")) userImage.image = UIImage(named: postName.text!.replacingOccurrences(of: " ", with: "_"))
} }
} }
func changeStylToBlack() {
func changeStylToBlack(){
userImage?.layer.cornerRadius = 30.0 userImage?.layer.cornerRadius = 30.0
postText.text = nil postText.text = nil
postName.font = UIFont(name: "HelveticaNeue-Light", size:18) ?? .systemFont(ofSize: 18) postName.font = UIFont(name: "HelveticaNeue-Light", size:18) ?? .systemFont(ofSize: 18)

View File

@ -1,57 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="PostCell" customModule="Example" customModuleProvider="target"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="84" id="b8n-8Y-pxb" customClass="PostCell" customModule="Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="326" height="84"/> <rect key="frame" x="0.0" y="0.0" width="375" height="84"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="b8n-8Y-pxb" id="K88-rd-6gZ">
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="3cF-Pb-bhF"> <rect key="frame" x="0.0" y="0.0" width="375" height="83.5"/>
<rect key="frame" x="12" y="12" width="60" height="60"/> <autoresizingMask key="autoresizingMask"/>
<constraints> <subviews>
<constraint firstAttribute="width" constant="60" id="Pny-Yy-5g4"/> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="wQ5-jv-KcD">
<constraint firstAttribute="height" constant="60" id="xre-y3-QCa"/> <rect key="frame" x="12" y="12" width="60" height="60"/>
</constraints> <constraints>
</imageView> <constraint firstAttribute="height" constant="60" id="a22-Yz-B14"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XpS-ev-AZK"> <constraint firstAttribute="width" constant="60" id="h3B-3k-YAV"/>
<rect key="frame" x="80" y="12" width="229" height="18"/> </constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/> </imageView>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Xt9-VS-IpY">
<nil key="highlightedColor"/> <rect key="frame" x="80" y="12" width="278" height="18"/>
</label> <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="M84-ZZ-G5B"> <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<rect key="frame" x="80" y="38" width="229" height="18"/> <nil key="highlightedColor"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/> </label>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fIC-u4-GzA">
<nil key="highlightedColor"/> <rect key="frame" x="80" y="38" width="278" height="18"/>
</label> <fontDescription key="fontDescription" type="system" pointSize="15"/>
</subviews> <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> <nil key="highlightedColor"/>
<constraints> </label>
<constraint firstAttribute="trailing" secondItem="M84-ZZ-G5B" secondAttribute="trailing" constant="17" id="ERc-X0-bm6"/> </subviews>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="M84-ZZ-G5B" secondAttribute="bottom" priority="999" constant="20" id="I1d-nA-bLK"/> <constraints>
<constraint firstItem="XpS-ev-AZK" firstAttribute="leading" secondItem="3cF-Pb-bhF" secondAttribute="trailing" constant="8" id="MCp-qr-s7q"/> <constraint firstItem="wQ5-jv-KcD" firstAttribute="top" secondItem="K88-rd-6gZ" secondAttribute="top" constant="12" id="0nA-Ff-0jE"/>
<constraint firstItem="M84-ZZ-G5B" firstAttribute="top" secondItem="XpS-ev-AZK" secondAttribute="bottom" constant="8" id="PxD-gM-hbj"/> <constraint firstItem="Xt9-VS-IpY" firstAttribute="leading" secondItem="wQ5-jv-KcD" secondAttribute="trailing" constant="8" id="CJD-v3-ZI5"/>
<constraint firstItem="M84-ZZ-G5B" firstAttribute="leading" secondItem="3cF-Pb-bhF" secondAttribute="trailing" constant="8" id="VmA-J2-6Ur"/> <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="fIC-u4-GzA" secondAttribute="bottom" priority="999" constant="20" id="Dsa-9n-hAy"/>
<constraint firstItem="3cF-Pb-bhF" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="12" id="Vqu-xf-y9G"/> <constraint firstAttribute="trailing" secondItem="fIC-u4-GzA" secondAttribute="trailing" constant="17" id="NGB-u3-BwT"/>
<constraint firstItem="XpS-ev-AZK" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="12" id="XP8-3C-YTa"/> <constraint firstItem="Xt9-VS-IpY" firstAttribute="top" secondItem="K88-rd-6gZ" secondAttribute="top" constant="12" id="aeT-ml-Joy"/>
<constraint firstAttribute="trailing" secondItem="XpS-ev-AZK" secondAttribute="trailing" constant="17" id="dh0-1d-SBr"/> <constraint firstItem="fIC-u4-GzA" firstAttribute="leading" secondItem="wQ5-jv-KcD" secondAttribute="trailing" constant="8" id="cdd-j8-SOs"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="3cF-Pb-bhF" secondAttribute="bottom" priority="999" constant="12" id="f9x-qu-WpO"/> <constraint firstItem="wQ5-jv-KcD" firstAttribute="leading" secondItem="K88-rd-6gZ" secondAttribute="leading" constant="12" id="hyC-j1-1ur"/>
<constraint firstItem="3cF-Pb-bhF" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="12" id="rjQ-uH-Euv"/> <constraint firstAttribute="bottom" secondItem="wQ5-jv-KcD" secondAttribute="bottom" priority="999" constant="12" id="igs-Iw-meI"/>
</constraints> <constraint firstAttribute="trailing" secondItem="Xt9-VS-IpY" secondAttribute="trailing" constant="17" id="xNw-iC-WEv"/>
<nil key="simulatedStatusBarMetrics"/> <constraint firstItem="fIC-u4-GzA" firstAttribute="top" secondItem="Xt9-VS-IpY" secondAttribute="bottom" constant="8" id="ypP-AG-hch"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> </constraints>
</tableViewCellContentView>
<connections> <connections>
<outlet property="postName" destination="XpS-ev-AZK" id="sua-hr-KD7"/> <outlet property="postName" destination="Xt9-VS-IpY" id="VYd-5D-WAS"/>
<outlet property="postText" destination="M84-ZZ-G5B" id="981-BE-BOc"/> <outlet property="postText" destination="fIC-u4-GzA" id="GvN-fW-jWH"/>
<outlet property="userImage" destination="3cF-Pb-bhF" id="rkH-iK-qN8"/> <outlet property="userImage" destination="wQ5-jv-KcD" id="T64-Nd-dc9"/>
</connections> </connections>
<point key="canvasLocation" x="362" y="495"/> <point key="canvasLocation" x="348" y="692"/>
</view> </tableViewCell>
</objects> </objects>
</document> </document>

View File

@ -1,7 +1,7 @@
// SegmentedExampleViewController.swift // SegmentedExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -26,10 +26,10 @@ import Foundation
import XLPagerTabStrip import XLPagerTabStrip
class InstagramExampleViewController: ButtonBarPagerTabStripViewController { class InstagramExampleViewController: ButtonBarPagerTabStripViewController {
@IBOutlet weak var shadowView: UIView! @IBOutlet weak var shadowView: UIView!
let blueInstagramColor = UIColor(red: 37/255.0, green: 111/255.0, blue: 206/255.0, alpha: 1.0) let blueInstagramColor = UIColor(red: 37/255.0, green: 111/255.0, blue: 206/255.0, alpha: 1.0)
override func viewDidLoad() { override func viewDidLoad() {
// change selected bar color // change selected bar color
settings.style.buttonBarBackgroundColor = .white settings.style.buttonBarBackgroundColor = .white
@ -39,10 +39,10 @@ class InstagramExampleViewController: ButtonBarPagerTabStripViewController {
settings.style.selectedBarHeight = 2.0 settings.style.selectedBarHeight = 2.0
settings.style.buttonBarMinimumLineSpacing = 0 settings.style.buttonBarMinimumLineSpacing = 0
settings.style.buttonBarItemTitleColor = .black settings.style.buttonBarItemTitleColor = .black
settings.style.buttonBarItemsShouldFillAvailiableWidth = true settings.style.buttonBarItemsShouldFillAvailableWidth = true
settings.style.buttonBarLeftContentInset = 0 settings.style.buttonBarLeftContentInset = 0
settings.style.buttonBarRightContentInset = 0 settings.style.buttonBarRightContentInset = 0
changeCurrentIndexProgressive = { [weak self] (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in changeCurrentIndexProgressive = { [weak self] (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in
guard changeCurrentIndex == true else { return } guard changeCurrentIndex == true else { return }
oldCell?.label.textColor = .black oldCell?.label.textColor = .black
@ -50,9 +50,9 @@ class InstagramExampleViewController: ButtonBarPagerTabStripViewController {
} }
super.viewDidLoad() super.viewDidLoad()
} }
// MARK: - PagerTabStripDataSource // MARK: - PagerTabStripDataSource
override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "FOLLOWING") let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "FOLLOWING")
let child_2 = ChildExampleViewController(itemInfo: "YOU") let child_2 = ChildExampleViewController(itemInfo: "YOU")
@ -60,13 +60,8 @@ class InstagramExampleViewController: ButtonBarPagerTabStripViewController {
} }
// MARK: - Custom Action // MARK: - Custom Action
@IBAction func closeAction(_ sender: UIButton) { @IBAction func closeAction(_ sender: UIButton) {
dismiss(animated: true, completion: nil) dismiss(animated: true, completion: nil)
} }
} }

View File

@ -1,7 +1,7 @@
// NavButtonBarExampleViewController.swift // NavButtonBarExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -27,38 +27,37 @@ import XLPagerTabStrip
class NavButtonBarExampleViewController: ButtonBarPagerTabStripViewController { class NavButtonBarExampleViewController: ButtonBarPagerTabStripViewController {
var isReload = false var isReload = false
override func viewDidLoad() { override func viewDidLoad() {
// set up style before super view did load is executed // set up style before super view did load is executed
settings.style.buttonBarBackgroundColor = .clear settings.style.buttonBarBackgroundColor = .clear
settings.style.selectedBarBackgroundColor = .orange settings.style.selectedBarBackgroundColor = .orange
//- //-
super.viewDidLoad() super.viewDidLoad()
buttonBarView.removeFromSuperview() buttonBarView.removeFromSuperview()
navigationController?.navigationBar.addSubview(buttonBarView) navigationController?.navigationBar.addSubview(buttonBarView)
changeCurrentIndexProgressive = { (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in changeCurrentIndexProgressive = { (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in
guard changeCurrentIndex == true else { return } guard changeCurrentIndex == true else { return }
oldCell?.label.textColor = UIColor(white: 1, alpha: 0.6) oldCell?.label.textColor = UIColor(white: 1, alpha: 0.6)
newCell?.label.textColor = .white newCell?.label.textColor = .white
if animated { if animated {
UIView.animate(withDuration: 0.1, animations: { () -> Void in UIView.animate(withDuration: 0.1, animations: { () -> Void in
newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0) newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
}) })
} } else {
else {
newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0) newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
} }
} }
} }
// MARK: - PagerTabStripDataSource // MARK: - PagerTabStripDataSource
override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "Table View") let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "Table View")
let child_2 = ChildExampleViewController(itemInfo: "View") let child_2 = ChildExampleViewController(itemInfo: "View")
@ -68,35 +67,34 @@ class NavButtonBarExampleViewController: ButtonBarPagerTabStripViewController {
let child_6 = ChildExampleViewController(itemInfo: "View 2") let child_6 = ChildExampleViewController(itemInfo: "View 2")
let child_7 = TableChildExampleViewController(style: .grouped, itemInfo: "Table View 4") let child_7 = TableChildExampleViewController(style: .grouped, itemInfo: "Table View 4")
let child_8 = ChildExampleViewController(itemInfo: "View 3") let child_8 = ChildExampleViewController(itemInfo: "View 3")
guard isReload else { guard isReload else {
return [child_1, child_2, child_3, child_4, child_5, child_6, child_7, child_8] return [child_1, child_2, child_3, child_4, child_5, child_6, child_7, child_8]
} }
var childViewControllers = [child_1, child_2, child_3, child_4, child_6, child_7, child_8] var childViewControllers = [child_1, child_2, child_3, child_4, child_5, child_6, child_7, child_8]
for (index, _) in childViewControllers.enumerated(){ for index in childViewControllers.indices {
let nElements = childViewControllers.count - index let nElements = childViewControllers.count - index
let n = (Int(arc4random()) % nElements) + index let n = (Int(arc4random()) % nElements) + index
if n != index{ if n != index {
swap(&childViewControllers[index], &childViewControllers[n]) childViewControllers.swapAt(index, n)
} }
} }
let nItems = 1 + (arc4random() % 8) let nItems = 1 + (arc4random() % 8)
return Array(childViewControllers.prefix(Int(nItems))) return Array(childViewControllers.prefix(Int(nItems)))
} }
override func reloadPagerTabStripView() { override func reloadPagerTabStripView() {
isReload = true isReload = true
if arc4random() % 2 == 0 { if arc4random() % 2 == 0 {
pagerBehaviour = .progressive(skipIntermediateViewControllers: arc4random() % 2 == 0, elasticIndicatorLimit: arc4random() % 2 == 0 ) pagerBehaviour = .progressive(skipIntermediateViewControllers: arc4random() % 2 == 0, elasticIndicatorLimit: arc4random() % 2 == 0 )
} } else {
else {
pagerBehaviour = .common(skipIntermediateViewControllers: arc4random() % 2 == 0) pagerBehaviour = .common(skipIntermediateViewControllers: arc4random() % 2 == 0)
} }
super.reloadPagerTabStripView() super.reloadPagerTabStripView()
} }
override func configureCell(_ cell: ButtonBarViewCell, indicatorInfo: IndicatorInfo) { override func configureCell(_ cell: ButtonBarViewCell, indicatorInfo: IndicatorInfo) {
super.configureCell(cell, indicatorInfo: indicatorInfo) super.configureCell(cell, indicatorInfo: indicatorInfo)
cell.backgroundColor = .clear cell.backgroundColor = .clear

View File

@ -1,7 +1,7 @@
// ReloadExampleViewController.swift // ReloadExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -26,12 +26,12 @@ import UIKit
import XLPagerTabStrip import XLPagerTabStrip
class ReloadExampleViewController: UIViewController { class ReloadExampleViewController: UIViewController {
@IBOutlet lazy var titleLabel: UILabel! = { @IBOutlet lazy var titleLabel: UILabel! = {
let label = UILabel() let label = UILabel()
return label return label
}() }()
lazy var bigLabel: UILabel = { lazy var bigLabel: UILabel = {
let bigLabel = UILabel() let bigLabel = UILabel()
bigLabel.backgroundColor = .clear bigLabel.backgroundColor = .clear
@ -40,20 +40,20 @@ class ReloadExampleViewController: UIViewController {
bigLabel.adjustsFontSizeToFitWidth = true bigLabel.adjustsFontSizeToFitWidth = true
return bigLabel return bigLabel
}() }()
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
if let _ = navigationController { if navigationController != nil {
navigationItem.titleView = bigLabel navigationItem.titleView = bigLabel
bigLabel.sizeToFit() bigLabel.sizeToFit()
} }
if let pagerViewController = childViewControllers.filter( { $0 is PagerTabStripViewController } ).first as? PagerTabStripViewController { if let pagerViewController = childViewControllers.first as? PagerTabStripViewController {
updateTitle(of: pagerViewController) updateTitle(of: pagerViewController)
} }
} }
@IBAction func reloadTapped(_ sender: UIBarButtonItem) { @IBAction func reloadTapped(_ sender: UIBarButtonItem) {
for childViewController in childViewControllers { for childViewController in childViewControllers {
guard let child = childViewController as? PagerTabStripViewController else { guard let child = childViewController as? PagerTabStripViewController else {
@ -61,27 +61,26 @@ class ReloadExampleViewController: UIViewController {
} }
child.reloadPagerTabStripView() child.reloadPagerTabStripView()
updateTitle(of: child) updateTitle(of: child)
break; break
} }
} }
@IBAction func closeTapped(_ sender: UIButton) { @IBAction func closeTapped(_ sender: UIButton) {
dismiss(animated: true, completion: nil) dismiss(animated: true, completion: nil)
} }
func updateTitle(of pagerTabStripViewController: PagerTabStripViewController) { func updateTitle(of pagerTabStripViewController: PagerTabStripViewController) {
func stringFromBool(_ bool: Bool) -> String { func stringFromBool(_ bool: Bool) -> String {
return bool ? "YES" : "NO" return bool ? "YES" : "NO"
} }
titleLabel.text = "Progressive = \(stringFromBool(pagerTabStripViewController.pagerBehaviour.isProgressiveIndicator)) ElasticLimit = \(stringFromBool(pagerTabStripViewController.pagerBehaviour.isElasticIndicatorLimit))" titleLabel.text = "Progressive = \(stringFromBool(pagerTabStripViewController.pagerBehaviour.isProgressiveIndicator)) ElasticLimit = \(stringFromBool(pagerTabStripViewController.pagerBehaviour.isElasticIndicatorLimit))"
(navigationItem.titleView as? UILabel)?.text = titleLabel.text (navigationItem.titleView as? UILabel)?.text = titleLabel.text
navigationItem.titleView?.sizeToFit() navigationItem.titleView?.sizeToFit()
} }
override var preferredStatusBarStyle : UIStatusBarStyle { override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent return .lightContent
} }
} }

View File

@ -1,7 +1,7 @@
// SegmentedExampleViewController.swift // SegmentedExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -26,41 +26,41 @@ import Foundation
import XLPagerTabStrip import XLPagerTabStrip
class SegmentedExampleViewController: SegmentedPagerTabStripViewController { class SegmentedExampleViewController: SegmentedPagerTabStripViewController {
var isReload = false var isReload = false
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) super.init(coder: aDecoder)
// change segmented style // change segmented style
settings.style.segmentedControlColor = .white settings.style.segmentedControlColor = .white
} }
// MARK: - PagerTabStripDataSource // MARK: - PagerTabStripDataSource
override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "Table View") let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "Table View")
let child_2 = ChildExampleViewController(itemInfo: "View") let child_2 = ChildExampleViewController(itemInfo: "View")
let child_3 = TableChildExampleViewController(style: .grouped, itemInfo: "Table View 2") let child_3 = TableChildExampleViewController(style: .grouped, itemInfo: "Table View 2")
let child_4 = ChildExampleViewController(itemInfo: "View 2") let child_4 = ChildExampleViewController(itemInfo: "View 2")
guard isReload else { guard isReload else {
return [child_1, child_2, child_3, child_4] return [child_1, child_2, child_3, child_4]
} }
var childViewControllers = [child_1, child_2, child_3, child_4] var childViewControllers = [child_1, child_2, child_3, child_4]
let count = childViewControllers.count let count = childViewControllers.count
for (index, _) in childViewControllers.enumerated(){ for index in childViewControllers.indices {
let nElements = count - index let nElements = count - index
let n = (Int(arc4random()) % nElements) + index let n = (Int(arc4random()) % nElements) + index
if n != index{ if n != index {
swap(&childViewControllers[index], &childViewControllers[n]) childViewControllers.swapAt(index, n)
} }
} }
let nItems = 1 + (arc4random() % 4) let nItems = 1 + (arc4random() % 4)
return Array(childViewControllers.prefix(Int(nItems))) return Array(childViewControllers.prefix(Int(nItems)))
} }
@IBAction func reloadTapped(_ sender: UIBarButtonItem) { @IBAction func reloadTapped(_ sender: UIBarButtonItem) {
isReload = true isReload = true
pagerBehaviour = .common(skipIntermediateViewControllers: arc4random() % 2 == 0) pagerBehaviour = .common(skipIntermediateViewControllers: arc4random() % 2 == 0)

View File

@ -1,7 +1,7 @@
// SpotifyExampleViewController.swift // SpotifyExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -26,12 +26,12 @@ import Foundation
import XLPagerTabStrip import XLPagerTabStrip
class SpotifyExampleViewController: ButtonBarPagerTabStripViewController { class SpotifyExampleViewController: ButtonBarPagerTabStripViewController {
@IBOutlet weak var shadowView: UIView! @IBOutlet weak var shadowView: UIView!
let graySpotifyColor = UIColor(red: 21/255.0, green: 21/255.0, blue: 24/255.0, alpha: 1.0) let graySpotifyColor = UIColor(red: 21/255.0, green: 21/255.0, blue: 24/255.0, alpha: 1.0)
let darkGraySpotifyColor = UIColor(red: 19/255.0, green: 20/255.0, blue: 20/255.0, alpha: 1.0) let darkGraySpotifyColor = UIColor(red: 19/255.0, green: 20/255.0, blue: 20/255.0, alpha: 1.0)
override func viewDidLoad() { override func viewDidLoad() {
// change selected bar color // change selected bar color
settings.style.buttonBarBackgroundColor = graySpotifyColor settings.style.buttonBarBackgroundColor = graySpotifyColor
@ -41,11 +41,11 @@ class SpotifyExampleViewController: ButtonBarPagerTabStripViewController {
settings.style.selectedBarHeight = 3.0 settings.style.selectedBarHeight = 3.0
settings.style.buttonBarMinimumLineSpacing = 0 settings.style.buttonBarMinimumLineSpacing = 0
settings.style.buttonBarItemTitleColor = .black settings.style.buttonBarItemTitleColor = .black
settings.style.buttonBarItemsShouldFillAvailiableWidth = true settings.style.buttonBarItemsShouldFillAvailableWidth = true
settings.style.buttonBarLeftContentInset = 20 settings.style.buttonBarLeftContentInset = 20
settings.style.buttonBarRightContentInset = 20 settings.style.buttonBarRightContentInset = 20
changeCurrentIndexProgressive = { (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in changeCurrentIndexProgressive = { (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in
guard changeCurrentIndex == true else { return } guard changeCurrentIndex == true else { return }
oldCell?.label.textColor = UIColor(red: 138/255.0, green: 138/255.0, blue: 144/255.0, alpha: 1.0) oldCell?.label.textColor = UIColor(red: 138/255.0, green: 138/255.0, blue: 144/255.0, alpha: 1.0)
@ -53,9 +53,9 @@ class SpotifyExampleViewController: ButtonBarPagerTabStripViewController {
} }
super.viewDidLoad() super.viewDidLoad()
} }
// MARK: - PagerTabStripDataSource // MARK: - PagerTabStripDataSource
override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
let child_1 = TableChildExampleViewController(style: .plain, itemInfo: IndicatorInfo(title: "FRIENDS")) let child_1 = TableChildExampleViewController(style: .plain, itemInfo: IndicatorInfo(title: "FRIENDS"))
child_1.blackTheme = true child_1.blackTheme = true
@ -63,15 +63,10 @@ class SpotifyExampleViewController: ButtonBarPagerTabStripViewController {
child_2.blackTheme = true child_2.blackTheme = true
return [child_1, child_2] return [child_1, child_2]
} }
// MARK: - Actions // MARK: - Actions
@IBAction func closeAction(_ sender: UIButton) { @IBAction func closeAction(_ sender: UIButton) {
dismiss(animated: true, completion: nil) dismiss(animated: true, completion: nil)
} }
} }

View File

@ -1,7 +1,7 @@
// TwitterExampleViewController.swift // TwitterExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -27,9 +27,9 @@ import XLPagerTabStrip
class TwitterExampleViewController: TwitterPagerTabStripViewController { class TwitterExampleViewController: TwitterPagerTabStripViewController {
var isReload = false var isReload = false
override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "TableView") let child_1 = TableChildExampleViewController(style: .plain, itemInfo: "TableView")
let child_2 = ChildExampleViewController(itemInfo: "View") let child_2 = ChildExampleViewController(itemInfo: "View")
let child_3 = TableChildExampleViewController(style: .grouped, itemInfo: "TableView 2") let child_3 = TableChildExampleViewController(style: .grouped, itemInfo: "TableView 2")
@ -38,24 +38,24 @@ class TwitterExampleViewController: TwitterPagerTabStripViewController {
let child_6 = ChildExampleViewController(itemInfo: "View 3") let child_6 = ChildExampleViewController(itemInfo: "View 3")
let child_7 = TableChildExampleViewController(style: .grouped, itemInfo: "TableView 4") let child_7 = TableChildExampleViewController(style: .grouped, itemInfo: "TableView 4")
let child_8 = ChildExampleViewController(itemInfo: "View 4") let child_8 = ChildExampleViewController(itemInfo: "View 4")
guard isReload else { guard isReload else {
return [child_1, child_2, child_3, child_4, child_5, child_6, child_7, child_8] return [child_1, child_2, child_3, child_4, child_5, child_6, child_7, child_8]
} }
var childViewControllers = [child_1, child_2, child_3, child_4, child_6, child_7, child_8] var childViewControllers = [child_1, child_2, child_3, child_4, child_5, child_6, child_7, child_8]
for (index, _) in childViewControllers.enumerated(){ for index in childViewControllers.indices {
let nElements = childViewControllers.count - index let nElements = childViewControllers.count - index
let n = (Int(arc4random()) % nElements) + index let n = (Int(arc4random()) % nElements) + index
if n != index{ if n != index {
swap(&childViewControllers[index], &childViewControllers[n]) childViewControllers.swapAt(index, n)
} }
} }
let nItems = 1 + (arc4random() % 8) let nItems = 1 + (arc4random() % 8)
return Array(childViewControllers.prefix(Int(nItems))) return Array(childViewControllers.prefix(Int(nItems)))
} }
@IBAction func reloadTapped(_ sender: AnyObject) { @IBAction func reloadTapped(_ sender: AnyObject) {
isReload = true isReload = true
reloadPagerTabStripView() reloadPagerTabStripView()

View File

@ -1,7 +1,7 @@
// YoutubeExampleViewController.swift // YoutubeExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -30,19 +30,18 @@ class YoutubeExampleViewController: BaseButtonBarPagerTabStripViewController<You
let redColor = UIColor(red: 221/255.0, green: 0/255.0, blue: 19/255.0, alpha: 1.0) let redColor = UIColor(red: 221/255.0, green: 0/255.0, blue: 19/255.0, alpha: 1.0)
let unselectedIconColor = UIColor(red: 73/255.0, green: 8/255.0, blue: 10/255.0, alpha: 1.0) let unselectedIconColor = UIColor(red: 73/255.0, green: 8/255.0, blue: 10/255.0, alpha: 1.0)
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
} }
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) super.init(coder: aDecoder)
buttonBarItemSpec = ButtonBarItemSpec.nibFile(nibName: "YoutubeIconCell", bundle: Bundle(for: YoutubeIconCell.self), width: { (cell: IndicatorInfo) -> CGFloat in buttonBarItemSpec = ButtonBarItemSpec.nibFile(nibName: "YoutubeIconCell", bundle: Bundle(for: YoutubeIconCell.self), width: { _ in
return 55.0 return 55.0
}) })
} }
override func viewDidLoad() { override func viewDidLoad() {
// change selected bar color // change selected bar color
settings.style.buttonBarBackgroundColor = redColor settings.style.buttonBarBackgroundColor = redColor
@ -51,56 +50,47 @@ class YoutubeExampleViewController: BaseButtonBarPagerTabStripViewController<You
settings.style.selectedBarHeight = 4.0 settings.style.selectedBarHeight = 4.0
settings.style.buttonBarMinimumLineSpacing = 0 settings.style.buttonBarMinimumLineSpacing = 0
settings.style.buttonBarItemTitleColor = .black settings.style.buttonBarItemTitleColor = .black
settings.style.buttonBarItemsShouldFillAvailiableWidth = true settings.style.buttonBarItemsShouldFillAvailableWidth = true
settings.style.buttonBarLeftContentInset = 0 settings.style.buttonBarLeftContentInset = 0
settings.style.buttonBarRightContentInset = 0 settings.style.buttonBarRightContentInset = 0
changeCurrentIndexProgressive = { [weak self] (oldCell: YoutubeIconCell?, newCell: YoutubeIconCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in changeCurrentIndexProgressive = { [weak self] (oldCell: YoutubeIconCell?, newCell: YoutubeIconCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in
guard changeCurrentIndex == true else { return } guard changeCurrentIndex == true else { return }
oldCell?.iconImage.tintColor = self?.unselectedIconColor oldCell?.iconImage.tintColor = self?.unselectedIconColor
newCell?.iconImage.tintColor = .white newCell?.iconImage.tintColor = .white
} }
super.viewDidLoad() super.viewDidLoad()
navigationController?.navigationBar.shadowImage = UIImage() navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
} }
// MARK: - PagerTabStripDataSource // MARK: - PagerTabStripDataSource
override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
let child_1 = TableChildExampleViewController(style: .plain, itemInfo: IndicatorInfo(title: " HOME", image: UIImage(named: "home"))) let child_1 = TableChildExampleViewController(style: .plain, itemInfo: IndicatorInfo(title: " HOME", image: UIImage(named: "home")))
let child_2 = TableChildExampleViewController(style: .plain, itemInfo: IndicatorInfo(title: " TRENDING", image: UIImage(named: "trending"))) let child_2 = TableChildExampleViewController(style: .plain, itemInfo: IndicatorInfo(title: " TRENDING", image: UIImage(named: "trending")))
let child_3 = ChildExampleViewController(itemInfo: IndicatorInfo(title: " ACCOUNT", image: UIImage(named: "profile"))) let child_3 = ChildExampleViewController(itemInfo: IndicatorInfo(title: " ACCOUNT", image: UIImage(named: "profile")))
return [child_1, child_2, child_3] return [child_1, child_2, child_3]
} }
override func configure(cell: YoutubeIconCell, for indicatorInfo: IndicatorInfo) { override func configure(cell: YoutubeIconCell, for indicatorInfo: IndicatorInfo) {
cell.iconImage.image = indicatorInfo.image?.withRenderingMode(.alwaysTemplate) cell.iconImage.image = indicatorInfo.image?.withRenderingMode(.alwaysTemplate)
} }
override func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) { override func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) {
super.updateIndicator(for: viewController, fromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: progressPercentage, indexWasChanged: indexWasChanged) super.updateIndicator(for: viewController, fromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: progressPercentage, indexWasChanged: indexWasChanged)
if indexWasChanged && toIndex > -1 && toIndex < viewControllers.count { if indexWasChanged && toIndex > -1 && toIndex < viewControllers.count {
let child = viewControllers[toIndex] as! IndicatorInfoProvider let child = viewControllers[toIndex] as! IndicatorInfoProvider // swiftlint:disable:this force_cast
UIView.performWithoutAnimation({ [weak self] () -> Void in UIView.performWithoutAnimation({ [weak self] () -> Void in
guard let me = self else { return } guard let me = self else { return }
me.navigationItem.leftBarButtonItem?.title = child.indicatorInfo(for: me).title me.navigationItem.leftBarButtonItem?.title = child.indicatorInfo(for: me).title
}) })
} }
} }
// MARK: - Actions // MARK: - Actions
@IBAction func closeAction(_ sender: UIButton) { @IBAction func closeAction(_ sender: UIButton) {
dismiss(animated: true, completion: nil) dismiss(animated: true, completion: nil)
} }
} }

View File

@ -1,7 +1,7 @@
// YoutubeIconCell.swift // YoutubeIconCell.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -25,9 +25,8 @@
import Foundation import Foundation
import UIKit import UIKit
class YoutubeIconCell: UICollectionViewCell {
class YoutubeIconCell : UICollectionViewCell {
@IBOutlet weak var iconImage: UIImageView! @IBOutlet weak var iconImage: UIImageView!
} }

View File

@ -0,0 +1,33 @@
// YoutubeIconWithLabelCell.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
//
// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
import UIKit
class YoutubeIconWithLabelCell: UICollectionViewCell {
@IBOutlet weak var iconImage: UIImageView!
@IBOutlet weak var iconLabel: UILabel!
}

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="2CI-9N-dP3" customClass="YoutubeIconWithLabelCell" customModule="Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="74" height="70"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="74" height="70"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Tkn-VR-o25">
<rect key="frame" x="20" y="10" width="35" height="35"/>
<constraints>
<constraint firstAttribute="width" constant="35" id="EUF-rI-9Y8"/>
<constraint firstAttribute="height" constant="35" id="RoA-LT-AHV"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rwk-fy-4KB">
<rect key="frame" x="0.0" y="45" width="74" height="20"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="kWi-HY-P6M"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="10"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
<constraints>
<constraint firstItem="rwk-fy-4KB" firstAttribute="top" secondItem="Tkn-VR-o25" secondAttribute="bottom" id="A8G-Sk-d4C"/>
<constraint firstItem="Tkn-VR-o25" firstAttribute="top" secondItem="2CI-9N-dP3" secondAttribute="top" constant="10" id="DaW-j3-w2g"/>
<constraint firstItem="rwk-fy-4KB" firstAttribute="leading" secondItem="2CI-9N-dP3" secondAttribute="leading" id="HFm-qh-fCk"/>
<constraint firstAttribute="bottom" secondItem="rwk-fy-4KB" secondAttribute="bottom" constant="5" id="Q0g-pb-bbf"/>
<constraint firstAttribute="trailing" secondItem="rwk-fy-4KB" secondAttribute="trailing" id="YuE-x9-9EY"/>
<constraint firstItem="Tkn-VR-o25" firstAttribute="centerX" secondItem="2CI-9N-dP3" secondAttribute="centerX" id="wav-eA-a2N"/>
</constraints>
<size key="customSize" width="74" height="50"/>
<connections>
<outlet property="iconImage" destination="Tkn-VR-o25" id="7DO-mm-BJX"/>
<outlet property="iconLabel" destination="rwk-fy-4KB" id="76s-nG-weE"/>
</connections>
<point key="canvasLocation" x="317" y="376"/>
</collectionViewCell>
</objects>
</document>

View File

@ -0,0 +1,99 @@
// YoutubeWithLabelExampleViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
//
// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
import XLPagerTabStrip
class YoutubeWithLabelExampleViewController: BaseButtonBarPagerTabStripViewController<YoutubeIconWithLabelCell> {
let redColor = UIColor(red: 221/255.0, green: 0/255.0, blue: 19/255.0, alpha: 1.0)
let unselectedIconColor = UIColor(red: 73/255.0, green: 8/255.0, blue: 10/255.0, alpha: 1.0)
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
buttonBarItemSpec = ButtonBarItemSpec.nibFile(nibName: "YoutubeIconWithLabelCell", bundle: Bundle(for: YoutubeIconWithLabelCell.self), width: { _ in
return 70.0
})
}
override func viewDidLoad() {
// change selected bar color
settings.style.buttonBarBackgroundColor = redColor
settings.style.buttonBarItemBackgroundColor = .clear
settings.style.selectedBarBackgroundColor = UIColor(red: 234/255.0, green: 234/255.0, blue: 234/255.0, alpha: 1.0)
settings.style.selectedBarHeight = 4.0
settings.style.buttonBarMinimumLineSpacing = 0
settings.style.buttonBarItemTitleColor = .black
settings.style.buttonBarItemsShouldFillAvailableWidth = true
settings.style.buttonBarLeftContentInset = 0
settings.style.buttonBarRightContentInset = 0
changeCurrentIndexProgressive = { [weak self] (oldCell: YoutubeIconWithLabelCell?, newCell: YoutubeIconWithLabelCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in
guard changeCurrentIndex == true else { return }
oldCell?.iconImage.tintColor = self?.unselectedIconColor
oldCell?.iconLabel.textColor = self?.unselectedIconColor
newCell?.iconImage.tintColor = .white
newCell?.iconLabel.textColor = .white
}
super.viewDidLoad()
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
}
// MARK: - PagerTabStripDataSource
override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
let child_1 = TableChildExampleViewController(style: .plain, itemInfo: IndicatorInfo(title: " HOME", image: UIImage(named: "home")))
let child_2 = TableChildExampleViewController(style: .plain, itemInfo: IndicatorInfo(title: " TRENDING", image: UIImage(named: "trending")))
let child_3 = ChildExampleViewController(itemInfo: IndicatorInfo(title: " ACCOUNT", image: UIImage(named: "profile")))
return [child_1, child_2, child_3]
}
override func configure(cell: YoutubeIconWithLabelCell, for indicatorInfo: IndicatorInfo) {
cell.iconImage.image = indicatorInfo.image?.withRenderingMode(.alwaysTemplate)
cell.iconLabel.text = indicatorInfo.title?.trimmingCharacters(in: .whitespacesAndNewlines)
}
override func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) {
super.updateIndicator(for: viewController, fromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: progressPercentage, indexWasChanged: indexWasChanged)
if indexWasChanged && toIndex > -1 && toIndex < viewControllers.count {
let child = viewControllers[toIndex] as! IndicatorInfoProvider // swiftlint:disable:this force_cast
UIView.performWithoutAnimation({ [weak self] () -> Void in
guard let me = self else { return }
me.navigationItem.leftBarButtonItem?.title = child.indicatorInfo(for: me).title
})
}
}
// MARK: - Actions
@IBAction func closeAction(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
}

View File

@ -8,12 +8,12 @@
import XCTest import XCTest
class ExampleUITests: XCTestCase { class ExampleUITests: XCTestCase {
override func setUp() { override func setUp() {
super.setUp() super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class. // Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs. // In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false continueAfterFailure = false
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
@ -21,15 +21,15 @@ class ExampleUITests: XCTestCase {
// In UI tests its 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. // In UI tests its 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.
} }
override func tearDown() { override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class. // Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown() super.tearDown()
} }
func testExample() { func testExample() {
// Use recording to get started writing UI tests. // Use recording to get started writing UI tests.
// Use XCTAssert and related functions to verify your tests produce the correct results. // Use XCTAssert and related functions to verify your tests produce the correct results.
} }
} }

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016 Xmartlabs SRL Copyright (c) 2017 Xmartlabs SRL
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -10,4 +10,4 @@
import UIKit import UIKit
import XLPagerTabStrip import XLPagerTabStrip
var str = "Hello, playground" var helloWorld = "Hello, playground"

View File

@ -3,12 +3,13 @@
<p align="left"> <p align="left">
<a href="https://travis-ci.org/xmartlabs/XLPagerTabStrip"><img src="https://travis-ci.org/xmartlabs/XLPagerTabStrip.svg?branch=master" alt="Build status" /></a> <a href="https://travis-ci.org/xmartlabs/XLPagerTabStrip"><img src="https://travis-ci.org/xmartlabs/XLPagerTabStrip.svg?branch=master" alt="Build status" /></a>
<img src="https://img.shields.io/badge/platform-iOS-blue.svg?style=flat" alt="Platform iOS" /> <img src="https://img.shields.io/badge/platform-iOS-blue.svg?style=flat" alt="Platform iOS" />
<a href="https://developer.apple.com/swift"><img src="https://img.shields.io/badge/swift2-compatible-4BC51D.svg?style=flat" alt="Swift 2 compatible" /></a> <a href="https://developer.apple.com/swift"><img src="https://img.shields.io/badge/swift4-compatible-4BC51D.svg?style=flat" alt="Swift 3 compatible" /></a>
<a href="https://github.com/Carthage/Carthage"><img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat" alt="Carthage compatible" /></a> <a href="https://github.com/Carthage/Carthage"><img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat" alt="Carthage compatible" /></a>
<a href="https://cocoapods.org/pods/XLActionController"><img src="https://img.shields.io/badge/pod-6.0.0-blue.svg" alt="CocoaPods compatible" /></a> <a href="https://cocoapods.org/pods/XLPagerTabStrip"><img src="https://img.shields.io/cocoapods/v/XLPagerTabStrip.svg" alt="CocoaPods compatible" /></a>
<a href="https://raw.githubusercontent.com/xmartlabs/XLPagerTabStrip/master/LICENSE"><img src="http://img.shields.io/badge/license-MIT-blue.svg?style=flat" alt="License: MIT" /> <a href="https://raw.githubusercontent.com/xmartlabs/XLPagerTabStrip/master/LICENSE"><img src="http://img.shields.io/badge/license-MIT-blue.svg?style=flat" alt="License: MIT" />
<a href="https://codebeat.co/projects/github-com-xmartlabs-xlpagertabstrip"><img alt="codebeat badge" src="https://codebeat.co/badges/f32c9ad3-0aa1-4b40-a632-9421211bd39e" /></a>
</a> </a>
<!-- <a href="https://codebeat.co/projects/github-com-xmartlabs-xlpagertabstrip"><img alt="codebeat badge" src="https://codebeat.co/badges/f32c9ad3-0aa1-4b40-a632-9421211bd39e" /></a> -->
</p> </p>
Made with ❤️ by [XMARTLABS](http://xmartlabs.com). Made with ❤️ by [XMARTLABS](http://xmartlabs.com).
@ -126,6 +127,8 @@ class MyEmbeddedViewController: UITableViewController, IndicatorInfoProvider {
} }
``` ```
**For a detailed step by step guide about how to use the library, please check out this community [blog post](https://medium.com/michaeladeyeri/how-to-implement-android-like-tab-layouts-in-ios-using-swift-3-578516c3aa9).**
That's it! We're done! 🍻🍻 That's it! We're done! 🍻🍻
@ -142,26 +145,26 @@ public var pagerBehaviour: PagerTabStripBehaviour
```swift ```swift
public enum PagerTabStripBehaviour { public enum PagerTabStripBehaviour {
case Common(skipIntermediteViewControllers: Bool) case common(skipIntermediteViewControllers: Bool)
case Progressive(skipIntermediteViewControllers: Bool, elasticIndicatorLimit: Bool) case progressive(skipIntermediteViewControllers: Bool, elasticIndicatorLimit: Bool)
} }
``` ```
Default Values: Default Values:
```swift ```swift
// Twitter Type // Twitter Type
PagerTabStripBehaviour.Common(skipIntermediteViewControllers: true) PagerTabStripBehaviour.common(skipIntermediateViewControllers: true)
// Segmented Type // Segmented Type
PagerTabStripBehaviour.Common(skipIntermediteViewControllers: true) PagerTabStripBehaviour.common(skipIntermediateViewControllers: true)
// Bar Type // Bar Type
PagerTabStripBehaviour.Progressive(skipIntermediteViewControllers: true, elasticIndicatorLimit: true) PagerTabStripBehaviour.progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true)
// ButtonBar Type // ButtonBar Type
PagerTabStripBehaviour.Progressive(skipIntermediteViewControllers: true, elasticIndicatorLimit: true)` PagerTabStripBehaviour.progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true)
``` ```
As you might have noticed `Common` and `Progressive` enumeration cases has `skipIntermediteViewControllers` and `elasticIndicatorLimit` associated values. As you might have noticed `common` and `progressive` enumeration cases has `skipIntermediateViewControllers` and `elasticIndicatorLimit` associated values.
`skipIntermediteViewControllers` allows us to skip intermediate view controllers when a tab indicator is tapped. `skipIntermediateViewControllers` allows us to skip intermediate view controllers when a tab indicator is tapped.
`elasticIndicatorLimit` allows us to tension the indicator when we reach a limit, I mean when we try to move forward from last indicator or move back from first indicator. `elasticIndicatorLimit` allows us to tension the indicator when we reach a limit, I mean when we try to move forward from last indicator or move back from first indicator.
@ -201,12 +204,12 @@ settings.style.buttonBarLeftContentInset: CGFloat?
settings.style.buttonBarRightContentInset: CGFloat? settings.style.buttonBarRightContentInset: CGFloat?
// selected bar view is created programmatically so it's important to set up the following 2 properties properly // selected bar view is created programmatically so it's important to set up the following 2 properties properly
settings.style.selectedBarBackgroundColor = UIColor.blackColor() settings.style.selectedBarBackgroundColor = UIColor.black
settings.style.selectedBarHeight: CGFloat = 5 settings.style.selectedBarHeight: CGFloat = 5
// each buttonBar item is a UICollectionView cell of type ButtonBarViewCell // each buttonBar item is a UICollectionView cell of type ButtonBarViewCell
settings.style.buttonBarItemBackgroundColor: UIColor? settings.style.buttonBarItemBackgroundColor: UIColor?
settings.style.buttonBarItemFont = UIFont.systemFontOfSize(18) settings.style.buttonBarItemFont = UIFont.systemFont(ofSize: 18)
// helps to determine the cell width, it represent the space before and after the title label // helps to determine the cell width, it represent the space before and after the title label
settings.style.buttonBarItemLeftRightMargin: CGFloat = 8 settings.style.buttonBarItemLeftRightMargin: CGFloat = 8
settings.style.buttonBarItemTitleColor: UIColor? settings.style.buttonBarItemTitleColor: UIColor?
@ -220,7 +223,7 @@ public var buttonBarHeight: CGFloat?
```swift ```swift
override func viewDidLoad() { override func viewDidLoad() {
self.settings.style.selectedBarHeight = 2 self.settings.style.selectedBarHeight = 2
self.settings.style.selectedBarBackgroundColor = UIColor.whiteColor() self.settings.style.selectedBarBackgroundColor = UIColor.white
super.viewDidLoad() super.viewDidLoad()
} }
@ -242,17 +245,17 @@ changeCurrentIndexProgressive = { (oldCell: ButtonBarViewCell?, newCell: ButtonB
guard changeCurrentIndex == true else { return } guard changeCurrentIndex == true else { return }
oldCell?.label.textColor = UIColor(white: 1, alpha: 0.6) oldCell?.label.textColor = UIColor(white: 1, alpha: 0.6)
newCell?.label.textColor = .whiteColor() newCell?.label.textColor = UIColor.white
if animated { if animated {
UIView.animateWithDuration(0.1, animations: { () -> Void in UIView.animate(withDuration: 0.1, animations: { () -> Void in
newCell?.transform = CGAffineTransformMakeScale(1.0, 1.0) newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
oldCell?.transform = CGAffineTransformMakeScale(0.8, 0.8) oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
}) })
} }
else { else {
newCell?.transform = CGAffineTransformMakeScale(1.0, 1.0) newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
oldCell?.transform = CGAffineTransformMakeScale(0.8, 0.8) oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
} }
} }
``` ```
@ -270,10 +273,10 @@ settings.style.barHeight: CGFloat = 5
```swift ```swift
settings.style.dotColor = UIColor(white: 1, alpha: 0.4) settings.style.dotColor = UIColor(white: 1, alpha: 0.4)
settings.style.selectedDotColor = UIColor.whiteColor() settings.style.selectedDotColor = UIColor.white
settings.style.portraitTitleFont = UIFont.systemFontOfSize(18) settings.style.portraitTitleFont = UIFont.systemFont(ofSize: 18)
settings.style.landscapeTitleFont = UIFont.systemFontOfSize(15) settings.style.landscapeTitleFont = UIFont.systemFont(ofSize: 15)
settings.style.titleColor = UIColor.whiteColor() settings.style.titleColor = UIColor.white
``` ```
### Segmented Type Customization ### Segmented Type Customization
@ -287,7 +290,7 @@ settings.style.segmentedControlColor: UIColor?
## Requirements ## Requirements
* iOS 8.0+ * iOS 8.0+
* Xcode 7.3+ * Xcode 9.3+
## Examples ## Examples
@ -302,7 +305,7 @@ Follow these 3 steps to run Example project: Clone XLPagerTabStrip repository, o
To install XLPagerTabStrip, simply add the following line to your Podfile: To install XLPagerTabStrip, simply add the following line to your Podfile:
```ruby ```ruby
pod 'XLPagerTabStrip', '~> 6.0' pod 'XLPagerTabStrip', '~> 8.0'
``` ```
### Carthage ### Carthage
@ -312,7 +315,7 @@ pod 'XLPagerTabStrip', '~> 6.0'
To install XLPagerTabStrip, simply add the following line to your Cartfile: To install XLPagerTabStrip, simply add the following line to your Cartfile:
```ogdl ```ogdl
github "xmartlabs/XLPagerTabStrip" ~> 6.0 github "xmartlabs/XLPagerTabStrip" ~> 8.0
``` ```
## FAQ ## FAQ
@ -337,7 +340,6 @@ Check out [our migration guide](https://github.com/xmartlabs/XLPagerTabStrip/blo
* [Martin Barreto](https://github.com/mtnBarreto) ([@mtnBarreto](https://twitter.com/mtnBarreto)) * [Martin Barreto](https://github.com/mtnBarreto) ([@mtnBarreto](https://twitter.com/mtnBarreto))
## Change Log ## Change Log
This can be found in the [CHANGELOG.md](CHANGELOG.md) file. This can be found in the [CHANGELOG.md](CHANGELOG.md) file.

View File

@ -1,7 +1,7 @@
// BarPagerTabStripViewController.swift // BarPagerTabStripViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -26,34 +26,34 @@ import Foundation
import UIKit import UIKit
public struct BarPagerTabStripSettings { public struct BarPagerTabStripSettings {
public struct Style { public struct Style {
public var barBackgroundColor: UIColor? public var barBackgroundColor: UIColor?
public var selectedBarBackgroundColor: UIColor? public var selectedBarBackgroundColor: UIColor?
public var barHeight: CGFloat = 5 // barHeight is ony set up when the bar is created programatically and not using storyboards or xib files. public var barHeight: CGFloat = 5 // barHeight is ony set up when the bar is created programatically and not using storyboards or xib files.
} }
public var style = Style() public var style = Style()
} }
open class BarPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate { open class BarPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate {
public var settings = BarPagerTabStripSettings() public var settings = BarPagerTabStripSettings()
@IBOutlet weak public var barView: BarView! @IBOutlet weak public var barView: BarView!
required public init?(coder aDecoder: NSCoder) { required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) super.init(coder: aDecoder)
delegate = self delegate = self
datasource = self datasource = self
} }
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
delegate = self delegate = self
datasource = self datasource = self
} }
open override func viewDidLoad() { open override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
barView = barView ?? { barView = barView ?? {
@ -63,11 +63,11 @@ open class BarPagerTabStripViewController: PagerTabStripViewController, PagerTab
barView.selectedBar.backgroundColor = .white barView.selectedBar.backgroundColor = .white
return barView return barView
}() }()
barView.backgroundColor = settings.style.barBackgroundColor ?? barView.backgroundColor barView.backgroundColor = settings.style.barBackgroundColor ?? barView.backgroundColor
barView.selectedBar.backgroundColor = settings.style.selectedBarBackgroundColor ?? barView.selectedBar.backgroundColor barView.selectedBar.backgroundColor = settings.style.selectedBarBackgroundColor ?? barView.selectedBar.backgroundColor
} }
open override func viewWillAppear(_ animated: Bool) { open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
if barView.superview == nil { if barView.superview == nil {
@ -76,15 +76,15 @@ open class BarPagerTabStripViewController: PagerTabStripViewController, PagerTab
barView.optionsCount = viewControllers.count barView.optionsCount = viewControllers.count
barView.moveTo(index: currentIndex, animated: false) barView.moveTo(index: currentIndex, animated: false)
} }
open override func reloadPagerTabStripView() { open override func reloadPagerTabStripView() {
super.reloadPagerTabStripView() super.reloadPagerTabStripView()
barView.optionsCount = viewControllers.count barView.optionsCount = viewControllers.count
if isViewLoaded{ if isViewLoaded {
barView.moveTo(index: currentIndex, animated: false) barView.moveTo(index: currentIndex, animated: false)
} }
} }
// MARK: - PagerTabStripDelegate // MARK: - PagerTabStripDelegate
open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) { open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) {

View File

@ -1,7 +1,7 @@
// BarView.swift // BarView.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -25,12 +25,12 @@
import Foundation import Foundation
open class BarView: UIView { open class BarView: UIView {
open lazy var selectedBar: UIView = { [unowned self] in open lazy var selectedBar: UIView = { [unowned self] in
let selectedBar = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)) let selectedBar = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height))
return selectedBar return selectedBar
}() }()
var optionsCount = 1 { var optionsCount = 1 {
willSet(newOptionsCount) { willSet(newOptionsCount) {
if newOptionsCount <= selectedIndex { if newOptionsCount <= selectedIndex {
@ -39,20 +39,19 @@ open class BarView: UIView {
} }
} }
var selectedIndex = 0 var selectedIndex = 0
required public init?(coder aDecoder: NSCoder) { required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) super.init(coder: aDecoder)
addSubview(selectedBar) addSubview(selectedBar)
} }
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
addSubview(selectedBar) addSubview(selectedBar)
} }
// MARK: - Helpers // MARK: - Helpers
private func updateSelectedBarPosition(with animation: Bool) { private func updateSelectedBarPosition(with animation: Bool) {
var frame = selectedBar.frame var frame = selectedBar.frame
frame.size.width = self.frame.size.width / CGFloat(optionsCount) frame.size.width = self.frame.size.width / CGFloat(optionsCount)
@ -61,20 +60,19 @@ open class BarView: UIView {
UIView.animate(withDuration: 0.3, animations: { [weak self] in UIView.animate(withDuration: 0.3, animations: { [weak self] in
self?.selectedBar.frame = frame self?.selectedBar.frame = frame
}) })
} } else {
else{
selectedBar.frame = frame selectedBar.frame = frame
} }
} }
open func moveTo(index: Int, animated: Bool) { open func moveTo(index: Int, animated: Bool) {
selectedIndex = index selectedIndex = index
updateSelectedBarPosition(with: animated) updateSelectedBarPosition(with: animated)
} }
open func move(fromIndex: Int, toIndex: Int, progressPercentage: CGFloat) { open func move(fromIndex: Int, toIndex: Int, progressPercentage: CGFloat) {
selectedIndex = (progressPercentage > 0.5) ? toIndex : fromIndex selectedIndex = (progressPercentage > 0.5) ? toIndex : fromIndex
var newFrame = selectedBar.frame var newFrame = selectedBar.frame
newFrame.size.width = frame.size.width / CGFloat(optionsCount) newFrame.size.width = frame.size.width / CGFloat(optionsCount)
var fromFrame = newFrame var fromFrame = newFrame
@ -85,7 +83,7 @@ open class BarView: UIView {
targetFrame.origin.x += (toFrame.origin.x - targetFrame.origin.x) * CGFloat(progressPercentage) targetFrame.origin.x += (toFrame.origin.x - targetFrame.origin.x) * CGFloat(progressPercentage)
selectedBar.frame = targetFrame selectedBar.frame = targetFrame
} }
open override func layoutSubviews() { open override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
updateSelectedBarPosition(with: false) updateSelectedBarPosition(with: false)

View File

@ -1,7 +1,7 @@
// BaseButtonBarPagerTabStripViewController.swift // BaseButtonBarPagerTabStripViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -24,14 +24,13 @@
import Foundation import Foundation
open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollectionViewCell>: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate, UICollectionViewDelegate, UICollectionViewDataSource { open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType: UICollectionViewCell>: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate, UICollectionViewDelegate, UICollectionViewDataSource {
public var settings = ButtonBarPagerTabStripSettings() public var settings = ButtonBarPagerTabStripSettings()
public var buttonBarItemSpec: ButtonBarItemSpec<ButtonBarCellType>! public var buttonBarItemSpec: ButtonBarItemSpec<ButtonBarCellType>!
public var changeCurrentIndex: ((_ oldCell: ButtonBarCellType?, _ newCell: ButtonBarCellType?, _ animated: Bool) -> Void)? public var changeCurrentIndex: ((_ oldCell: ButtonBarCellType?, _ newCell: ButtonBarCellType?, _ animated: Bool) -> Void)?
public var changeCurrentIndexProgressive: ((_ oldCell: ButtonBarCellType?, _ newCell: ButtonBarCellType?, _ progressPercentage: CGFloat, _ changeCurrentIndex: Bool, _ animated: Bool) -> Void)? public var changeCurrentIndexProgressive: ((_ oldCell: ButtonBarCellType?, _ newCell: ButtonBarCellType?, _ progressPercentage: CGFloat, _ changeCurrentIndex: Bool, _ animated: Bool) -> Void)?
@IBOutlet public weak var buttonBarView: ButtonBarView! @IBOutlet public weak var buttonBarView: ButtonBarView!
lazy private var cachedCellWidths: [CGFloat]? = { [unowned self] in lazy private var cachedCellWidths: [CGFloat]? = { [unowned self] in
@ -52,10 +51,10 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
open override func viewDidLoad() { open override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
buttonBarView = buttonBarView ?? { let buttonBarViewAux = buttonBarView ?? {
let flowLayout = UICollectionViewFlowLayout() let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal flowLayout.scrollDirection = .horizontal
flowLayout.sectionInset = UIEdgeInsetsMake(0, settings.style.buttonBarLeftContentInset ?? 35, 0, settings.style.buttonBarRightContentInset ?? 35) flowLayout.sectionInset = UIEdgeInsets(top: 0, left: settings.style.buttonBarLeftContentInset ?? 35, bottom: 0, right: settings.style.buttonBarRightContentInset ?? 35)
let buttonBarHeight = settings.style.buttonBarHeight ?? 44 let buttonBarHeight = settings.style.buttonBarHeight ?? 44
let buttonBar = ButtonBarView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: buttonBarHeight), collectionViewLayout: flowLayout) let buttonBar = ButtonBarView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: buttonBarHeight), collectionViewLayout: flowLayout)
buttonBar.backgroundColor = .orange buttonBar.backgroundColor = .orange
@ -67,6 +66,8 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
containerView.frame = newContainerViewFrame containerView.frame = newContainerViewFrame
return buttonBar return buttonBar
}() }()
buttonBarView = buttonBarViewAux
if buttonBarView.superview == nil { if buttonBarView.superview == nil {
view.addSubview(buttonBarView) view.addSubview(buttonBarView)
} }
@ -77,12 +78,12 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
buttonBarView.dataSource = self buttonBarView.dataSource = self
} }
buttonBarView.scrollsToTop = false buttonBarView.scrollsToTop = false
let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast
flowLayout.scrollDirection = .horizontal flowLayout.scrollDirection = .horizontal
flowLayout.minimumInteritemSpacing = settings.style.buttonBarMinimumLineSpacing ?? flowLayout.minimumLineSpacing flowLayout.minimumInteritemSpacing = settings.style.buttonBarMinimumInteritemSpacing ?? flowLayout.minimumInteritemSpacing
flowLayout.minimumLineSpacing = settings.style.buttonBarMinimumLineSpacing ?? flowLayout.minimumLineSpacing flowLayout.minimumLineSpacing = settings.style.buttonBarMinimumLineSpacing ?? flowLayout.minimumLineSpacing
let sectionInset = flowLayout.sectionInset let sectionInset = flowLayout.sectionInset
flowLayout.sectionInset = UIEdgeInsetsMake(sectionInset.top, settings.style.buttonBarLeftContentInset ?? sectionInset.left, sectionInset.bottom, settings.style.buttonBarRightContentInset ?? sectionInset.right) flowLayout.sectionInset = UIEdgeInsets(top: sectionInset.top, left: settings.style.buttonBarLeftContentInset ?? sectionInset.left, bottom: sectionInset.bottom, right: settings.style.buttonBarRightContentInset ?? sectionInset.right)
buttonBarView.showsHorizontalScrollIndicator = false buttonBarView.showsHorizontalScrollIndicator = false
buttonBarView.backgroundColor = settings.style.buttonBarBackgroundColor ?? buttonBarView.backgroundColor buttonBarView.backgroundColor = settings.style.buttonBarBackgroundColor ?? buttonBarView.backgroundColor
buttonBarView.selectedBar.backgroundColor = settings.style.selectedBarBackgroundColor buttonBarView.selectedBar.backgroundColor = settings.style.selectedBarBackgroundColor
@ -130,6 +131,7 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
// selectedBar is resized and its contentOffset/scroll is set correctly (the selected // selectedBar is resized and its contentOffset/scroll is set correctly (the selected
// tab/cell may end up either skewed or off screen after a rotation otherwise) // tab/cell may end up either skewed or off screen after a rotation otherwise)
buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .scrollOnlyIfOutOfScreen) buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .scrollOnlyIfOutOfScreen)
buttonBarView.selectItem(at: IndexPath(item: currentIndex, section: 0), animated: false, scrollPosition: [])
} }
// MARK: - View Rotation // MARK: - View Rotation
@ -152,16 +154,14 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
var numberOfLargeCells = 0 var numberOfLargeCells = 0
var totalWidthOfLargeCells: CGFloat = 0 var totalWidthOfLargeCells: CGFloat = 0
for minimumCellWidthValue in minimumCellWidths { for minimumCellWidthValue in minimumCellWidths where minimumCellWidthValue > suggestedStretchedCellWidth {
if minimumCellWidthValue > suggestedStretchedCellWidth { totalWidthOfLargeCells += minimumCellWidthValue
totalWidthOfLargeCells += minimumCellWidthValue numberOfLargeCells += 1
numberOfLargeCells += 1
}
} }
guard numberOfLargeCells > previousNumberOfLargeCells else { return suggestedStretchedCellWidth } guard numberOfLargeCells > previousNumberOfLargeCells else { return suggestedStretchedCellWidth }
let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast
let collectionViewAvailiableWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right let collectionViewAvailiableWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right
let numberOfCells = minimumCellWidths.count let numberOfCells = minimumCellWidths.count
let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumLineSpacing let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumLineSpacing
@ -195,7 +195,7 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
// MARK: - UICollectionViewDelegateFlowLayut // MARK: - UICollectionViewDelegateFlowLayut
open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize { @objc open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
guard let cellWidthValue = cachedCellWidths?[indexPath.row] else { guard let cellWidthValue = cachedCellWidths?[indexPath.row] else {
fatalError("cachedCellWidths for \(indexPath.row) must not be nil") fatalError("cachedCellWidths for \(indexPath.row) must not be nil")
} }
@ -214,8 +214,7 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { if let changeCurrentIndexProgressive = changeCurrentIndexProgressive {
changeCurrentIndexProgressive(oldCell, newCell, 1, true, true) changeCurrentIndexProgressive(oldCell, newCell, 1, true, true)
} }
} } else {
else {
if let changeCurrentIndex = changeCurrentIndex { if let changeCurrentIndex = changeCurrentIndex {
changeCurrentIndex(oldCell, newCell, true) changeCurrentIndex(oldCell, newCell, true)
} }
@ -233,7 +232,7 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? ButtonBarCellType else { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? ButtonBarCellType else {
fatalError("UICollectionViewCell should be or extend from ButtonBarViewCell") fatalError("UICollectionViewCell should be or extend from ButtonBarViewCell")
} }
let childController = viewControllers[indexPath.item] as! IndicatorInfoProvider let childController = viewControllers[indexPath.item] as! IndicatorInfoProvider // swiftlint:disable:this force_cast
let indicatorInfo = childController.indicatorInfo(for: self) let indicatorInfo = childController.indicatorInfo(for: self)
configure(cell: cell, for: indicatorInfo) configure(cell: cell, for: indicatorInfo)
@ -242,8 +241,7 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { if let changeCurrentIndexProgressive = changeCurrentIndexProgressive {
changeCurrentIndexProgressive(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, 1, true, false) changeCurrentIndexProgressive(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, 1, true, false)
} }
} } else {
else {
if let changeCurrentIndex = changeCurrentIndex { if let changeCurrentIndex = changeCurrentIndex {
changeCurrentIndex(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, false) changeCurrentIndex(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, false)
} }
@ -261,19 +259,19 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
shouldUpdateButtonBarView = true shouldUpdateButtonBarView = true
} }
open func configure(cell: ButtonBarCellType, for indicatorInfo: IndicatorInfo){ open func configure(cell: ButtonBarCellType, for indicatorInfo: IndicatorInfo) {
fatalError("You must override this method to set up ButtonBarView cell accordingly") fatalError("You must override this method to set up ButtonBarView cell accordingly")
} }
private func calculateWidths() -> [CGFloat] { private func calculateWidths() -> [CGFloat] {
let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast
let numberOfCells = viewControllers.count let numberOfCells = viewControllers.count
var minimumCellWidths = [CGFloat]() var minimumCellWidths = [CGFloat]()
var collectionViewContentWidth: CGFloat = 0 var collectionViewContentWidth: CGFloat = 0
for viewController in viewControllers { for viewController in viewControllers {
let childController = viewController as! IndicatorInfoProvider let childController = viewController as! IndicatorInfoProvider // swiftlint:disable:this force_cast
let indicatorInfo = childController.indicatorInfo(for: self) let indicatorInfo = childController.indicatorInfo(for: self)
switch buttonBarItemSpec! { switch buttonBarItemSpec! {
case .cellClass(let widthCallback): case .cellClass(let widthCallback):
@ -292,10 +290,9 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
let collectionViewAvailableVisibleWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right let collectionViewAvailableVisibleWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right
if !settings.style.buttonBarItemsShouldFillAvailiableWidth || collectionViewAvailableVisibleWidth < collectionViewContentWidth { if !settings.style.buttonBarItemsShouldFillAvailableWidth || collectionViewAvailableVisibleWidth < collectionViewContentWidth {
return minimumCellWidths return minimumCellWidths
} } else {
else {
let stretchedCellWidthIfAllEqual = (collectionViewAvailableVisibleWidth - cellSpacingTotal) / CGFloat(numberOfCells) let stretchedCellWidthIfAllEqual = (collectionViewAvailableVisibleWidth - cellSpacingTotal) / CGFloat(numberOfCells)
let generalMinimumCellWidth = calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: stretchedCellWidthIfAllEqual, previousNumberOfLargeCells: 0) let generalMinimumCellWidth = calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: stretchedCellWidthIfAllEqual, previousNumberOfLargeCells: 0)
var stretchedCellWidths = [CGFloat]() var stretchedCellWidths = [CGFloat]()
@ -312,7 +309,6 @@ open class BaseButtonBarPagerTabStripViewController<ButtonBarCellType : UICollec
private var shouldUpdateButtonBarView = true private var shouldUpdateButtonBarView = true
} }
open class ExampleBaseButtonBarPagerTabStripViewController: BaseButtonBarPagerTabStripViewController<ButtonBarViewCell> { open class ExampleBaseButtonBarPagerTabStripViewController: BaseButtonBarPagerTabStripViewController<ButtonBarViewCell> {
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
@ -325,8 +321,15 @@ open class ExampleBaseButtonBarPagerTabStripViewController: BaseButtonBarPagerTa
initialize() initialize()
} }
open func initialize(){ open func initialize() {
buttonBarItemSpec = .nibFile(nibName: "ButtonCell", bundle: Bundle(for: ButtonBarViewCell.self), width:{ [weak self] (childItemInfo) -> CGFloat in var bundle = Bundle(for: ButtonBarViewCell.self)
if let resourcePath = bundle.path(forResource: "XLPagerTabStrip", ofType: "bundle") {
if let resourcesBundle = Bundle(path: resourcePath) {
bundle = resourcesBundle
}
}
buttonBarItemSpec = .nibFile(nibName: "ButtonCell", bundle: bundle, width: { [weak self] (childItemInfo) -> CGFloat in
let label = UILabel() let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false label.translatesAutoresizingMaskIntoConstraints = false
label.font = self?.settings.style.buttonBarItemFont ?? label.font label.font = self?.settings.style.buttonBarItemFont ?? label.font
@ -336,8 +339,9 @@ open class ExampleBaseButtonBarPagerTabStripViewController: BaseButtonBarPagerTa
}) })
} }
open override func configure(cell: ButtonBarViewCell, for indicatorInfo: IndicatorInfo){ open override func configure(cell: ButtonBarViewCell, for indicatorInfo: IndicatorInfo) {
cell.label.text = indicatorInfo.title cell.label.text = indicatorInfo.title
cell.accessibilityLabel = indicatorInfo.accessibilityLabel
if let image = indicatorInfo.image { if let image = indicatorInfo.image {
cell.imageView.image = image cell.imageView.image = image
} }

View File

@ -1,7 +1,7 @@
// ButtonBarPagerTabStripViewController.swift // ButtonBarPagerTabStripViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -25,10 +25,10 @@
import Foundation import Foundation
public enum ButtonBarItemSpec<CellType: UICollectionViewCell> { public enum ButtonBarItemSpec<CellType: UICollectionViewCell> {
case nibFile(nibName: String, bundle: Bundle?, width:((IndicatorInfo)-> CGFloat)) case nibFile(nibName: String, bundle: Bundle?, width:((IndicatorInfo)-> CGFloat))
case cellClass(width:((IndicatorInfo)-> CGFloat)) case cellClass(width:((IndicatorInfo)-> CGFloat))
public var weight: ((IndicatorInfo) -> CGFloat) { public var weight: ((IndicatorInfo) -> CGFloat) {
switch self { switch self {
case .cellClass(let widthCallback): case .cellClass(let widthCallback):
@ -40,45 +40,53 @@ public enum ButtonBarItemSpec<CellType: UICollectionViewCell> {
} }
public struct ButtonBarPagerTabStripSettings { public struct ButtonBarPagerTabStripSettings {
public struct Style { public struct Style {
public var buttonBarBackgroundColor: UIColor? public var buttonBarBackgroundColor: UIColor?
@available(*, deprecated: 4.0.2) public var buttonBarMinimumInteritemSpacing: CGFloat? = 0 public var buttonBarMinimumInteritemSpacing: CGFloat?
public var buttonBarMinimumLineSpacing: CGFloat? public var buttonBarMinimumLineSpacing: CGFloat?
public var buttonBarLeftContentInset: CGFloat? public var buttonBarLeftContentInset: CGFloat?
public var buttonBarRightContentInset: CGFloat? public var buttonBarRightContentInset: CGFloat?
public var selectedBarBackgroundColor = UIColor.black public var selectedBarBackgroundColor = UIColor.black
public var selectedBarHeight: CGFloat = 5 public var selectedBarHeight: CGFloat = 5
public var selectedBarVerticalAlignment: SelectedBarVerticalAlignment = .bottom
public var buttonBarItemBackgroundColor: UIColor? public var buttonBarItemBackgroundColor: UIColor?
public var buttonBarItemFont = UIFont.systemFont(ofSize: 18) public var buttonBarItemFont = UIFont.systemFont(ofSize: 18)
public var buttonBarItemLeftRightMargin: CGFloat = 8 public var buttonBarItemLeftRightMargin: CGFloat = 8
public var buttonBarItemTitleColor: UIColor? public var buttonBarItemTitleColor: UIColor?
public var buttonBarItemsShouldFillAvailiableWidth = true @available(*, deprecated: 7.0.0) public var buttonBarItemsShouldFillAvailiableWidth: Bool {
set {
buttonBarItemsShouldFillAvailableWidth = newValue
}
get {
return buttonBarItemsShouldFillAvailableWidth
}
}
public var buttonBarItemsShouldFillAvailableWidth = true
// only used if button bar is created programaticaly and not using storyboards or nib files // only used if button bar is created programaticaly and not using storyboards or nib files
public var buttonBarHeight: CGFloat? public var buttonBarHeight: CGFloat?
} }
public var style = Style() public var style = Style()
} }
open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate, UICollectionViewDelegate, UICollectionViewDataSource { open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate, UICollectionViewDelegate, UICollectionViewDataSource {
public var settings = ButtonBarPagerTabStripSettings() public var settings = ButtonBarPagerTabStripSettings()
public var buttonBarItemSpec: ButtonBarItemSpec<ButtonBarViewCell>! public var buttonBarItemSpec: ButtonBarItemSpec<ButtonBarViewCell>!
public var changeCurrentIndex: ((_ oldCell: ButtonBarViewCell?, _ newCell: ButtonBarViewCell?, _ animated: Bool) -> Void)? public var changeCurrentIndex: ((_ oldCell: ButtonBarViewCell?, _ newCell: ButtonBarViewCell?, _ animated: Bool) -> Void)?
public var changeCurrentIndexProgressive: ((_ oldCell: ButtonBarViewCell?, _ newCell: ButtonBarViewCell?, _ progressPercentage: CGFloat, _ changeCurrentIndex: Bool, _ animated: Bool) -> Void)? public var changeCurrentIndexProgressive: ((_ oldCell: ButtonBarViewCell?, _ newCell: ButtonBarViewCell?, _ progressPercentage: CGFloat, _ changeCurrentIndex: Bool, _ animated: Bool) -> Void)?
@IBOutlet public weak var buttonBarView: ButtonBarView! @IBOutlet public weak var buttonBarView: ButtonBarView!
lazy private var cachedCellWidths: [CGFloat]? = { [unowned self] in lazy private var cachedCellWidths: [CGFloat]? = { [unowned self] in
return self.calculateWidths() return self.calculateWidths()
}() }()
override public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { override public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
delegate = self delegate = self
@ -90,10 +98,18 @@ open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, Pa
delegate = self delegate = self
datasource = self datasource = self
} }
open override func viewDidLoad() { open override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
buttonBarItemSpec = .nibFile(nibName: "ButtonCell", bundle: Bundle(for: ButtonBarViewCell.self), width:{ [weak self] (childItemInfo) -> CGFloat in
var bundle = Bundle(for: ButtonBarViewCell.self)
if let resourcePath = bundle.path(forResource: "XLPagerTabStrip", ofType: "bundle") {
if let resourcesBundle = Bundle(path: resourcePath) {
bundle = resourcesBundle
}
}
buttonBarItemSpec = .nibFile(nibName: "ButtonCell", bundle: bundle, width: { [weak self] (childItemInfo) -> CGFloat in
let label = UILabel() let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false label.translatesAutoresizingMaskIntoConstraints = false
label.font = self?.settings.style.buttonBarItemFont label.font = self?.settings.style.buttonBarItemFont
@ -101,8 +117,7 @@ open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, Pa
let labelSize = label.intrinsicContentSize let labelSize = label.intrinsicContentSize
return labelSize.width + (self?.settings.style.buttonBarItemLeftRightMargin ?? 8) * 2 return labelSize.width + (self?.settings.style.buttonBarItemLeftRightMargin ?? 8) * 2
}) })
let buttonBarViewAux = buttonBarView ?? { let buttonBarViewAux = buttonBarView ?? {
let flowLayout = UICollectionViewFlowLayout() let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal flowLayout.scrollDirection = .horizontal
@ -118,7 +133,7 @@ open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, Pa
return buttonBar return buttonBar
}() }()
buttonBarView = buttonBarViewAux buttonBarView = buttonBarViewAux
if buttonBarView.superview == nil { if buttonBarView.superview == nil {
view.addSubview(buttonBarView) view.addSubview(buttonBarView)
} }
@ -129,18 +144,20 @@ open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, Pa
buttonBarView.dataSource = self buttonBarView.dataSource = self
} }
buttonBarView.scrollsToTop = false buttonBarView.scrollsToTop = false
let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast
flowLayout.scrollDirection = .horizontal flowLayout.scrollDirection = .horizontal
flowLayout.minimumInteritemSpacing = 0 flowLayout.minimumInteritemSpacing = settings.style.buttonBarMinimumInteritemSpacing ?? flowLayout.minimumInteritemSpacing
flowLayout.minimumLineSpacing = settings.style.buttonBarMinimumLineSpacing ?? flowLayout.minimumLineSpacing flowLayout.minimumLineSpacing = settings.style.buttonBarMinimumLineSpacing ?? flowLayout.minimumLineSpacing
let sectionInset = flowLayout.sectionInset let sectionInset = flowLayout.sectionInset
flowLayout.sectionInset = UIEdgeInsetsMake(sectionInset.top, settings.style.buttonBarLeftContentInset ?? sectionInset.left, sectionInset.bottom, settings.style.buttonBarRightContentInset ?? sectionInset.right) flowLayout.sectionInset = UIEdgeInsets(top: sectionInset.top, left: settings.style.buttonBarLeftContentInset ?? sectionInset.left, bottom: sectionInset.bottom, right: settings.style.buttonBarRightContentInset ?? sectionInset.right)
buttonBarView.showsHorizontalScrollIndicator = false buttonBarView.showsHorizontalScrollIndicator = false
buttonBarView.backgroundColor = settings.style.buttonBarBackgroundColor ?? buttonBarView.backgroundColor buttonBarView.backgroundColor = settings.style.buttonBarBackgroundColor ?? buttonBarView.backgroundColor
buttonBarView.selectedBar.backgroundColor = settings.style.selectedBarBackgroundColor buttonBarView.selectedBar.backgroundColor = settings.style.selectedBarBackgroundColor
buttonBarView.selectedBarHeight = settings.style.selectedBarHeight buttonBarView.selectedBarHeight = settings.style.selectedBarHeight
buttonBarView.selectedBarVerticalAlignment = settings.style.selectedBarVerticalAlignment
// register button bar item cell // register button bar item cell
switch buttonBarItemSpec! { switch buttonBarItemSpec! {
case .nibFile(let nibName, let bundle, _): case .nibFile(let nibName, let bundle, _):
@ -150,17 +167,17 @@ open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, Pa
} }
//- //-
} }
open override func viewWillAppear(_ animated: Bool) { open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
buttonBarView.layoutIfNeeded() buttonBarView.layoutIfNeeded()
} }
open override func viewDidLayoutSubviews() { open override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
guard isViewAppearing || isViewRotating else { return } guard isViewAppearing || isViewRotating else { return }
// Force the UICollectionViewFlowLayout to get laid out again with the new size if // Force the UICollectionViewFlowLayout to get laid out again with the new size if
// a) The view is appearing. This ensures that // a) The view is appearing. This ensures that
// collectionView:layout:sizeForItemAtIndexPath: is called for a second time // collectionView:layout:sizeForItemAtIndexPath: is called for a second time
@ -177,10 +194,11 @@ open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, Pa
// selectedBar is resized and its contentOffset/scroll is set correctly (the selected // selectedBar is resized and its contentOffset/scroll is set correctly (the selected
// tab/cell may end up either skewed or off screen after a rotation otherwise) // tab/cell may end up either skewed or off screen after a rotation otherwise)
buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .scrollOnlyIfOutOfScreen) buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .scrollOnlyIfOutOfScreen)
buttonBarView.selectItem(at: IndexPath(item: currentIndex, section: 0), animated: false, scrollPosition: [])
} }
// MARK: - Public Methods // MARK: - Public Methods
open override func reloadPagerTabStripView() { open override func reloadPagerTabStripView() {
super.reloadPagerTabStripView() super.reloadPagerTabStripView()
guard isViewLoaded else { return } guard isViewLoaded else { return }
@ -188,37 +206,39 @@ open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, Pa
cachedCellWidths = calculateWidths() cachedCellWidths = calculateWidths()
buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .yes) buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .yes)
} }
open func calculateStretchedCellWidths(_ minimumCellWidths: [CGFloat], suggestedStretchedCellWidth: CGFloat, previousNumberOfLargeCells: Int) -> CGFloat { open func calculateStretchedCellWidths(_ minimumCellWidths: [CGFloat], suggestedStretchedCellWidth: CGFloat, previousNumberOfLargeCells: Int) -> CGFloat {
var numberOfLargeCells = 0 var numberOfLargeCells = 0
var totalWidthOfLargeCells: CGFloat = 0 var totalWidthOfLargeCells: CGFloat = 0
for minimumCellWidthValue in minimumCellWidths where minimumCellWidthValue > suggestedStretchedCellWidth { for minimumCellWidthValue in minimumCellWidths where minimumCellWidthValue > suggestedStretchedCellWidth {
totalWidthOfLargeCells += minimumCellWidthValue totalWidthOfLargeCells += minimumCellWidthValue
numberOfLargeCells += 1 numberOfLargeCells += 1
} }
guard numberOfLargeCells > previousNumberOfLargeCells else { return suggestedStretchedCellWidth } guard numberOfLargeCells > previousNumberOfLargeCells else { return suggestedStretchedCellWidth }
let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast
let collectionViewAvailiableWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right let collectionViewAvailiableWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right
let numberOfCells = minimumCellWidths.count let numberOfCells = minimumCellWidths.count
let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumLineSpacing let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumLineSpacing
let numberOfSmallCells = numberOfCells - numberOfLargeCells let numberOfSmallCells = numberOfCells - numberOfLargeCells
let newSuggestedStretchedCellWidth = (collectionViewAvailiableWidth - totalWidthOfLargeCells - cellSpacingTotal) / CGFloat(numberOfSmallCells) let newSuggestedStretchedCellWidth = (collectionViewAvailiableWidth - totalWidthOfLargeCells - cellSpacingTotal) / CGFloat(numberOfSmallCells)
return calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: newSuggestedStretchedCellWidth, previousNumberOfLargeCells: numberOfLargeCells) return calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: newSuggestedStretchedCellWidth, previousNumberOfLargeCells: numberOfLargeCells)
} }
open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) { open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) {
guard shouldUpdateButtonBarView else { return } guard shouldUpdateButtonBarView else { return }
buttonBarView.moveTo(index: toIndex, animated: true, swipeDirection: toIndex < fromIndex ? .right : .left, pagerScroll: .yes) buttonBarView.moveTo(index: toIndex, animated: false, swipeDirection: toIndex < fromIndex ? .right : .left, pagerScroll: .yes)
if let changeCurrentIndex = changeCurrentIndex { if let changeCurrentIndex = changeCurrentIndex {
let oldCell = buttonBarView.cellForItem(at: IndexPath(item: currentIndex != fromIndex ? fromIndex : toIndex, section: 0)) as? ButtonBarViewCell let oldIndexPath = IndexPath(item: currentIndex != fromIndex ? fromIndex : toIndex, section: 0)
let newCell = buttonBarView.cellForItem(at: IndexPath(item: currentIndex, section: 0)) as? ButtonBarViewCell let newIndexPath = IndexPath(item: currentIndex, section: 0)
changeCurrentIndex(oldCell, newCell, true)
let cells = cellForItems(at: [oldIndexPath, newIndexPath], reloadIfNotVisible: collectionViewDidLoad)
changeCurrentIndex(cells.first!, cells.last!, true)
} }
} }
@ -226,56 +246,85 @@ open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, Pa
guard shouldUpdateButtonBarView else { return } guard shouldUpdateButtonBarView else { return }
buttonBarView.move(fromIndex: fromIndex, toIndex: toIndex, progressPercentage: progressPercentage, pagerScroll: .yes) buttonBarView.move(fromIndex: fromIndex, toIndex: toIndex, progressPercentage: progressPercentage, pagerScroll: .yes)
if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { if let changeCurrentIndexProgressive = changeCurrentIndexProgressive {
let oldCell = buttonBarView.cellForItem(at: IndexPath(item: currentIndex != fromIndex ? fromIndex : toIndex, section: 0)) as? ButtonBarViewCell let oldIndexPath = IndexPath(item: currentIndex != fromIndex ? fromIndex : toIndex, section: 0)
let newCell = buttonBarView.cellForItem(at: IndexPath(item: currentIndex, section: 0)) as? ButtonBarViewCell let newIndexPath = IndexPath(item: currentIndex, section: 0)
changeCurrentIndexProgressive(oldCell, newCell, progressPercentage, indexWasChanged, true)
let cells = cellForItems(at: [oldIndexPath, newIndexPath], reloadIfNotVisible: collectionViewDidLoad)
changeCurrentIndexProgressive(cells.first!, cells.last!, progressPercentage, indexWasChanged, true)
} }
} }
private func cellForItems(at indexPaths: [IndexPath], reloadIfNotVisible reload: Bool = true) -> [ButtonBarViewCell?] {
let cells = indexPaths.map { buttonBarView.cellForItem(at: $0) as? ButtonBarViewCell }
if reload {
let indexPathsToReload = cells.enumerated()
.compactMap { (arg) -> IndexPath? in
let (index, cell) = arg
return cell == nil ? indexPaths[index] : nil
}
.compactMap { (indexPath: IndexPath) -> IndexPath? in
return (indexPath.item >= 0 && indexPath.item < buttonBarView.numberOfItems(inSection: indexPath.section)) ? indexPath : nil
}
if !indexPathsToReload.isEmpty {
buttonBarView.reloadItems(at: Array(Set(indexPathsToReload)))
}
}
return cells
}
// MARK: - UICollectionViewDelegateFlowLayut // MARK: - UICollectionViewDelegateFlowLayut
open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize { @objc open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
guard let cellWidthValue = cachedCellWidths?[indexPath.row] else { guard let cellWidthValue = cachedCellWidths?[indexPath.row] else {
fatalError("cachedCellWidths for \(indexPath.row) must not be nil") fatalError("cachedCellWidths for \(indexPath.row) must not be nil")
} }
return CGSize(width: cellWidthValue, height: collectionView.frame.size.height) return CGSize(width: cellWidthValue, height: collectionView.frame.size.height)
} }
open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard indexPath.item != currentIndex else { return } guard indexPath.item != currentIndex else { return }
buttonBarView.moveTo(index: indexPath.item, animated: true, swipeDirection: .none, pagerScroll: .yes) buttonBarView.moveTo(index: indexPath.item, animated: true, swipeDirection: .none, pagerScroll: .yes)
shouldUpdateButtonBarView = false shouldUpdateButtonBarView = false
let oldCell = buttonBarView.cellForItem(at: IndexPath(item: currentIndex, section: 0)) as? ButtonBarViewCell let oldIndexPath = IndexPath(item: currentIndex, section: 0)
let newCell = buttonBarView.cellForItem(at: IndexPath(item: indexPath.item, section: 0)) as? ButtonBarViewCell let newIndexPath = IndexPath(item: indexPath.item, section: 0)
let cells = cellForItems(at: [oldIndexPath, newIndexPath], reloadIfNotVisible: collectionViewDidLoad)
if pagerBehaviour.isProgressiveIndicator { if pagerBehaviour.isProgressiveIndicator {
if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { if let changeCurrentIndexProgressive = changeCurrentIndexProgressive {
changeCurrentIndexProgressive(oldCell, newCell, 1, true, true) changeCurrentIndexProgressive(cells.first!, cells.last!, 1, true, true)
} }
} } else {
else {
if let changeCurrentIndex = changeCurrentIndex { if let changeCurrentIndex = changeCurrentIndex {
changeCurrentIndex(oldCell, newCell, true) changeCurrentIndex(cells.first!, cells.last!, true)
} }
} }
moveToViewController(at: indexPath.item) moveToViewController(at: indexPath.item)
} }
// MARK: - UICollectionViewDataSource // MARK: - UICollectionViewDataSource
open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return viewControllers.count return viewControllers.count
} }
open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? ButtonBarViewCell else { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? ButtonBarViewCell else {
fatalError("UICollectionViewCell should be or extend from ButtonBarViewCell") fatalError("UICollectionViewCell should be or extend from ButtonBarViewCell")
} }
let childController = viewControllers[indexPath.item] as! IndicatorInfoProvider
collectionViewDidLoad = true
let childController = viewControllers[indexPath.item] as! IndicatorInfoProvider // swiftlint:disable:this force_cast
let indicatorInfo = childController.indicatorInfo(for: self) let indicatorInfo = childController.indicatorInfo(for: self)
cell.label.text = indicatorInfo.title cell.label.text = indicatorInfo.title
cell.accessibilityLabel = indicatorInfo.accessibilityLabel
cell.label.font = settings.style.buttonBarItemFont cell.label.font = settings.style.buttonBarItemFont
cell.label.textColor = settings.style.buttonBarItemTitleColor ?? cell.label.textColor cell.label.textColor = settings.style.buttonBarItemTitleColor ?? cell.label.textColor
cell.contentView.backgroundColor = settings.style.buttonBarItemBackgroundColor ?? cell.contentView.backgroundColor cell.contentView.backgroundColor = settings.style.buttonBarItemBackgroundColor ?? cell.contentView.backgroundColor
@ -288,41 +337,43 @@ open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, Pa
} }
configureCell(cell, indicatorInfo: indicatorInfo) configureCell(cell, indicatorInfo: indicatorInfo)
if pagerBehaviour.isProgressiveIndicator { if pagerBehaviour.isProgressiveIndicator {
if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { if let changeCurrentIndexProgressive = changeCurrentIndexProgressive {
changeCurrentIndexProgressive(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, 1, true, false) changeCurrentIndexProgressive(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, 1, true, false)
} }
} } else {
else {
if let changeCurrentIndex = changeCurrentIndex { if let changeCurrentIndex = changeCurrentIndex {
changeCurrentIndex(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, false) changeCurrentIndex(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, false)
} }
} }
cell.isAccessibilityElement = true
cell.accessibilityLabel = cell.label.text
cell.accessibilityTraits.insert([.button, .header])
return cell return cell
} }
// MARK: - UIScrollViewDelegate // MARK: - UIScrollViewDelegate
open override func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { open override func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
super.scrollViewDidEndScrollingAnimation(scrollView) super.scrollViewDidEndScrollingAnimation(scrollView)
guard scrollView == containerView else { return } guard scrollView == containerView else { return }
shouldUpdateButtonBarView = true shouldUpdateButtonBarView = true
} }
open func configureCell(_ cell: ButtonBarViewCell, indicatorInfo: IndicatorInfo){ open func configureCell(_ cell: ButtonBarViewCell, indicatorInfo: IndicatorInfo) {
} }
private func calculateWidths() -> [CGFloat] { private func calculateWidths() -> [CGFloat] {
let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast
let numberOfCells = viewControllers.count let numberOfCells = viewControllers.count
var minimumCellWidths = [CGFloat]() var minimumCellWidths = [CGFloat]()
var collectionViewContentWidth: CGFloat = 0 var collectionViewContentWidth: CGFloat = 0
for viewController in viewControllers { for viewController in viewControllers {
let childController = viewController as! IndicatorInfoProvider let childController = viewController as! IndicatorInfoProvider // swiftlint:disable:this force_cast
let indicatorInfo = childController.indicatorInfo(for: self) let indicatorInfo = childController.indicatorInfo(for: self)
switch buttonBarItemSpec! { switch buttonBarItemSpec! {
case .cellClass(let widthCallback): case .cellClass(let widthCallback):
@ -335,29 +386,29 @@ open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, Pa
collectionViewContentWidth += width collectionViewContentWidth += width
} }
} }
let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumLineSpacing let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumLineSpacing
collectionViewContentWidth += cellSpacingTotal collectionViewContentWidth += cellSpacingTotal
let collectionViewAvailableVisibleWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right let collectionViewAvailableVisibleWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right
if !settings.style.buttonBarItemsShouldFillAvailiableWidth || collectionViewAvailableVisibleWidth < collectionViewContentWidth { if !settings.style.buttonBarItemsShouldFillAvailableWidth || collectionViewAvailableVisibleWidth < collectionViewContentWidth {
return minimumCellWidths return minimumCellWidths
} } else {
else {
let stretchedCellWidthIfAllEqual = (collectionViewAvailableVisibleWidth - cellSpacingTotal) / CGFloat(numberOfCells) let stretchedCellWidthIfAllEqual = (collectionViewAvailableVisibleWidth - cellSpacingTotal) / CGFloat(numberOfCells)
let generalMinimumCellWidth = calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: stretchedCellWidthIfAllEqual, previousNumberOfLargeCells: 0) let generalMinimumCellWidth = calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: stretchedCellWidthIfAllEqual, previousNumberOfLargeCells: 0)
var stretchedCellWidths = [CGFloat]() var stretchedCellWidths = [CGFloat]()
for minimumCellWidthValue in minimumCellWidths { for minimumCellWidthValue in minimumCellWidths {
let cellWidth = (minimumCellWidthValue > generalMinimumCellWidth) ? minimumCellWidthValue : generalMinimumCellWidth let cellWidth = (minimumCellWidthValue > generalMinimumCellWidth) ? minimumCellWidthValue : generalMinimumCellWidth
stretchedCellWidths.append(cellWidth) stretchedCellWidths.append(cellWidth)
} }
return stretchedCellWidths return stretchedCellWidths
} }
} }
private var shouldUpdateButtonBarView = true private var shouldUpdateButtonBarView = true
private var collectionViewDidLoad = false
} }

View File

@ -1,7 +1,7 @@
// ButtonBarView.swift // ButtonBarView.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -37,112 +37,115 @@ public enum SelectedBarAlignment {
case progressive case progressive
} }
public enum SelectedBarVerticalAlignment {
case top
case middle
case bottom
}
open class ButtonBarView: UICollectionView { open class ButtonBarView: UICollectionView {
open lazy var selectedBar: UIView = { [unowned self] in open lazy var selectedBar: UIView = { [unowned self] in
let bar = UIView(frame: CGRect(x: 0, y: self.frame.size.height - CGFloat(self.selectedBarHeight), width: 0, height: CGFloat(self.selectedBarHeight))) let bar = UIView(frame: CGRect(x: 0, y: self.frame.size.height - CGFloat(self.selectedBarHeight), width: 0, height: CGFloat(self.selectedBarHeight)))
bar.layer.zPosition = 9999 bar.layer.zPosition = 9999
return bar return bar
}() }()
internal var selectedBarHeight: CGFloat = 4 { internal var selectedBarHeight: CGFloat = 4 {
didSet { didSet {
updateSlectedBarYPosition() updateSelectedBarYPosition()
} }
} }
var selectedBarVerticalAlignment: SelectedBarVerticalAlignment = .bottom
var selectedBarAlignment: SelectedBarAlignment = .center var selectedBarAlignment: SelectedBarAlignment = .center
var selectedIndex = 0 var selectedIndex = 0
required public init?(coder aDecoder: NSCoder) { required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) super.init(coder: aDecoder)
addSubview(selectedBar) addSubview(selectedBar)
} }
override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) { public override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout) super.init(frame: frame, collectionViewLayout: layout)
addSubview(selectedBar) addSubview(selectedBar)
} }
open func moveTo(index: Int, animated: Bool, swipeDirection: SwipeDirection, pagerScroll: PagerScroll) { open func moveTo(index: Int, animated: Bool, swipeDirection: SwipeDirection, pagerScroll: PagerScroll) {
selectedIndex = index selectedIndex = index
updateSelectedBarPosition(animated, swipeDirection: swipeDirection, pagerScroll: pagerScroll) updateSelectedBarPosition(animated, swipeDirection: swipeDirection, pagerScroll: pagerScroll)
} }
open func move(fromIndex: Int, toIndex: Int, progressPercentage: CGFloat,pagerScroll: PagerScroll) { open func move(fromIndex: Int, toIndex: Int, progressPercentage: CGFloat, pagerScroll: PagerScroll) {
selectedIndex = progressPercentage > 0.5 ? toIndex : fromIndex selectedIndex = progressPercentage > 0.5 ? toIndex : fromIndex
let fromFrame = layoutAttributesForItem(at: IndexPath(item: fromIndex, section: 0))!.frame let fromFrame = layoutAttributesForItem(at: IndexPath(item: fromIndex, section: 0))!.frame
let numberOfItems = dataSource!.collectionView(self, numberOfItemsInSection: 0) let numberOfItems = dataSource!.collectionView(self, numberOfItemsInSection: 0)
var toFrame: CGRect var toFrame: CGRect
if toIndex < 0 || toIndex > numberOfItems - 1 { if toIndex < 0 || toIndex > numberOfItems - 1 {
if toIndex < 0 { if toIndex < 0 {
let cellAtts = layoutAttributesForItem(at: IndexPath(item: 0, section: 0)) let cellAtts = layoutAttributesForItem(at: IndexPath(item: 0, section: 0))
toFrame = cellAtts!.frame.offsetBy(dx: -cellAtts!.frame.size.width, dy: 0) toFrame = cellAtts!.frame.offsetBy(dx: -cellAtts!.frame.size.width, dy: 0)
} } else {
else {
let cellAtts = layoutAttributesForItem(at: IndexPath(item: (numberOfItems - 1), section: 0)) let cellAtts = layoutAttributesForItem(at: IndexPath(item: (numberOfItems - 1), section: 0))
toFrame = cellAtts!.frame.offsetBy(dx: cellAtts!.frame.size.width, dy: 0) toFrame = cellAtts!.frame.offsetBy(dx: cellAtts!.frame.size.width, dy: 0)
} }
} } else {
else {
toFrame = layoutAttributesForItem(at: IndexPath(item: toIndex, section: 0))!.frame toFrame = layoutAttributesForItem(at: IndexPath(item: toIndex, section: 0))!.frame
} }
var targetFrame = fromFrame var targetFrame = fromFrame
targetFrame.size.height = selectedBar.frame.size.height targetFrame.size.height = selectedBar.frame.size.height
targetFrame.size.width += (toFrame.size.width - fromFrame.size.width) * progressPercentage targetFrame.size.width += (toFrame.size.width - fromFrame.size.width) * progressPercentage
targetFrame.origin.x += (toFrame.origin.x - fromFrame.origin.x) * progressPercentage targetFrame.origin.x += (toFrame.origin.x - fromFrame.origin.x) * progressPercentage
selectedBar.frame = CGRect(x: targetFrame.origin.x, y: selectedBar.frame.origin.y, width: targetFrame.size.width, height: selectedBar.frame.size.height) selectedBar.frame = CGRect(x: targetFrame.origin.x, y: selectedBar.frame.origin.y, width: targetFrame.size.width, height: selectedBar.frame.size.height)
var targetContentOffset: CGFloat = 0.0 var targetContentOffset: CGFloat = 0.0
if contentSize.width > frame.size.width { if contentSize.width > frame.size.width {
let toContentOffset = contentOffsetForCell(withFrame: toFrame, andIndex: toIndex) let toContentOffset = contentOffsetForCell(withFrame: toFrame, andIndex: toIndex)
let fromContentOffset = contentOffsetForCell(withFrame: fromFrame, andIndex: fromIndex) let fromContentOffset = contentOffsetForCell(withFrame: fromFrame, andIndex: fromIndex)
targetContentOffset = fromContentOffset + ((toContentOffset - fromContentOffset) * progressPercentage) targetContentOffset = fromContentOffset + ((toContentOffset - fromContentOffset) * progressPercentage)
} }
let animated = abs(contentOffset.x - targetContentOffset) > 30 || (fromIndex == toIndex) setContentOffset(CGPoint(x: targetContentOffset, y: 0), animated: false)
setContentOffset(CGPoint(x: targetContentOffset, y: 0), animated: animated)
} }
open func updateSelectedBarPosition(_ animated: Bool, swipeDirection: SwipeDirection, pagerScroll: PagerScroll) -> Void { open func updateSelectedBarPosition(_ animated: Bool, swipeDirection: SwipeDirection, pagerScroll: PagerScroll) {
var selectedBarFrame = selectedBar.frame var selectedBarFrame = selectedBar.frame
let selectedCellIndexPath = IndexPath(item: selectedIndex, section: 0) let selectedCellIndexPath = IndexPath(item: selectedIndex, section: 0)
let attributes = layoutAttributesForItem(at: selectedCellIndexPath) let attributes = layoutAttributesForItem(at: selectedCellIndexPath)
let selectedCellFrame = attributes!.frame let selectedCellFrame = attributes!.frame
updateContentOffset(animated: animated, pagerScroll: pagerScroll, toFrame: selectedCellFrame, toIndex: (selectedCellIndexPath as NSIndexPath).row) updateContentOffset(animated: animated, pagerScroll: pagerScroll, toFrame: selectedCellFrame, toIndex: (selectedCellIndexPath as NSIndexPath).row)
selectedBarFrame.size.width = selectedCellFrame.size.width selectedBarFrame.size.width = selectedCellFrame.size.width
selectedBarFrame.origin.x = selectedCellFrame.origin.x selectedBarFrame.origin.x = selectedCellFrame.origin.x
if animated { if animated {
UIView.animate(withDuration: 0.3, animations: { [weak self] in UIView.animate(withDuration: 0.3, animations: { [weak self] in
self?.selectedBar.frame = selectedBarFrame self?.selectedBar.frame = selectedBarFrame
}) })
} } else {
else {
selectedBar.frame = selectedBarFrame selectedBar.frame = selectedBarFrame
} }
} }
// MARK: - Helpers // MARK: - Helpers
private func updateContentOffset(animated: Bool, pagerScroll: PagerScroll, toFrame: CGRect, toIndex: Int) -> Void { private func updateContentOffset(animated: Bool, pagerScroll: PagerScroll, toFrame: CGRect, toIndex: Int) {
guard pagerScroll != .no || (pagerScroll != .scrollOnlyIfOutOfScreen && (toFrame.origin.x < contentOffset.x || toFrame.origin.x >= (contentOffset.x + frame.size.width - contentInset.left))) else { return } guard pagerScroll != .no || (pagerScroll != .scrollOnlyIfOutOfScreen && (toFrame.origin.x < contentOffset.x || toFrame.origin.x >= (contentOffset.x + frame.size.width - contentInset.left))) else { return }
let targetContentOffset = contentSize.width > frame.size.width ? contentOffsetForCell(withFrame: toFrame, andIndex: toIndex) : 0 let targetContentOffset = contentSize.width > frame.size.width ? contentOffsetForCell(withFrame: toFrame, andIndex: toIndex) : 0
setContentOffset(CGPoint(x: targetContentOffset, y: 0), animated: animated) setContentOffset(CGPoint(x: targetContentOffset, y: 0), animated: animated)
} }
private func contentOffsetForCell(withFrame cellFrame: CGRect, andIndex index: Int) -> CGFloat { private func contentOffsetForCell(withFrame cellFrame: CGRect, andIndex index: Int) -> CGFloat {
let sectionInset = (collectionViewLayout as! UICollectionViewFlowLayout).sectionInset let sectionInset = (collectionViewLayout as! UICollectionViewFlowLayout).sectionInset // swiftlint:disable:this force_cast
var alignmentOffset: CGFloat = 0.0 var alignmentOffset: CGFloat = 0.0
switch selectedBarAlignment { switch selectedBarAlignment {
case .left: case .left:
alignmentOffset = sectionInset.left alignmentOffset = sectionInset.left
@ -158,17 +161,31 @@ open class ButtonBarView: UICollectionView {
let progress = index / (numberOfItems - 1) let progress = index / (numberOfItems - 1)
alignmentOffset = leftAlignmentOffset + (rightAlignmentOffset - leftAlignmentOffset) * CGFloat(progress) - cellHalfWidth alignmentOffset = leftAlignmentOffset + (rightAlignmentOffset - leftAlignmentOffset) * CGFloat(progress) - cellHalfWidth
} }
var contentOffset = cellFrame.origin.x - alignmentOffset var contentOffset = cellFrame.origin.x - alignmentOffset
contentOffset = max(0, contentOffset) contentOffset = max(0, contentOffset)
contentOffset = min(contentSize.width - frame.size.width, contentOffset) contentOffset = min(contentSize.width - frame.size.width, contentOffset)
return contentOffset return contentOffset
} }
private func updateSlectedBarYPosition() { private func updateSelectedBarYPosition() {
var selectedBarFrame = selectedBar.frame var selectedBarFrame = selectedBar.frame
selectedBarFrame.origin.y = frame.size.height - selectedBarHeight
switch selectedBarVerticalAlignment {
case .top:
selectedBarFrame.origin.y = 0
case .middle:
selectedBarFrame.origin.y = (frame.size.height - selectedBarHeight) / 2
case .bottom:
selectedBarFrame.origin.y = frame.size.height - selectedBarHeight
}
selectedBarFrame.size.height = selectedBarHeight selectedBarFrame.size.height = selectedBarHeight
selectedBar.frame = selectedBarFrame selectedBar.frame = selectedBarFrame
} }
override open func layoutSubviews() {
super.layoutSubviews()
updateSelectedBarYPosition()
}
} }

View File

@ -1,7 +1,7 @@
// ButtonBarViewCell.swift // ButtonBarViewCell.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -25,21 +25,28 @@
import Foundation import Foundation
open class ButtonBarViewCell: UICollectionViewCell { open class ButtonBarViewCell: UICollectionViewCell {
@IBOutlet open var imageView: UIImageView! @IBOutlet open var imageView: UIImageView!
@IBOutlet open lazy var label: UILabel! = { [unowned self] in @IBOutlet open var label: UILabel!
let label = UILabel(frame: self.contentView.bounds)
label.autoresizingMask = [.flexibleWidth, .flexibleHeight] public required init?(coder aDecoder: NSCoder) {
label.textAlignment = .center super.init(coder: aDecoder)
label.font = UIFont.boldSystemFont(ofSize: 14.0)
return label
}()
open override func willMove(toSuperview newSuperview: UIView?) {
super.willMove(toSuperview: newSuperview)
if label.superview != nil { isAccessibilityElement = true
contentView.addSubview(label) accessibilityTraits.insert([.button, .header])
}
open override var isSelected: Bool {
get {
return super.isSelected
}
set {
super.isSelected = newValue
if (newValue) {
accessibilityTraits.insert(.selected)
} else {
accessibilityTraits.remove(.selected)
}
} }
} }
} }

View File

@ -1,34 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="ButtonBarViewCell" customModule="XLPagerTabStrip" customModuleProvider="target"> <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="zg4-fX-zUF" customClass="ButtonBarViewCell" customModule="XLPagerTabStrip" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="80" height="40"/> <rect key="frame" x="0.0" y="0.0" width="80" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews> <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4bA-d3-zGi"> <rect key="frame" x="0.0" y="0.0" width="80" height="40"/>
<rect key="frame" x="18" y="10" width="45" height="21"/> <autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/> <subviews>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="s7f-rk-sQl">
<nil key="highlightedColor"/> <rect key="frame" x="22" y="12" width="37.5" height="17"/>
</label> <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
</subviews> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="calibratedRGB"/> <nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="tFG-yJ-6Th">
<rect key="frame" x="22.5" y="2.5" width="35" height="35"/>
<constraints>
<constraint firstAttribute="width" constant="35" id="VRw-5F-5WY"/>
<constraint firstAttribute="height" constant="35" id="ojk-Ug-Lgh"/>
</constraints>
</imageView>
</subviews>
</view>
<color key="backgroundColor" red="0.027450980390000001" green="0.72549019609999998" blue="0.60784313729999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstAttribute="centerX" secondItem="4bA-d3-zGi" secondAttribute="centerX" id="kcH-EZ-rRx"/> <constraint firstItem="tFG-yJ-6Th" firstAttribute="centerY" secondItem="zg4-fX-zUF" secondAttribute="centerY" id="5so-ZP-gRs"/>
<constraint firstAttribute="centerY" secondItem="4bA-d3-zGi" secondAttribute="centerY" id="lcE-iT-kgq"/> <constraint firstItem="tFG-yJ-6Th" firstAttribute="centerX" secondItem="zg4-fX-zUF" secondAttribute="centerX" id="9em-NR-hoa"/>
<constraint firstItem="s7f-rk-sQl" firstAttribute="centerY" secondItem="zg4-fX-zUF" secondAttribute="centerY" id="ZeP-6I-AXE"/>
<constraint firstItem="s7f-rk-sQl" firstAttribute="centerX" secondItem="zg4-fX-zUF" secondAttribute="centerX" id="c15-bZ-hPG"/>
</constraints> </constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections> <connections>
<outlet property="label" destination="4bA-d3-zGi" id="Ckx-bG-ZhP"/> <outlet property="imageView" destination="tFG-yJ-6Th" id="Odb-dR-tf4"/>
<outlet property="label" destination="s7f-rk-sQl" id="4gU-tb-BMB"/>
</connections> </connections>
<point key="canvasLocation" x="304" y="552"/> <point key="canvasLocation" x="307" y="541"/>
</view> </collectionViewCell>
</objects> </objects>
</document> </document>

View File

@ -34,7 +34,6 @@
#pragma GCC diagnostic ignored "-Wgnu" #pragma GCC diagnostic ignored "-Wgnu"
#pragma GCC diagnostic ignored "-Wreceiver-is-weak"
#pragma GCC diagnostic ignored "-Warc-repeated-use-of-weak" #pragma GCC diagnostic ignored "-Warc-repeated-use-of-weak"
#pragma GCC diagnostic ignored "-Wdirect-ivar-access" #pragma GCC diagnostic ignored "-Wdirect-ivar-access"

View File

@ -1,7 +1,7 @@
// IndicatorInfo.swift // IndicatorInfo.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -25,38 +25,56 @@
import Foundation import Foundation
public struct IndicatorInfo { public struct IndicatorInfo {
public var title: String public var title: String?
public var image: UIImage? public var image: UIImage?
public var highlightedImage: UIImage? public var highlightedImage: UIImage?
public var accessibilityLabel: String?
public var userInfo: Any?
public init(title: String) { public init(title: String?) {
self.title = title self.title = title
self.accessibilityLabel = title
} }
public init(title: String, image: UIImage?) { public init(image: UIImage?, highlightedImage: UIImage? = nil, userInfo: Any? = nil) {
self.init(title: title)
self.image = image self.image = image
self.highlightedImage = highlightedImage
self.userInfo = userInfo
} }
public init(title: String, image: UIImage?, highlightedImage: UIImage?) { public init(title: String?, image: UIImage?, highlightedImage: UIImage? = nil, userInfo: Any? = nil) {
self.init(title: title, image: image) self.title = title
self.accessibilityLabel = title
self.image = image
self.highlightedImage = highlightedImage self.highlightedImage = highlightedImage
self.userInfo = userInfo
}
public init(title: String?, accessibilityLabel:String?, image: UIImage?, highlightedImage: UIImage? = nil, userInfo: Any? = nil) {
self.title = title
self.accessibilityLabel = accessibilityLabel
self.image = image
self.highlightedImage = highlightedImage
self.userInfo = userInfo
} }
}
}
extension IndicatorInfo : ExpressibleByStringLiteral { extension IndicatorInfo : ExpressibleByStringLiteral {
public init(stringLiteral value: String){ public init(stringLiteral value: String) {
title = value title = value
accessibilityLabel = value
} }
public init(extendedGraphemeClusterLiteral value: String){ public init(extendedGraphemeClusterLiteral value: String) {
title = value title = value
accessibilityLabel = value
} }
public init(unicodeScalarLiteral value: String){ public init(unicodeScalarLiteral value: String) {
title = value title = value
accessibilityLabel = value
} }
} }

View File

@ -1,7 +1,7 @@
// PagerTabStripOptions.swift // PagerTabStripOptions.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -25,10 +25,10 @@
import Foundation import Foundation
public enum PagerTabStripBehaviour { public enum PagerTabStripBehaviour {
case common(skipIntermediateViewControllers: Bool) case common(skipIntermediateViewControllers: Bool)
case progressive(skipIntermediateViewControllers: Bool, elasticIndicatorLimit: Bool) case progressive(skipIntermediateViewControllers: Bool, elasticIndicatorLimit: Bool)
public var skipIntermediateViewControllers: Bool { public var skipIntermediateViewControllers: Bool {
switch self { switch self {
case .common(let skipIntermediateViewControllers): case .common(let skipIntermediateViewControllers):
@ -37,27 +37,22 @@ public enum PagerTabStripBehaviour {
return skipIntermediateViewControllers return skipIntermediateViewControllers
} }
} }
public var isProgressiveIndicator: Bool { public var isProgressiveIndicator: Bool {
switch self { switch self {
case .common(_): case .common:
return false return false
case .progressive(_, _): case .progressive:
return true return true
} }
} }
public var isElasticIndicatorLimit: Bool { public var isElasticIndicatorLimit: Bool {
switch self { switch self {
case .common(_): case .common:
return false return false
case .progressive(_, let elasticIndicatorLimit): case .progressive(_, let elasticIndicatorLimit):
return elasticIndicatorLimit return elasticIndicatorLimit
} }
} }
} }

View File

@ -1,7 +1,7 @@
// PagerTabStripError.swift // PagerTabStripError.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -25,5 +25,7 @@
import Foundation import Foundation
public enum PagerTabStripError: Error { public enum PagerTabStripError: Error {
case viewControllerNotContainedInPagerTabStrip
case viewControllerOutOfBounds
} }

View File

@ -1,7 +1,7 @@
// PagerTabStripViewController.swift // PagerTabStripViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -22,51 +22,50 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
import Foundation import Foundation
// MARK: Protocols // MARK: Protocols
public protocol IndicatorInfoProvider { public protocol IndicatorInfoProvider {
func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo
} }
public protocol PagerTabStripDelegate: class { public protocol PagerTabStripDelegate: class {
func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int)
} }
public protocol PagerTabStripIsProgressiveDelegate : PagerTabStripDelegate { public protocol PagerTabStripIsProgressiveDelegate: PagerTabStripDelegate {
func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool)
} }
public protocol PagerTabStripDataSource: class { public protocol PagerTabStripDataSource: class {
func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController]
} }
// MARK: PagerTabStripViewController
//MARK: PagerTabStripViewController
open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate { open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
@IBOutlet weak public var containerView: UIScrollView! @IBOutlet weak public var containerView: UIScrollView!
open weak var delegate: PagerTabStripDelegate? open weak var delegate: PagerTabStripDelegate?
open weak var datasource: PagerTabStripDataSource? open weak var datasource: PagerTabStripDataSource?
open var pagerBehaviour = PagerTabStripBehaviour.progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true) open var pagerBehaviour = PagerTabStripBehaviour.progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true)
open private(set) var viewControllers = [UIViewController]() open private(set) var viewControllers = [UIViewController]()
open private(set) var currentIndex = 0 open private(set) var currentIndex = 0
open private(set) var preCurrentIndex = 0 // used *only* to store the index to which move when the pager becomes visible
open var pageWidth: CGFloat { open var pageWidth: CGFloat {
return containerView.bounds.width return containerView.bounds.width
} }
open var scrollPercentage: CGFloat { open var scrollPercentage: CGFloat {
if swipeDirection != .right { if swipeDirection != .right {
let module = fmod(containerView.contentOffset.x, pageWidth) let module = fmod(containerView.contentOffset.x, pageWidth)
@ -74,17 +73,16 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
} }
return 1 - fmod(containerView.contentOffset.x >= 0 ? containerView.contentOffset.x : pageWidth + containerView.contentOffset.x, pageWidth) / pageWidth return 1 - fmod(containerView.contentOffset.x >= 0 ? containerView.contentOffset.x : pageWidth + containerView.contentOffset.x, pageWidth) / pageWidth
} }
open var swipeDirection: SwipeDirection { open var swipeDirection: SwipeDirection {
if containerView.contentOffset.x > lastContentOffset { if containerView.contentOffset.x > lastContentOffset {
return .left return .left
} } else if containerView.contentOffset.x < lastContentOffset {
else if containerView.contentOffset.x < lastContentOffset {
return .right return .right
} }
return .none return .none
} }
override open func viewDidLoad() { override open func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
let conteinerViewAux = containerView ?? { let conteinerViewAux = containerView ?? {
@ -105,52 +103,57 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
containerView.showsHorizontalScrollIndicator = false containerView.showsHorizontalScrollIndicator = false
containerView.isPagingEnabled = true containerView.isPagingEnabled = true
reloadViewControllers() reloadViewControllers()
let childController = viewControllers[currentIndex] let childController = viewControllers[currentIndex]
addChildViewController(childController) addChild(childController)
childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth] childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
containerView.addSubview(childController.view) containerView.addSubview(childController.view)
childController.didMove(toParentViewController: self) childController.didMove(toParent: self)
} }
open override func viewWillAppear(_ animated: Bool) { open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
isViewAppearing = true isViewAppearing = true
childViewControllers.forEach { $0.beginAppearanceTransition(true, animated: animated) } children.forEach { $0.beginAppearanceTransition(true, animated: animated) }
} }
override open func viewDidAppear(_ animated: Bool) { override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated) super.viewDidAppear(animated)
lastSize = containerView.bounds.size lastSize = containerView.bounds.size
updateIfNeeded() updateIfNeeded()
let needToUpdateCurrentChild = preCurrentIndex != currentIndex
if needToUpdateCurrentChild {
moveToViewController(at: preCurrentIndex)
}
isViewAppearing = false isViewAppearing = false
childViewControllers.forEach { $0.endAppearanceTransition() } children.forEach { $0.endAppearanceTransition() }
} }
open override func viewWillDisappear(_ animated: Bool) { open override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated) super.viewWillDisappear(animated)
childViewControllers.forEach { $0.beginAppearanceTransition(false, animated: animated) } children.forEach { $0.beginAppearanceTransition(false, animated: animated) }
} }
open override func viewDidDisappear(_ animated: Bool) { open override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated) super.viewDidDisappear(animated)
childViewControllers.forEach { $0.endAppearanceTransition() } children.forEach { $0.endAppearanceTransition() }
} }
override open func viewDidLayoutSubviews(){ override open func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
updateIfNeeded() updateIfNeeded()
} }
open override var shouldAutomaticallyForwardAppearanceMethods: Bool { open override var shouldAutomaticallyForwardAppearanceMethods: Bool {
return false return false
} }
open func moveToViewController(at index: Int, animated: Bool = true) { open func moveToViewController(at index: Int, animated: Bool = true) {
guard isViewLoaded && view.window != nil && currentIndex != index else { guard isViewLoaded && view.window != nil && currentIndex != index else {
currentIndex = index preCurrentIndex = index
return return
} }
if animated && pagerBehaviour.skipIntermediateViewControllers && abs(currentIndex - index) > 1 { if animated && pagerBehaviour.skipIntermediateViewControllers && abs(currentIndex - index) > 1 {
var tmpViewControllers = viewControllers var tmpViewControllers = viewControllers
let currentChildVC = viewControllers[currentIndex] let currentChildVC = viewControllers[currentIndex]
@ -162,32 +165,31 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: fromIndex), y: 0), animated: false) containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: fromIndex), y: 0), animated: false)
(navigationController?.view ?? view).isUserInteractionEnabled = !animated (navigationController?.view ?? view).isUserInteractionEnabled = !animated
containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: index), y: 0), animated: true) containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: index), y: 0), animated: true)
} } else {
else {
(navigationController?.view ?? view).isUserInteractionEnabled = !animated (navigationController?.view ?? view).isUserInteractionEnabled = !animated
containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: index), y: 0), animated: animated) containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: index), y: 0), animated: animated)
} }
} }
open func moveTo(viewController: UIViewController, animated: Bool = true) { open func moveTo(viewController: UIViewController, animated: Bool = true) {
moveToViewController(at: viewControllers.index(of: viewController)!, animated: animated) moveToViewController(at: viewControllers.index(of: viewController)!, animated: animated)
} }
//MARK: - PagerTabStripDataSource // MARK: - PagerTabStripDataSource
open func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { open func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
assertionFailure("Sub-class must implement the PagerTabStripDataSource viewControllers(for:) method") assertionFailure("Sub-class must implement the PagerTabStripDataSource viewControllers(for:) method")
return [] return []
} }
//MARK: - Helpers // MARK: - Helpers
open func updateIfNeeded() { open func updateIfNeeded() {
if isViewLoaded && !lastSize.equalTo(containerView.bounds.size){ if isViewLoaded && !lastSize.equalTo(containerView.bounds.size) {
updateContent() updateContent()
} }
} }
open func canMoveTo(index: Int) -> Bool { open func canMoveTo(index: Int) -> Bool {
return currentIndex != index && viewControllers.count > index return currentIndex != index && viewControllers.count > index
} }
@ -195,28 +197,28 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
open func pageOffsetForChild(at index: Int) -> CGFloat { open func pageOffsetForChild(at index: Int) -> CGFloat {
return CGFloat(index) * containerView.bounds.width return CGFloat(index) * containerView.bounds.width
} }
open func offsetForChild(at index: Int) -> CGFloat{ open func offsetForChild(at index: Int) -> CGFloat {
return (CGFloat(index) * containerView.bounds.width) + ((containerView.bounds.width - view.bounds.width) * 0.5) return (CGFloat(index) * containerView.bounds.width) + ((containerView.bounds.width - view.bounds.width) * 0.5)
} }
open func offsetForChild(viewController: UIViewController) throws -> CGFloat{ open func offsetForChild(viewController: UIViewController) throws -> CGFloat {
guard let index = viewControllers.index(of: viewController) else { guard let index = viewControllers.index(of: viewController) else {
throw PagerTabStripError.viewControllerNotContainedInPagerTabStrip throw PagerTabStripError.viewControllerOutOfBounds
} }
return offsetForChild(at: index) return offsetForChild(at: index)
} }
open func pageFor(contentOffset: CGFloat) -> Int { open func pageFor(contentOffset: CGFloat) -> Int {
let result = virtualPageFor(contentOffset: contentOffset) let result = virtualPageFor(contentOffset: contentOffset)
return pageFor(virtualPage: result) return pageFor(virtualPage: result)
} }
open func virtualPageFor(contentOffset: CGFloat) -> Int { open func virtualPageFor(contentOffset: CGFloat) -> Int {
return Int((contentOffset + 1.5 * pageWidth) / pageWidth) - 1 return Int((contentOffset + 1.5 * pageWidth) / pageWidth) - 1
} }
open func pageFor(virtualPage: Int) -> Int{ open func pageFor(virtualPage: Int) -> Int {
if virtualPage < 0 { if virtualPage < 0 {
return 0 return 0
} }
@ -225,96 +227,93 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
} }
return virtualPage return virtualPage
} }
open func updateContent() { open func updateContent() {
if lastSize.width != containerView.bounds.size.width { if lastSize.width != containerView.bounds.size.width {
lastSize = containerView.bounds.size lastSize = containerView.bounds.size
containerView.contentOffset = CGPoint(x: pageOffsetForChild(at: currentIndex), y: 0) containerView.contentOffset = CGPoint(x: pageOffsetForChild(at: currentIndex), y: 0)
} }
lastSize = containerView.bounds.size lastSize = containerView.bounds.size
let pagerViewControllers = pagerTabStripChildViewControllersForScrolling ?? viewControllers let pagerViewControllers = pagerTabStripChildViewControllersForScrolling ?? viewControllers
containerView.contentSize = CGSize(width: containerView.bounds.width * CGFloat(pagerViewControllers.count), height: containerView.contentSize.height) containerView.contentSize = CGSize(width: containerView.bounds.width * CGFloat(pagerViewControllers.count), height: containerView.contentSize.height)
for (index, childController) in pagerViewControllers.enumerated() { for (index, childController) in pagerViewControllers.enumerated() {
let pageOffsetForChild = self.pageOffsetForChild(at: index) let pageOffsetForChild = self.pageOffsetForChild(at: index)
if fabs(containerView.contentOffset.x - pageOffsetForChild) < containerView.bounds.width { if abs(containerView.contentOffset.x - pageOffsetForChild) < containerView.bounds.width {
if let _ = childController.parent { if childController.parent != nil {
childController.view.frame = CGRect(x: offsetForChild(at: index), y: 0, width: view.bounds.width, height: containerView.bounds.height) childController.view.frame = CGRect(x: offsetForChild(at: index), y: 0, width: view.bounds.width, height: containerView.bounds.height)
childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth] childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
} } else {
else {
childController.beginAppearanceTransition(true, animated: false) childController.beginAppearanceTransition(true, animated: false)
addChildViewController(childController) addChild(childController)
childController.view.frame = CGRect(x: offsetForChild(at: index), y: 0, width: view.bounds.width, height: containerView.bounds.height) childController.view.frame = CGRect(x: offsetForChild(at: index), y: 0, width: view.bounds.width, height: containerView.bounds.height)
childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth] childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
containerView.addSubview(childController.view) containerView.addSubview(childController.view)
childController.didMove(toParentViewController: self) childController.didMove(toParent: self)
childController.endAppearanceTransition() childController.endAppearanceTransition()
} }
} } else {
else { if childController.parent != nil {
if let _ = childController.parent {
childController.beginAppearanceTransition(false, animated: false) childController.beginAppearanceTransition(false, animated: false)
childController.willMove(toParentViewController: nil) childController.willMove(toParent: nil)
childController.view.removeFromSuperview() childController.view.removeFromSuperview()
childController.removeFromParentViewController() childController.removeFromParent()
childController.endAppearanceTransition() childController.endAppearanceTransition()
} }
} }
} }
let oldCurrentIndex = currentIndex let oldCurrentIndex = currentIndex
let virtualPage = virtualPageFor(contentOffset: containerView.contentOffset.x) let virtualPage = virtualPageFor(contentOffset: containerView.contentOffset.x)
let newCurrentIndex = pageFor(virtualPage: virtualPage) let newCurrentIndex = pageFor(virtualPage: virtualPage)
currentIndex = newCurrentIndex currentIndex = newCurrentIndex
preCurrentIndex = currentIndex
let changeCurrentIndex = newCurrentIndex != oldCurrentIndex let changeCurrentIndex = newCurrentIndex != oldCurrentIndex
if let progressiveDeledate = self as? PagerTabStripIsProgressiveDelegate, pagerBehaviour.isProgressiveIndicator { if let progressiveDelegate = self as? PagerTabStripIsProgressiveDelegate, pagerBehaviour.isProgressiveIndicator {
let (fromIndex, toIndex, scrollPercentage) = progressiveIndicatorData(virtualPage) let (fromIndex, toIndex, scrollPercentage) = progressiveIndicatorData(virtualPage)
progressiveDeledate.updateIndicator(for: self, fromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: scrollPercentage, indexWasChanged: changeCurrentIndex) progressiveDelegate.updateIndicator(for: self, fromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: scrollPercentage, indexWasChanged: changeCurrentIndex)
} } else {
else{
delegate?.updateIndicator(for: self, fromIndex: min(oldCurrentIndex, pagerViewControllers.count - 1), toIndex: newCurrentIndex) delegate?.updateIndicator(for: self, fromIndex: min(oldCurrentIndex, pagerViewControllers.count - 1), toIndex: newCurrentIndex)
} }
} }
open func reloadPagerTabStripView() { open func reloadPagerTabStripView() {
guard isViewLoaded else { return } guard isViewLoaded else { return }
for childController in viewControllers { for childController in viewControllers where childController.parent != nil {
if let _ = childController.parent { childController.beginAppearanceTransition(false, animated: false)
childController.beginAppearanceTransition(false, animated: false) childController.willMove(toParent: nil)
childController.willMove(toParentViewController: nil) childController.view.removeFromSuperview()
childController.view.removeFromSuperview() childController.removeFromParent()
childController.removeFromParentViewController() childController.endAppearanceTransition()
childController.endAppearanceTransition()
}
} }
reloadViewControllers() reloadViewControllers()
containerView.contentSize = CGSize(width: containerView.bounds.width * CGFloat(viewControllers.count), height: containerView.contentSize.height) containerView.contentSize = CGSize(width: containerView.bounds.width * CGFloat(viewControllers.count), height: containerView.contentSize.height)
if currentIndex >= viewControllers.count { if currentIndex >= viewControllers.count {
currentIndex = viewControllers.count - 1 currentIndex = viewControllers.count - 1
} }
preCurrentIndex = currentIndex
containerView.contentOffset = CGPoint(x: pageOffsetForChild(at: currentIndex), y: 0) containerView.contentOffset = CGPoint(x: pageOffsetForChild(at: currentIndex), y: 0)
updateContent() updateContent()
} }
//MARK: - UIScrollDelegate // MARK: - UIScrollViewDelegate
open func scrollViewDidScroll(_ scrollView: UIScrollView) { open func scrollViewDidScroll(_ scrollView: UIScrollView) {
if containerView == scrollView { if containerView == scrollView {
updateContent() updateContent()
}
}
open func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
if containerView == scrollView {
lastPageNumber = pageFor(contentOffset: scrollView.contentOffset.x)
lastContentOffset = scrollView.contentOffset.x lastContentOffset = scrollView.contentOffset.x
} }
} }
open func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
if containerView == scrollView {
lastPageNumber = pageFor(contentOffset: scrollView.contentOffset.x)
}
}
open func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { open func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
if containerView == scrollView { if containerView == scrollView {
pagerTabStripChildViewControllersForScrolling = nil pagerTabStripChildViewControllersForScrolling = nil
@ -322,9 +321,9 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
updateContent() updateContent()
} }
} }
//MARK: - Orientation // MARK: - Orientation
open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator) super.viewWillTransition(to: size, with: coordinator)
isViewRotating = true isViewRotating = true
@ -333,43 +332,38 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
guard let me = self else { return } guard let me = self else { return }
me.isViewRotating = false me.isViewRotating = false
me.currentIndex = me.pageBeforeRotate me.currentIndex = me.pageBeforeRotate
me.preCurrentIndex = me.currentIndex
me.updateIfNeeded() me.updateIfNeeded()
} }
} }
// MARK: Private
//MARK: Private
private func progressiveIndicatorData(_ virtualPage: Int) -> (Int, Int, CGFloat) { private func progressiveIndicatorData(_ virtualPage: Int) -> (Int, Int, CGFloat) {
let count = viewControllers.count let count = viewControllers.count
var fromIndex = currentIndex var fromIndex = currentIndex
var toIndex = currentIndex var toIndex = currentIndex
let direction = swipeDirection let direction = swipeDirection
if direction == .left { if direction == .left {
if virtualPage > count - 1 { if virtualPage > count - 1 {
fromIndex = count - 1 fromIndex = count - 1
toIndex = count toIndex = count
} } else {
else {
if self.scrollPercentage >= 0.5 { if self.scrollPercentage >= 0.5 {
fromIndex = max(toIndex - 1, 0) fromIndex = max(toIndex - 1, 0)
} } else {
else {
toIndex = fromIndex + 1 toIndex = fromIndex + 1
} }
} }
} } else if direction == .right {
else if direction == .right {
if virtualPage < 0 { if virtualPage < 0 {
fromIndex = 0 fromIndex = 0
toIndex = -1 toIndex = -1
} } else {
else {
if self.scrollPercentage > 0.5 { if self.scrollPercentage > 0.5 {
fromIndex = min(toIndex + 1, count - 1) fromIndex = min(toIndex + 1, count - 1)
} } else {
else {
toIndex = fromIndex - 1 toIndex = fromIndex - 1
} }
} }
@ -377,26 +371,26 @@ open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate {
let scrollPercentage = pagerBehaviour.isElasticIndicatorLimit ? self.scrollPercentage : ((toIndex < 0 || toIndex >= count) ? 0.0 : self.scrollPercentage) let scrollPercentage = pagerBehaviour.isElasticIndicatorLimit ? self.scrollPercentage : ((toIndex < 0 || toIndex >= count) ? 0.0 : self.scrollPercentage)
return (fromIndex, toIndex, scrollPercentage) return (fromIndex, toIndex, scrollPercentage)
} }
private func reloadViewControllers(){ private func reloadViewControllers() {
guard let dataSource = datasource else { guard let dataSource = datasource else {
fatalError("dataSource must not be nil") fatalError("dataSource must not be nil")
} }
viewControllers = dataSource.viewControllers(for: self) viewControllers = dataSource.viewControllers(for: self)
// viewControllers // viewControllers
guard viewControllers.count != 0 else { guard !viewControllers.isEmpty else {
fatalError("viewControllers(for:) should provide at least one child view controller") fatalError("viewControllers(for:) should provide at least one child view controller")
} }
viewControllers.forEach { if !($0 is IndicatorInfoProvider) { fatalError("Every view controller provided by PagerTabStripDataSource's viewControllers(for:) method must conform to InfoProvider") }} viewControllers.forEach { if !($0 is IndicatorInfoProvider) { fatalError("Every view controller provided by PagerTabStripDataSource's viewControllers(for:) method must conform to IndicatorInfoProvider") }}
} }
private var pagerTabStripChildViewControllersForScrolling : [UIViewController]? private var pagerTabStripChildViewControllersForScrolling: [UIViewController]?
private var lastPageNumber = 0 private var lastPageNumber = 0
private var lastContentOffset: CGFloat = 0.0 private var lastContentOffset: CGFloat = 0.0
private var pageBeforeRotate = 0 private var pageBeforeRotate = 0
private var lastSize = CGSize(width: 0, height: 0) private var lastSize = CGSize(width: 0, height: 0)
internal var isViewRotating = false internal var isViewRotating = false
internal var isViewAppearing = false internal var isViewAppearing = false
} }

View File

@ -1,7 +1,7 @@
// SegmentedPagerTabStripViewController.swift // SegmentedPagerTabStripViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -25,40 +25,40 @@
import Foundation import Foundation
public struct SegmentedPagerTabStripSettings { public struct SegmentedPagerTabStripSettings {
public struct Style { public struct Style {
public var segmentedControlColor: UIColor? public var segmentedControlColor: UIColor?
} }
public var style = Style() public var style = Style()
} }
open class SegmentedPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripDelegate { open class SegmentedPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripDelegate {
@IBOutlet weak public var segmentedControl: UISegmentedControl! @IBOutlet weak public var segmentedControl: UISegmentedControl!
open var settings = SegmentedPagerTabStripSettings() open var settings = SegmentedPagerTabStripSettings()
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
pagerBehaviour = PagerTabStripBehaviour.common(skipIntermediateViewControllers: true) pagerBehaviour = PagerTabStripBehaviour.common(skipIntermediateViewControllers: true)
delegate = self delegate = self
datasource = self datasource = self
} }
required public init?(coder aDecoder: NSCoder) { required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) super.init(coder: aDecoder)
pagerBehaviour = PagerTabStripBehaviour.common(skipIntermediateViewControllers: true) pagerBehaviour = PagerTabStripBehaviour.common(skipIntermediateViewControllers: true)
delegate = self delegate = self
datasource = self datasource = self
} }
private(set) var shouldUpdateSegmentedControl = true private(set) var shouldUpdateSegmentedControl = true
open override func viewDidLoad() { open override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
segmentedControl = segmentedControl ?? UISegmentedControl() let auxSegmentedControl = segmentedControl ?? UISegmentedControl()
segmentedControl = auxSegmentedControl
if segmentedControl.superview == nil { if segmentedControl.superview == nil {
navigationItem.titleView = segmentedControl navigationItem.titleView = segmentedControl
} }
@ -66,35 +66,34 @@ open class SegmentedPagerTabStripViewController: PagerTabStripViewController, Pa
segmentedControl.addTarget(self, action: #selector(SegmentedPagerTabStripViewController.segmentedControlChanged(_:)), for: .valueChanged) segmentedControl.addTarget(self, action: #selector(SegmentedPagerTabStripViewController.segmentedControlChanged(_:)), for: .valueChanged)
reloadSegmentedControl() reloadSegmentedControl()
} }
open override func reloadPagerTabStripView() { open override func reloadPagerTabStripView() {
super.reloadPagerTabStripView() super.reloadPagerTabStripView()
if isViewLoaded { if isViewLoaded {
reloadSegmentedControl() reloadSegmentedControl()
} }
} }
func reloadSegmentedControl() { func reloadSegmentedControl() {
segmentedControl.removeAllSegments() segmentedControl.removeAllSegments()
for (index, item) in viewControllers.enumerated(){ for (index, item) in viewControllers.enumerated() {
let child = item as! IndicatorInfoProvider let child = item as! IndicatorInfoProvider // swiftlint:disable:this force_cast
if let image = child.indicatorInfo(for: self).image { if let image = child.indicatorInfo(for: self).image {
segmentedControl.insertSegment(with: image, at: index, animated: false) segmentedControl.insertSegment(with: image, at: index, animated: false)
} } else {
else {
segmentedControl.insertSegment(withTitle: child.indicatorInfo(for: self).title, at: index, animated: false) segmentedControl.insertSegment(withTitle: child.indicatorInfo(for: self).title, at: index, animated: false)
} }
} }
segmentedControl.selectedSegmentIndex = currentIndex segmentedControl.selectedSegmentIndex = currentIndex
} }
func segmentedControlChanged(_ sender: UISegmentedControl) { @objc func segmentedControlChanged(_ sender: UISegmentedControl) {
let index = sender.selectedSegmentIndex let index = sender.selectedSegmentIndex
updateIndicator(for: self, fromIndex: currentIndex, toIndex: index) updateIndicator(for: self, fromIndex: currentIndex, toIndex: index)
shouldUpdateSegmentedControl = false shouldUpdateSegmentedControl = false
moveToViewController(at: index) moveToViewController(at: index)
} }
// MARK: - PagerTabStripDelegate // MARK: - PagerTabStripDelegate
open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) { open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) {
@ -102,9 +101,9 @@ open class SegmentedPagerTabStripViewController: PagerTabStripViewController, Pa
segmentedControl.selectedSegmentIndex = toIndex segmentedControl.selectedSegmentIndex = toIndex
} }
} }
// MARK: - UIScrollViewDelegate // MARK: - UIScrollViewDelegate
open override func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { open override func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
super.scrollViewDidEndScrollingAnimation(scrollView) super.scrollViewDidEndScrollingAnimation(scrollView)
shouldUpdateSegmentedControl = true shouldUpdateSegmentedControl = true

View File

@ -1,7 +1,7 @@
// SwipeDirection.swift // SwipeDirection.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy

View File

@ -1,7 +1,7 @@
// TwitterPagerTabStripViewController.swift // TwitterPagerTabStripViewController.swift
// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) // XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip )
// //
// Copyright (c) 2016 Xmartlabs ( http://xmartlabs.com ) // Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com )
// //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@ -25,7 +25,7 @@
import Foundation import Foundation
public struct TwitterPagerTabStripSettings { public struct TwitterPagerTabStripSettings {
public struct Style { public struct Style {
public var dotColor = UIColor(white: 1, alpha: 0.4) public var dotColor = UIColor(white: 1, alpha: 0.4)
public var selectedDotColor = UIColor.white public var selectedDotColor = UIColor.white
@ -33,38 +33,38 @@ public struct TwitterPagerTabStripSettings {
public var landscapeTitleFont = UIFont.systemFont(ofSize: 15) public var landscapeTitleFont = UIFont.systemFont(ofSize: 15)
public var titleColor = UIColor.white public var titleColor = UIColor.white
} }
public var style = Style() public var style = Style()
} }
open class TwitterPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate { open class TwitterPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate {
open var settings = TwitterPagerTabStripSettings() open var settings = TwitterPagerTabStripSettings()
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
pagerBehaviour = .progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true) pagerBehaviour = .progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true)
delegate = self delegate = self
datasource = self datasource = self
} }
required public init?(coder aDecoder: NSCoder) { required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) super.init(coder: aDecoder)
pagerBehaviour = .progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true) pagerBehaviour = .progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true)
delegate = self delegate = self
datasource = self datasource = self
} }
open override func viewDidLoad() { open override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
if titleView.superview == nil { if titleView.superview == nil {
navigationItem.titleView = titleView navigationItem.titleView = titleView
} }
// keep watching the frame of titleView // keep watching the frame of titleView
titleView.addObserver(self, forKeyPath: "frame", options: [.new, .old], context: nil) titleView.addObserver(self, forKeyPath: "frame", options: [.new, .old], context: nil)
guard let navigationController = navigationController else { guard let navigationController = navigationController else {
fatalError("TwitterPagerTabStripViewController should be embedded in a UINavigationController") fatalError("TwitterPagerTabStripViewController should be embedded in a UINavigationController")
} }
@ -77,25 +77,23 @@ open class TwitterPagerTabStripViewController: PagerTabStripViewController, Page
open override func reloadPagerTabStripView() { open override func reloadPagerTabStripView() {
super.reloadPagerTabStripView() super.reloadPagerTabStripView()
guard isViewLoaded else { return } guard isViewLoaded else { return }
reloadNavigationViewItems() reloadNavigationViewItems()
setNavigationViewItemsPosition(updateAlpha: true) setNavigationViewItemsPosition(updateAlpha: true)
} }
// MARK: - PagerTabStripDelegate // MARK: - PagerTabStripDelegate
open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) { open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) {
// move indicator scroll view // move indicator scroll view
let distance = distanceValue guard let distance = distanceValue else { return }
var xOffset: CGFloat = 0 var xOffset: CGFloat = 0
if fromIndex < toIndex { if fromIndex < toIndex {
xOffset = distance * CGFloat(fromIndex) + distance * progressPercentage xOffset = distance * CGFloat(fromIndex) + distance * progressPercentage
} } else if fromIndex > toIndex {
else if fromIndex > toIndex {
xOffset = distance * CGFloat(fromIndex) - distance * progressPercentage xOffset = distance * CGFloat(fromIndex) - distance * progressPercentage
} } else {
else {
xOffset = distance * CGFloat(fromIndex) xOffset = distance * CGFloat(fromIndex)
} }
@ -111,10 +109,10 @@ open class TwitterPagerTabStripViewController: PagerTabStripViewController, Page
open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) { open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) {
fatalError() fatalError()
} }
open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard object as AnyObject === titleView && keyPath == "frame" && change?[NSKeyValueChangeKey.kindKey] as? UInt == NSKeyValueChange.setting.rawValue else { return } guard object as AnyObject === titleView && keyPath == "frame" && change?[NSKeyValueChangeKey.kindKey] as? UInt == NSKeyValueChange.setting.rawValue else { return }
let oldRect = (change![NSKeyValueChangeKey.oldKey]! as AnyObject).cgRectValue let oldRect = (change![NSKeyValueChangeKey.oldKey]! as AnyObject).cgRectValue
let newRect = (change![NSKeyValueChangeKey.oldKey]! as AnyObject).cgRectValue let newRect = (change![NSKeyValueChangeKey.oldKey]! as AnyObject).cgRectValue
if (oldRect?.equalTo(newRect!))! { if (oldRect?.equalTo(newRect!))! {
@ -122,26 +120,26 @@ open class TwitterPagerTabStripViewController: PagerTabStripViewController, Page
setNavigationViewItemsPosition(updateAlpha: true) setNavigationViewItemsPosition(updateAlpha: true)
} }
} }
deinit { deinit {
if isViewLoaded { if isViewLoaded {
titleView.removeObserver(self, forKeyPath: "frame") titleView.removeObserver(self, forKeyPath: "frame")
} }
} }
open override func viewDidLayoutSubviews() { open override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews() super.viewDidLayoutSubviews()
setNavigationViewItemsPosition(updateAlpha: false) setNavigationViewItemsPosition(updateAlpha: false)
} }
// MARK: - Helpers // MARK: - Helpers
private lazy var titleView: UIView = { private lazy var titleView: UIView = {
let navigationView = UIView() let navigationView = UIView()
navigationView.autoresizingMask = [.flexibleWidth, .flexibleHeight] navigationView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
return navigationView return navigationView
}() }()
private lazy var titleScrollView: UIScrollView = { [unowned self] in private lazy var titleScrollView: UIScrollView = { [unowned self] in
let titleScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 44)) let titleScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 44))
titleScrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight] titleScrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
@ -156,7 +154,7 @@ open class TwitterPagerTabStripViewController: PagerTabStripViewController, Page
titleScrollView.alwaysBounceVertical = false titleScrollView.alwaysBounceVertical = false
return titleScrollView return titleScrollView
}() }()
private lazy var pageControl: FXPageControl = { [unowned self] in private lazy var pageControl: FXPageControl = { [unowned self] in
let pageControl = FXPageControl() let pageControl = FXPageControl()
pageControl.backgroundColor = .clear pageControl.backgroundColor = .clear
@ -167,7 +165,7 @@ open class TwitterPagerTabStripViewController: PagerTabStripViewController, Page
pageControl.isUserInteractionEnabled = false pageControl.isUserInteractionEnabled = false
return pageControl return pageControl
}() }()
private var childTitleLabels = [UILabel]() private var childTitleLabels = [UILabel]()
private func reloadNavigationViewItems() { private func reloadNavigationViewItems() {
@ -175,9 +173,9 @@ open class TwitterPagerTabStripViewController: PagerTabStripViewController, Page
childTitleLabels.forEach { $0.removeFromSuperview() } childTitleLabels.forEach { $0.removeFromSuperview() }
childTitleLabels.removeAll() childTitleLabels.removeAll()
for (index, item) in viewControllers.enumerated() { for (index, item) in viewControllers.enumerated() {
let child = item as! IndicatorInfoProvider let child = item as! IndicatorInfoProvider // swiftlint:disable:this force_cast
let indicatorInfo = child.indicatorInfo(for: self) let indicatorInfo = child.indicatorInfo(for: self)
let navTitleLabel : UILabel = { let navTitleLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.text = indicatorInfo.title label.text = indicatorInfo.title
label.font = UIApplication.shared.statusBarOrientation.isPortrait ? settings.style.portraitTitleFont : settings.style.landscapeTitleFont label.font = UIApplication.shared.statusBarOrientation.isPortrait ? settings.style.portraitTitleFont : settings.style.landscapeTitleFont
@ -191,9 +189,9 @@ open class TwitterPagerTabStripViewController: PagerTabStripViewController, Page
childTitleLabels.append(navTitleLabel) childTitleLabels.append(navTitleLabel)
} }
} }
private func setNavigationViewItemsPosition(updateAlpha: Bool) { private func setNavigationViewItemsPosition(updateAlpha: Bool) {
let distance = distanceValue guard let distance = distanceValue else { return }
let isPortrait = UIApplication.shared.statusBarOrientation.isPortrait let isPortrait = UIApplication.shared.statusBarOrientation.isPortrait
let navBarHeight: CGFloat = navigationController!.navigationBar.frame.size.height let navBarHeight: CGFloat = navigationController!.navigationBar.frame.size.height
for (index, label) in childTitleLabels.enumerated() { for (index, label) in childTitleLabels.enumerated() {
@ -207,32 +205,30 @@ open class TwitterPagerTabStripViewController: PagerTabStripViewController, Page
label.frame = CGRect(x: originX, y: originY - 2, width: viewSize.width, height: viewSize.height) label.frame = CGRect(x: originX, y: originY - 2, width: viewSize.width, height: viewSize.height)
label.tag = index label.tag = index
} }
let xOffset = distance * CGFloat(currentIndex) let xOffset = distance * CGFloat(currentIndex)
titleScrollView.contentOffset = CGPoint(x: xOffset, y: 0) titleScrollView.contentOffset = CGPoint(x: xOffset, y: 0)
pageControl.numberOfPages = childTitleLabels.count pageControl.numberOfPages = childTitleLabels.count
pageControl.currentPage = currentIndex pageControl.currentPage = currentIndex
let viewSize = pageControl.sizeForNumber(ofPages: childTitleLabels.count) let viewSize = pageControl.sizeForNumber(ofPages: childTitleLabels.count)
let originX = distance - viewSize.width / 2 let originX = distance - viewSize.width / 2
pageControl.frame = CGRect(x: originX, y: navBarHeight - 10, width: viewSize.width, height: viewSize.height) pageControl.frame = CGRect(x: originX, y: navBarHeight - 10, width: viewSize.width, height: viewSize.height)
} }
private func setAlphaWith(offset: CGFloat, andDistance distance: CGFloat) { private func setAlphaWith(offset: CGFloat, andDistance distance: CGFloat) {
for (index, label) in childTitleLabels.enumerated() { for (index, label) in childTitleLabels.enumerated() {
label.alpha = { label.alpha = {
if offset < distance * CGFloat(index) { if offset < distance * CGFloat(index) {
return (offset - distance * CGFloat(index - 1)) / distance return (offset - distance * CGFloat(index - 1)) / distance
} } else {
else {
return 1 - ((offset - distance * CGFloat(index)) / distance) return 1 - ((offset - distance * CGFloat(index)) / distance)
} }
}() }()
} }
} }
private var distanceValue: CGFloat { private var distanceValue: CGFloat? {
let middle = navigationController!.navigationBar.convert(navigationController!.navigationBar.center, to: titleView) return navigationController.map { $0.navigationBar.convert($0.navigationBar.center, to: titleView) }?.x
return middle.x
} }
} }

View File

@ -9,27 +9,27 @@ import XCTest
@testable import XLPagerTabStrip @testable import XLPagerTabStrip
class XLPagerTabStripTests: XCTestCase { class XLPagerTabStripTests: XCTestCase {
override func setUp() { override func setUp() {
super.setUp() super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class. // Put setup code here. This method is called before the invocation of each test method in the class.
} }
override func tearDown() { override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class. // Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown() super.tearDown()
} }
func testExample() { func testExample() {
// This is an example of a functional test case. // This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results. // Use XCTAssert and related functions to verify your tests produce the correct results.
} }
func testPerformanceExample() { func testPerformanceExample() {
// This is an example of a performance test case. // This is an example of a performance test case.
self.measure { self.measure {
// Put the code you want to measure the time of here. // Put the code you want to measure the time of here.
} }
} }
} }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = "XLPagerTabStrip" s.name = "XLPagerTabStrip"
s.version = "6.0.0" s.version = "8.0.1"
s.summary = "Android PagerTabStrip for iOS and much more." s.summary = "Android PagerTabStrip for iOS and much more."
s.homepage = "https://github.com/xmartlabs/XLPagerTabStrip" s.homepage = "https://github.com/xmartlabs/XLPagerTabStrip"
s.license = { type: 'MIT', file: 'LICENSE' } s.license = { type: 'MIT', file: 'LICENSE' }
@ -9,7 +9,8 @@ Pod::Spec.new do |s|
s.social_media_url = 'https://twitter.com/xmartlabs' s.social_media_url = 'https://twitter.com/xmartlabs'
s.ios.deployment_target = '8.0' s.ios.deployment_target = '8.0'
s.requires_arc = true s.requires_arc = true
s.ios.source_files = 'Sources/**/*' s.ios.source_files = 'Sources/**/*.{h,m,swift}'
s.ios.frameworks = 'UIKit', 'Foundation' s.ios.frameworks = 'UIKit', 'Foundation'
s.resource_bundles = { 'XLPagerTabStrip' => ['Sources/ButtonCell.xib'] } s.resource_bundles = { 'XLPagerTabStrip' => ['Sources/ButtonCell.xib'] }
s.swift_version = "4.2"
end end

View File

@ -192,6 +192,7 @@
28F828791C494B2C00330CF4 /* Frameworks */, 28F828791C494B2C00330CF4 /* Frameworks */,
28F8287A1C494B2C00330CF4 /* Headers */, 28F8287A1C494B2C00330CF4 /* Headers */,
28F8287B1C494B2C00330CF4 /* Resources */, 28F8287B1C494B2C00330CF4 /* Resources */,
CB25B8F81EBCF0CE00FEB0A2 /* SwiftLint */,
); );
buildRules = ( buildRules = (
); );
@ -227,11 +228,11 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0720; LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0810; LastUpgradeCheck = 0900;
TargetAttributes = { TargetAttributes = {
28F8287C1C494B2C00330CF4 = { 28F8287C1C494B2C00330CF4 = {
CreatedOnToolsVersion = 7.2; CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0800; LastSwiftMigration = 0900;
}; };
28F828861C494B2C00330CF4 = { 28F828861C494B2C00330CF4 = {
CreatedOnToolsVersion = 7.2; CreatedOnToolsVersion = 7.2;
@ -275,6 +276,23 @@
}; };
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
CB25B8F81EBCF0CE00FEB0A2 /* SwiftLint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = SwiftLint;
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
28F828781C494B2C00330CF4 /* Sources */ = { 28F828781C494B2C00330CF4 /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
@ -324,14 +342,20 @@
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@ -360,7 +384,7 @@
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 2.3; SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = ""; VERSION_INFO_PREFIX = "";
@ -375,14 +399,20 @@
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@ -427,7 +457,8 @@
PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.XLPagerTabStrip; PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.XLPagerTabStrip;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0; SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.2;
}; };
name = Debug; name = Debug;
}; };
@ -447,7 +478,8 @@
PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.XLPagerTabStrip; PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.XLPagerTabStrip;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0; SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.2;
}; };
name = Release; name = Release;
}; };
@ -460,7 +492,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.XLPagerTabStripTests; PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.XLPagerTabStripTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0; SWIFT_VERSION = 4.2;
}; };
name = Debug; name = Debug;
}; };
@ -472,7 +504,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.XLPagerTabStripTests; PRODUCT_BUNDLE_IDENTIFIER = com.xmartlabs.XLPagerTabStripTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0; SWIFT_VERSION = 4.2;
}; };
name = Release; name = Release;
}; };

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0810" LastUpgradeVersion = "0900"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@ -26,6 +26,7 @@
buildConfiguration = "Debug" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<Testables> <Testables>
<TestableReference <TestableReference
@ -55,6 +56,7 @@
buildConfiguration = "Debug" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0" launchStyle = "0"
useCustomWorkingDirectory = "NO" useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>