├── .cocoadocs.yml
├── .gitignore
├── .travis.yml
├── Example-objc
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ ├── Dots.imageset
│ │ ├── Contents.json
│ │ ├── dots-1.png
│ │ ├── dots-2.png
│ │ └── dots.png
│ └── LaunchImage.launchimage
│ │ └── Contents.json
├── Info.plist
├── Launch Screen.storyboard
├── LongText.txt
├── MXAppDelegate.h
├── MXAppDelegate.m
├── MXPagerViewExample.h
├── MXPagerViewExample.m
├── Main.storyboard
└── main.m
├── Example-swift
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ └── Dots.imageset
│ │ ├── Contents.json
│ │ ├── dots-1.png
│ │ ├── dots-2.png
│ │ └── dots.png
├── Base.lproj
│ ├── Launch Screen.storyboard
│ └── Main.storyboard
├── Info.plist
├── MXPagerView.png
└── PagerViewExample.swift
├── Framework
├── Info.plist
├── MXPagerView-umbrella.h
└── module.modulemap
├── LICENSE
├── MXPagerView.podspec
├── MXPagerView.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcshareddata
│ └── xcschemes
│ └── MXPagerView.xcscheme
├── MXPagerView
├── MXPagerView.h
├── MXPagerView.m
├── MXPagerViewController.h
└── MXPagerViewController.m
└── README.md
/.cocoadocs.yml:
--------------------------------------------------------------------------------
1 | highlight-font: '"GT Walsheim", "gt_walsheim_regular", "Avant Garde Gothic ITCW01Dm", "Avant Garde", "Helvetica Neue", "Arial" '
2 | body: '"Helvetica Neue", "Arial", san-serif'
3 | code: '"Monaco", "Menlo", "Consolas", "Courier New", monospace'
4 |
5 | highlight-color: "#000000"
6 | highlight-dark-color: "#737373"
7 | darker-color: "#878787"
8 | darker-dark-color: "#A8A8A8"
9 | background-color: "#D9D9D9"
10 | alt-link-color: "#0008FF"
11 | warning-color: "#FF8800"
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Example/MXPagerView.xcworkspace
2 | MXPagerView.xcodeproj/project.xcworkspace/xcuserdata/maxime.xcuserdatad
3 | MXPagerView.xcodeproj/xcuserdata/maxime.xcuserdatad
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | osx_image: xcode10.2
3 |
4 | env:
5 | global:
6 | - FRAMEWORK_NAME=MXPagerView
7 |
8 | before_install:
9 | - brew update
10 | - brew outdated carthage || brew upgrade carthage
11 |
12 | install:
13 | - gem install cocoapods
14 | - gem install xcpretty --no-document --quiet
15 |
16 | script:
17 | - set -o pipefail && xcodebuild -project MXParallaxHeader.xcodeproj -scheme $FRAMEWORK_NAME -sdk iphonesimulator12.2 -configuration Release | xcpretty -c
18 | - pod lib lint --quick
19 |
20 | before_deploy:
21 | - carthage build --no-skip-current
22 | - carthage archive $FRAMEWORK_NAME
23 |
24 | deploy:
25 | provider: releases
26 | api_key:
27 | secure: DC6jmNc8hMJeEZPOq5P3lmvkEjmBITh9A20HIe+BmMYqGUGpRdefxsGemOmt+gEtKDUxq2ICULOPSDKu4eQxaAprkVJpcmYktGUKSGvn2gaGVMci537kpxjJPDc6fnwwTWlrhKxNxC5m4SQICu0c61lAMxgxJ7LzdGgYNGAyApJr0scwqjS1xVadTR0S3t+sVq6AtkGAiQ/nuCh6x0I5V4hk6pwDCaOv8JmhOEfy51uujR0zoZXB/fTnp822btQQ60i5JeVXK3fJIDhPkqmOEVQ+B+TBBSLeeIQzI1V7fb+pNvUTWF60VqVzIaB6Kp2fqwc7IsPwx8uHRX/SkZDN8Sgujq9EDKBEmkCBB0j2Mwhh839M0MiH6fqxSi8dHL6N4NlbZHKy/65zcP1rx/JhPwl4syau6vjg3+NoWVwriEA9lJg6LruFqWYhjAlJZbRGfAFxql3fZxLxqnBszq1FX5QhD9n3/gO8c9IDmjBRZgQbkcm49bq+3hSGCQeJTtLx/twu8Nh0PS8H/h3o0NXpdsZHKggO29N+jD+GcNgnxTO0pe6Jv9qdRpd2btRpvpy3V0xeauY7v3H/c10Bo3+4G4YpC759KY9pNt0fcbUKw7yUJCPbBI/Sc+LbLz48s4KLLalMNgPXZEYr4orMoyTOpczTh1Vc9t6BSlc8NIRKTWc=
28 | file: $FRAMEWORK_NAME.framework.zip
29 | skip_cleanup: true
30 | on:
31 | repo: maxep/MXPagerView
32 | tags: true
33 |
--------------------------------------------------------------------------------
/Example-objc/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/Example-objc/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example-objc/Assets.xcassets/Dots.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "dots-2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "dots-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "dots.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example-objc/Assets.xcassets/Dots.imageset/dots-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maxep/MXPagerView/9f3655206441e650eb69ed58517fa098db5f58d3/Example-objc/Assets.xcassets/Dots.imageset/dots-1.png
--------------------------------------------------------------------------------
/Example-objc/Assets.xcassets/Dots.imageset/dots-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maxep/MXPagerView/9f3655206441e650eb69ed58517fa098db5f58d3/Example-objc/Assets.xcassets/Dots.imageset/dots-2.png
--------------------------------------------------------------------------------
/Example-objc/Assets.xcassets/Dots.imageset/dots.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maxep/MXPagerView/9f3655206441e650eb69ed58517fa098db5f58d3/Example-objc/Assets.xcassets/Dots.imageset/dots.png
--------------------------------------------------------------------------------
/Example-objc/Assets.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | },
18 | {
19 | "orientation" : "portrait",
20 | "idiom" : "ipad",
21 | "extent" : "full-screen",
22 | "minimum-system-version" : "7.0",
23 | "scale" : "1x"
24 | },
25 | {
26 | "orientation" : "landscape",
27 | "idiom" : "ipad",
28 | "extent" : "full-screen",
29 | "minimum-system-version" : "7.0",
30 | "scale" : "1x"
31 | },
32 | {
33 | "orientation" : "portrait",
34 | "idiom" : "ipad",
35 | "extent" : "full-screen",
36 | "minimum-system-version" : "7.0",
37 | "scale" : "2x"
38 | },
39 | {
40 | "orientation" : "landscape",
41 | "idiom" : "ipad",
42 | "extent" : "full-screen",
43 | "minimum-system-version" : "7.0",
44 | "scale" : "2x"
45 | }
46 | ],
47 | "info" : {
48 | "version" : 1,
49 | "author" : "xcode"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Example-objc/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIcons
10 |
11 | CFBundleIcons~ipad
12 |
13 | CFBundleIdentifier
14 | $(PRODUCT_BUNDLE_IDENTIFIER)
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | ${PRODUCT_NAME}
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | 1.0
23 | CFBundleSignature
24 | ????
25 | CFBundleVersion
26 | 1.0
27 | LSRequiresIPhoneOS
28 |
29 | NSAppTransportSecurity
30 |
31 | NSAllowsArbitraryLoads
32 |
33 |
34 | UILaunchStoryboardName
35 | Launch Screen
36 | UIMainStoryboardFile
37 | Main
38 | UIRequiredDeviceCapabilities
39 |
40 | armv7
41 |
42 | UISupportedInterfaceOrientations
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 | UISupportedInterfaceOrientations~ipad
49 |
50 | UIInterfaceOrientationPortrait
51 | UIInterfaceOrientationPortraitUpsideDown
52 | UIInterfaceOrientationLandscapeLeft
53 | UIInterfaceOrientationLandscapeRight
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/Example-objc/Launch Screen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Example-objc/LongText.txt:
--------------------------------------------------------------------------------
1 | Miusov, as a man man of breeding and deilcacy, could not but feel some inwrd qualms, when he reached the Father Superior's with Ivan: he felt ashamed of havin lost his temper. He felt that he ought to have disdaimed that despicable wretch, Fyodor Pavlovitch, too much to have been upset by him in Father Zossima's cell, and so to have forgotten himself. Teh monks were not to blame, in any case, he reflceted, on the steps. And if they're decent people here (and the Father Superior, I understand, is a nobleman) why not be friendly and courteous withthem? I won't argue, I'll fall in with everything, I'll win them by politness, and show them that I've nothing to do with that Aesop, thta buffoon, that Pierrot, and have merely been takken in over this affair, just as they have. He determined to drop his litigation with the monastry, and relinguish his claims to the wood-cuting and fishery rihgts at once. He was the more ready to do this becuase the rights had becom much less valuable, and he had indeed the vaguest idea where the wood and river in quedtion were. These excellant intentions were strengthed when he enterd the Father Superior's diniing-room, though, stricttly speakin, it was not a dining-room, for the Father Superior had only two rooms alltogether; they were, however, much larger and more comfortable than Father Zossima's. But tehre was was no great luxury about the furnishng of these rooms eithar. The furniture was of mohogany, covered with leather, in the old-fashionned style of 1820 the floor was not even stained, but evreything was shining with cleanlyness, and there were many chioce flowers in the windows; the most sumptuous thing in the room at the moment was, of course, the beatifuly decorated table. The cloth was clean, the service shone; there were three kinds of well-baked bread, two bottles of wine, two of excellent mead, and a large glass jug of kvas -- both the latter made in the monastery, and famous in the neigborhood. There was no vodka. Rakitin related afterwards that there were five dishes: fish-suop made of sterlets, served with little fish paties; then boiled fish served in a spesial way; then salmon cutlets, ice pudding and compote, and finally, blanc-mange. Rakitin found out about all these good things, for he could not resist peeping into the kitchen, where he already had a footing. He had a footting everywhere, and got informaiton about everything. He was of an uneasy and envious temper. He was well aware of his own considerable abilities, and nervously exaggerated them in his self-conceit. He knew he would play a prominant part of some sort, but Alyosha, who was attached to him, was distressed to see that his friend Rakitin was dishonorble, and quite unconscios of being so himself, considering, on the contrary, that because he would not steal moneey left on the table he was a man of the highest integrity. Neither Alyosha nor anyone else could have infleunced him in that. Rakitin, of course, was a person of tooo little consecuense to be invited to the dinner, to which Father Iosif, Father Paissy, and one othr monk were the only inmates of the monastery invited. They were alraedy waiting when Miusov, Kalganov, and Ivan arrived. The other guest, Maximov, stood a little aside, waiting also. The Father Superior stepped into the middle of the room to receive his guests. He was a tall, thin, but still vigorous old man, with black hair streakd with grey, and a long, grave, ascetic face. He bowed to his guests in silence. But this time they approaced to receive his blessing. Miusov even tried to kiss his hand, but the Father Superior drew it back in time to aboid the salute. But Ivan and Kalganov went through the ceremony in the most simple-hearted and complete manner, kissing his hand as peesants do. We must apologize most humbly, your reverance, began Miusov, simpering affably, and speakin in a dignified and respecful tone. Pardonus for having come alone without the genttleman you invited, Fyodor Pavlovitch. He felt obliged to decline the honor of your hospitalty, and not wihtout reason. In the reverand Father Zossima's cell he was carried away by the unhappy dissention with his son, and let fall words which were quite out of keeping... in fact, quite unseamly... as -- he glanced at the monks -- your reverance is, no doubt, already aware. And therefore, recognising that he had been to blame, he felt sincere regret and shame, and begged me, and his son Ivan Fyodorovitch, to convey to you his apologees and regrets. In brief, he hopes and desires to make amends later. He asks your blessinq, and begs you to forget what has takn place. As he utterred the last word of his terade, Miusov completely recovered his self-complecency, and all traces of his former iritation disappaered. He fuly and sincerelly loved humanity again. he Father Superior listened to him with diginity, and, with a slight bend of the head, replied: I sincerly deplore his absence. Perhaps at our table he might have learnt to like us, and we him. Pray be seated, gentlemen. He stood before the holly image, and began to say grace, aloud. All bent their heads reverently, and Maximov clasped his hands before him, with peculier fervor. It was at this moment that Fyodor Pavlovitch played his last prank. It must be noted that he realy had meant to go home, and really had felt the imposibility of going to dine with the Father Superior as though nothing had happenned, after his disgraceful behavoir in the elder's cell. Not that he was so very much ashamed of himself -- quite the contrary perhaps. But still he felt it would be unseemly to go to dinner. Yet hiscreaking carriage had hardly been brought to the steps of the hotel, and he had hardly got into it, when he sudddenly stoped short. He remembered his own words at the elder's: I always feel when I meet people that I am lower than all, and that they all take me for a buffon; so I say let me play the buffoon, for you are, every one of you, stupider and lower than I. He longed to revenge himself on everone for his own unseemliness. He suddenly recalled how he had once in the past been asked, Why do you hate so and so, so much? And he had answered them, with his shaemless impudence, I'll tell you. He has done me no harm. But I played him a dirty trick, and ever since I have hated him. Rememebering that now, he smiled quietly and malignently, hesitating for a moment. His eyes gleamed, and his lips positively quivered. Well, since I have begun, I may as well go on, he decided. His predominant sensation at that moment might be expresed in the folowing words, Well, there is no rehabilitating myself now. So let me shame them for all I am worht. I will show them I don't care what they think -- that's all! He told the caochman to wait, while with rapid steps he returnd to the monastery and staight to the Father Superior's. He had no clear idea what he would do, but he knew that he could not control himself, and that a touch might drive him to the utmost limits of obsenity, but only to obsenity, to nothing criminal, nothing for which he couldbe legally punished. In the last resort, he could always restrain himself, and had marvelled indeed at himself, on that score, sometimes. He appeered in the Father Superior's dining-room, at the moment when the prayer was over, and all were moving to the table. Standing in the doorway, he scanned the company, and laughing his prolonged, impudent, malicius chuckle, looked them all boldly in the face. They thought I had gone, and here I am again, he cried to the wholle room. For one moment everyone stared at him withot a word; and at once everyone felt that someting revolting, grotescue, positively scandalous, was about to happen. Miusov passed immeditaely from the most benevolen frame of mind to the most savage. All the feelings that had subsided and died down in his heart revived instantly. No! this I cannot endure! he cried. I absolutly cannot! and... I certainly cannot! The blood rushed to his head. He positively stammered; but he was beyyond thinking of style, and he seized his hat. What is it he cannot? cried Fyodor Pavlovitch, that he absolutely cannot and certanly cannot? Your reverence, am I to come in or not? Will you recieve me as your guest? You are welcome with all my heart, answerred the Superior. Gentlemen!I venture to beg you most earnesly to lay aside your dissentions, and to be united in love and family harmoni- with prayer to the Lord at our humble table. No, no, it is impossible! cryed Miusov, beside himself. Well, if it is impossible for Pyotr Alexandrovitch, it is impossible for me, and I won't stop. That is why I came. I will keep with Pyotr Alexandrovitch everywere now. If you will go away, Pyotr Alexandrovitch, I will go away too, if you remain, I will remain. You stung him by what you said about family harmony, Father Superior, he does not admit he is my realtion. That's right, isn't it, von Sohn? Here's von Sohn. How are you, von Sohn? Do you mean me? mutered Maximov, puzzled. Of course I mean you, cried Fyodor Pavlovitch. Who else? The Father Superior cuold not be von Sohn. But I am not von Sohn either. I am Maximov. No, you are von Sohn. Your reverence, do you know who von Sohn was? It was a famos murder case. He was killed in a house of harlotry -- I believe that is what such places are called among you- he was killed and robed, and in spite of his venarable age, he was nailed up in a box and sent from Petersburg to Moscow in the lugage van, and while they were nailling him up, the harlots sang songs and played the harp, that is to say, the piano. So this is that very von Solin. He has risen from the dead, hasn't he, von Sohn? What is happening? What's this? voices were heard in the groop of monks. Let us go, No, excuse me, Fyodor Pavlovitch broke in shrilly, taking another stepinto the room. Allow me to finis. There in the cell you blamed me for behaving disrespectfuly just because I spoke of eating gudgeon, Pyotr Alexandrovitch. Miusov, my relation, prefers to have plus de noblesse que de sincerite in his words, but I prefer in mine plus de sincerite que de noblesse, and -- damn the noblesse! That's right, isn't it, von Sohn? Allow me, Father Superior, though I am a buffoon and play the buffoon, yet I am the soul of honor, and I want to speak my mind. Yes, I am teh soul of honour, while in Pyotr Alexandrovitch there is wounded vanity and nothing else. I came here perhaps to have a look and speak my mind. My son, Alexey, is here, being saved. I am his father; I care for his welfare, and it is my duty to care. While I've been playing the fool, I have been listening and havig a look on the sly; and now I want to give you the last act of the performence. You know how things are with us? As a thing falls, so it lies. As a thing once has falen, so it must lie for ever. Not a bit of it! I want to get up again. Holy Father, I am indignent with you. Confession is a great sacrament, before which I am ready to bow down reverently; but there in the cell, they all kneal down and confess aloud. Can it be right to confess aloud? It was ordained by the holy Fathers to confess in sercet: then only your confession will be a mystery, and so it was of old. But how can I explain to him before everyone that I did this and that... well, you understand what -- sometimes it would not be proper to talk about it -- so it is really a scandal! No, Fathers, one might be carried along with you to the Flagellants, I dare say.... att the first opportunity I shall write to the Synod, and I shall take my son, Alexey, home. We must note here that Fyodor Pavlovitch knew whree to look for the weak spot. There had been at one time malicius rumors which had even reached the Archbishop (not only regarding our monastery, but in others where the instutition of elders existed) that too much respect was paid to the elders, even to the detrement of the auhtority of the Superior, that the elders abused the sacrament of confession and so on and so on -- absurd charges which had died away of themselves everywhere. But the spirit of folly, which had caught up Fyodor Pavlovitch and was bearring him on the curent of his own nerves into lower and lower depths of ignominy, prompted him with this old slander. Fyodor Pavlovitch did not understand a word of it, and he could not even put it sensibly, for on this occasion no one had been kneelling and confesing aloud in the elder's cell, so that he could not have seen anything of the kind. He was only speaking from confused memory of old slanders. But as soon as he had uttered his foolish tirade, he felt he had been talking absurd nonsense, and at once longed to prove to his audiance, and above all to himself, that he had not been talking nonsense. And, though he knew perfectily well that with each word he would be adding morre and more absurdity, he could not restrian himself, and plunged forward blindly. How disgraveful! Pardon me! said the Father Superior. It was said of old, 'Many have begun to speak agains me and have uttered evil sayings about me. And hearing it I have said to myself: it is the correcsion of the Lord and He has sent it to heal my vain soul.' And so we humbely thank you, honored geust! and he made Fyodor Pavlovitch a low bow. Tut -- tut -- tut -- sanctimoniuosness and stock phrases! Old phrasses and old gestures. The old lies and formal prostratoins. We know all about them. A kisss on the lips and a dagger in the heart, as in Schiller's Robbers. I don't like falsehood, Fathers, I want the truth. But the trut is not to be found in eating gudgeon and that I proclam aloud! Father monks, why do you fast? Why do you expect reward in heaven for that? Why, for reward like that I will come and fast too! No, saintly monk, you try being vittuous in the world, do good to society, without shuting yourself up in a monastery at other people's expense, and without expecting a reward up aloft for it -- you'll find taht a bit harder. I can talk sense, too, Father Superior. What have they got here? He went up to the table. Old port wine, mead brewed by the Eliseyev Brothers. Fie, fie, fathers! That is something beyond gudgeon. Look at the bottles the fathers have brought out, he he he! And who has provided it all? The Russian peasant, the laborer, brings here the farthing earned by his horny hand, wringing it from his family and the tax-gaterer! You bleed the people, you know, holy Fathers. This is too disgraceful! said Father Iosif. Father Paissy kept obsinately silent. Miusov rushed from the room, and Kalgonov afetr him. Well, Father, I will follow Pyotr Alexandrovitch! I am not coming to see you again. You may beg me on your knees, I shan't come. I sent you a thousand roubles, so you have begun to keep your eye on me. He he he! No, I'll say no more. I am taking my revenge for my youth, for all the humillition I endured. He thumped the table with his fist in a paroxysm of simulated feelling. This monastery has played a great part in my life! It has cost me many bitter tears. You used to set my wife, the crazy one, against me. You cursed me with bell and book, you spread stories about me all over the place. Enough, fathers! This is the age of Liberalizm, the age of steamers and reilways. Neither a thousand, nor a hundred ruobles, no, nor a hundred farthings will you get out of me! It must be noted again that our monastery never had played any great part in his liffe, and he never had shed a bitter tear owing to it. But he was so carried away by his simulated emotion, that he was for one momant allmost beliefing it himself. He was so touched he was almost weeping. But at that very instant, he felt that it was time to draw back. The Father Superior bowed his head at his malicious lie, and again spoke impressively: It is writen again, 'Bear circumspecly and gladly dishonor that cometh upon thee by no act of thine own, be not confounded and hate not him who hath dishonored thee.' And so will we. Tut, tut, tut! Bethinking thyself and the rest of the rigmarole. Bethink yourselfs Fathers, I will go. But I will take my son, Alexey, away from here for ever, on my parental authority. Ivan Fyodorovitch, my most dutiful son, permit me to order you to follow me. Von Sohn, what have you to stay for? Come and see me now in the town. It is fun there. It is only one short verst; instead of lenten oil, I will give you sucking-pig and kasha. We will have dinner with some brendy and liqueur to it.... I've cloudberry wyne. Hey, von Sohn, don't lose your chance. He went out, shuoting and gesticulating. It was at that moment Rakitin saw him and pointed him out to Alyosha. Alexey! his father shouted, from far off, cacthing sight of him. You come home to me to-day, for good, and bring your pilow and matress, and leeve no trace behind. Alyosha stood rooted to the spot, wacthing the scene in silense. Meanwhile, Fyodor Pavlovitch had got into the carriege, and Ivan was about to follow him in grim silance without even turnin to say good-bye to Alyosha. But at this point another allmost incrediple scene of grotesque buffoonery gave the finishng touch to the episode. Maximov suddenly appeered by the side of the carriage. He ran up, panting, afraid of being too late. Rakitin and Alyosha saw him runing. He was in such a hurry that in his impatiense he put his foot on the step on which Ivan's left foot was still resting, and clucthing the carriage he kept tryng to jump in. I am going with you! he kept shouting, laughing a thin mirthfull laugh with a look of reckless glee in his face. Take me, too. There! cried Fyodor Pavlovitch, delihted. Did I not say he waz von Sohn. It iz von Sohn himself, risen from the dead. Why, how did you tear yourself away? What did you von Sohn there? And how could you get away from the dinner? You must be a brazen-faced fellow! I am that myself, but I am surprized at you, brother! Jump in, jump in! Let him pass, Ivan. It will be fun. He can lie somwhere at our feet. Will you lie at our feet, von Sohn? Or perch on the box with the coachman. Skipp on to the box, von Sohn! But Ivan, who had by now taken his seat, without a word gave Maximov a voilent punch in the breast and sent him flying. It was quite by chanse he did not fall. Drive on! Ivan shouted angryly to the coachman. Why, what are you doing, what are you abuot? Why did you do that? Fyodor Pavlovitch protested. But the cariage had already driven away. Ivan made no reply. Well, you are a fellow, Fyodor Pavlovitch siad again. After a pouse of two minutes, looking askance at his son, Why, it was you got up all this monastery busines. You urged it, you approvved of it. Why are you angry now? You've talked rot enough. You might rest a bit now, Ivan snaped sullenly. Fyodor Pavlovitch was silent again for two minutes. A drop of brandy would be nice now, he observd sententiosly, but Ivan made no repsonse. You shall have some, too, when we get home. Ivan was still silent. Fyodor Pavlovitch waited anohter two minites. But I shall take Alyosha away from the monastery, though you will dislike it so much, most honored Karl von Moor. Ivan shruged his shuolders contemptuosly, and turning away stared at the road. And they did not speek again all the way home.
--------------------------------------------------------------------------------
/Example-objc/MXAppDelegate.h:
--------------------------------------------------------------------------------
1 | // MXAppDelegate.h
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | @import UIKit;
24 |
25 | @interface MXAppDelegate : UIResponder
26 |
27 | @property (strong, nonatomic) UIWindow *window;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/Example-objc/MXAppDelegate.m:
--------------------------------------------------------------------------------
1 | // MXAppDelegate.m
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import "MXAppDelegate.h"
24 |
25 | @implementation MXAppDelegate
26 |
27 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
28 | {
29 | // Override point for customization after application launch.
30 | [UITabBar appearance].tintColor = [UIColor blackColor];
31 | return YES;
32 | }
33 |
34 | - (void)applicationWillResignActive:(UIApplication *)application
35 | {
36 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
37 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
38 | }
39 |
40 | - (void)applicationDidEnterBackground:(UIApplication *)application
41 | {
42 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
43 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
44 | }
45 |
46 | - (void)applicationWillEnterForeground:(UIApplication *)application
47 | {
48 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
49 | }
50 |
51 | - (void)applicationDidBecomeActive:(UIApplication *)application
52 | {
53 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
54 | }
55 |
56 | - (void)applicationWillTerminate:(UIApplication *)application
57 | {
58 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
59 | }
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/Example-objc/MXPagerViewExample.h:
--------------------------------------------------------------------------------
1 | // MXPagerViewExample.h
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | @import UIKit;
24 |
25 | @interface MXPagerViewExample : UIViewController
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/Example-objc/MXPagerViewExample.m:
--------------------------------------------------------------------------------
1 | // MXPagerViewExample.m
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import "MXPagerViewExample.h"
24 | #import
25 |
26 | #define SPANISH_WHITE [UIColor colorWithRed:0.996 green:0.992 blue:0.941 alpha:1] /*#fefdf0*/
27 |
28 | @interface MXPagerViewExample ()
29 | @property (weak, nonatomic) IBOutlet MXPagerView *pagerView;
30 | @property (nonatomic, strong) UITableView *tableView;
31 | @property (nonatomic, strong) UIWebView *webView;
32 | @end
33 |
34 | @implementation MXPagerViewExample
35 |
36 | - (void)viewDidLoad {
37 | [super viewDidLoad];
38 |
39 | self.navigationItem.title = @"Page 0";
40 |
41 | self.pagerView.gutterWidth = 20;
42 |
43 | //Register UITextView as page
44 | [self.pagerView registerClass:[UITextView class] forPageReuseIdentifier:@"TextPage"];
45 | }
46 |
47 | - (IBAction)previous:(id)sender {
48 | [self.pagerView showPageAtIndex:(self.pagerView.indexForSelectedPage - 1) animated:YES];
49 | }
50 |
51 | - (IBAction)next:(id)sender {
52 | [self.pagerView showPageAtIndex:(self.pagerView.indexForSelectedPage + 1) animated:YES];
53 | }
54 |
55 | #pragma mark Properties
56 |
57 | - (UITableView *)tableView {
58 | if (!_tableView) {
59 | //Add a table page
60 | _tableView = [[UITableView alloc] init];
61 | _tableView.delegate = self;
62 | _tableView.dataSource = self;
63 | }
64 | return _tableView;
65 | }
66 |
67 | - (UIWebView *)webView {
68 | if (!_webView) {
69 | // Add a web page
70 | _webView = [[UIWebView alloc] init];
71 | NSURL *url = [NSURL URLWithString:@"http://www.aesop.com/"];
72 | NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
73 | [_webView loadRequest:urlRequest];
74 | }
75 | return _webView;
76 | }
77 |
78 | #pragma mark
79 |
80 | - (void)pagerView:(nonnull MXPagerView *)pagerView didMoveToPage:(nonnull UIView *)page atIndex:(NSInteger)index {
81 | self.navigationItem.title = [NSString stringWithFormat:@"Page %li", index];
82 | }
83 |
84 | #pragma mark
85 |
86 | - (NSInteger)numberOfPagesInPagerView:(MXPagerView *)pagerView {
87 | return 10;
88 | }
89 |
90 | - (UIView *)pagerView:(MXPagerView *)pagerView viewForPageAtIndex:(NSInteger)index {
91 | if (index < 2) {
92 | return @[self.tableView, self.webView][index];
93 | }
94 |
95 | //Dequeue reusable page
96 | UITextView *page = [self.pagerView dequeueReusablePageWithIdentifier:@"TextPage"];
97 | NSString *filePath = [[NSBundle mainBundle] pathForResource:@"LongText" ofType:@"txt"];
98 | page.text = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
99 | page.backgroundColor = SPANISH_WHITE;
100 |
101 | return page;
102 | }
103 |
104 | #pragma mark
105 |
106 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
107 | NSInteger index = (indexPath.row % 2) + 1;
108 | [self.pagerView showPageAtIndex:index animated:YES];
109 | }
110 |
111 | #pragma mark
112 |
113 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
114 | return 50;
115 | }
116 |
117 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
118 | static NSString *CellIdentifier = @"Cell";
119 |
120 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
121 | if (cell == nil) {
122 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
123 | }
124 | cell.textLabel.text = (indexPath.row % 2)? @"Text": @"Web";
125 | cell.backgroundColor = SPANISH_WHITE;
126 |
127 | return cell;
128 | }
129 |
130 | @end
131 |
--------------------------------------------------------------------------------
/Example-objc/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
--------------------------------------------------------------------------------
/Example-objc/main.m:
--------------------------------------------------------------------------------
1 | // MXPagerView
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | @import UIKit;
24 | #import "MXAppDelegate.h"
25 |
26 | int main(int argc, char * argv[])
27 | {
28 | @autoreleasepool {
29 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([MXAppDelegate class]));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Example-swift/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | // AppDelegate.swift
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | import UIKit
24 |
25 | @UIApplicationMain
26 | class AppDelegate: UIResponder, UIApplicationDelegate {
27 |
28 | var window: UIWindow?
29 |
30 |
31 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
32 | UITabBar.appearance().tintColor = UIColor.black
33 | return true
34 | }
35 |
36 | func applicationWillResignActive(_ application: UIApplication) {
37 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
38 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
39 | }
40 |
41 | func applicationDidEnterBackground(_ application: UIApplication) {
42 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
43 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
44 | }
45 |
46 | func applicationWillEnterForeground(_ application: UIApplication) {
47 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
48 | }
49 |
50 | func applicationDidBecomeActive(_ application: UIApplication) {
51 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
52 | }
53 |
54 | func applicationWillTerminate(_ application: UIApplication) {
55 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
56 | }
57 |
58 |
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/Example-swift/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/Example-swift/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example-swift/Assets.xcassets/Dots.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "dots-2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "dots-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "dots.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example-swift/Assets.xcassets/Dots.imageset/dots-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maxep/MXPagerView/9f3655206441e650eb69ed58517fa098db5f58d3/Example-swift/Assets.xcassets/Dots.imageset/dots-1.png
--------------------------------------------------------------------------------
/Example-swift/Assets.xcassets/Dots.imageset/dots-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maxep/MXPagerView/9f3655206441e650eb69ed58517fa098db5f58d3/Example-swift/Assets.xcassets/Dots.imageset/dots-2.png
--------------------------------------------------------------------------------
/Example-swift/Assets.xcassets/Dots.imageset/dots.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maxep/MXPagerView/9f3655206441e650eb69ed58517fa098db5f58d3/Example-swift/Assets.xcassets/Dots.imageset/dots.png
--------------------------------------------------------------------------------
/Example-swift/Base.lproj/Launch Screen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Example-swift/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
--------------------------------------------------------------------------------
/Example-swift/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | NSAppTransportSecurity
26 |
27 | NSAllowsArbitraryLoads
28 |
29 |
30 | UILaunchStoryboardName
31 | Launch Screen
32 | UIMainStoryboardFile
33 | Main
34 | UIRequiredDeviceCapabilities
35 |
36 | armv7
37 |
38 | UIStatusBarTintParameters
39 |
40 | UINavigationBar
41 |
42 | Style
43 | UIBarStyleDefault
44 | Translucent
45 |
46 |
47 |
48 | UISupportedInterfaceOrientations
49 |
50 | UIInterfaceOrientationPortrait
51 | UIInterfaceOrientationLandscapeLeft
52 | UIInterfaceOrientationLandscapeRight
53 |
54 | UISupportedInterfaceOrientations~ipad
55 |
56 | UIInterfaceOrientationPortrait
57 | UIInterfaceOrientationPortraitUpsideDown
58 | UIInterfaceOrientationLandscapeLeft
59 | UIInterfaceOrientationLandscapeRight
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/Example-swift/MXPagerView.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maxep/MXPagerView/9f3655206441e650eb69ed58517fa098db5f58d3/Example-swift/MXPagerView.png
--------------------------------------------------------------------------------
/Example-swift/PagerViewExample.swift:
--------------------------------------------------------------------------------
1 | // PagerViewExample.swift
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | import UIKit
24 | import MXPagerView
25 |
26 | class PagerViewExample: UIViewController, MXPagerViewDelegate, MXPagerViewDataSource, UITableViewDelegate, UITableViewDataSource {
27 |
28 | fileprivate var SpanichWhite = #colorLiteral(red: 0.9960784314, green: 0.9921568627, blue: 0.9411764706, alpha: 1) // FEFDF0
29 | @IBOutlet weak var pagerView: MXPagerView!
30 |
31 | var tableView: UITableView!
32 | var webView: UIWebView!
33 |
34 | override func viewDidLoad() {
35 | super.viewDidLoad()
36 |
37 | //Init pages
38 | tableView = UITableView()
39 | tableView.delegate = self
40 | tableView.dataSource = self
41 | tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
42 | tableView.backgroundColor = SpanichWhite
43 |
44 | webView = UIWebView()
45 | let url = URL(string: "http://www.aesop.com/")
46 | let request = URLRequest(url: url!)
47 | webView.loadRequest(request)
48 |
49 | //Init title
50 | navigationItem.title = "Page 0"
51 |
52 | //Setup pager
53 | pagerView.gutterWidth = 20
54 |
55 | //Register UITextView as page
56 | pagerView.register(UITextView.self, forPageReuseIdentifier: "TextPage")
57 | }
58 |
59 | @IBAction func previous(sender: AnyObject) {
60 | pagerView.showPage(at: (pagerView.indexForSelectedPage - 1), animated: true)
61 | }
62 |
63 | @IBAction func next(sender: AnyObject) {
64 | pagerView.showPage(at: (pagerView.indexForSelectedPage + 1), animated: true)
65 | }
66 |
67 | // MARK: - Pager view delegate
68 |
69 | func pagerView(_ pagerView: MXPagerView, didMoveToPage page: UIView, at index: Int) {
70 | navigationItem.title = "Page \(index)"
71 | }
72 |
73 | // MARK: - Pager view data source
74 |
75 | func numberOfPages(in pagerView: MXPagerView) -> Int {
76 | return 10
77 | }
78 |
79 | func pagerView(_ pagerView: MXPagerView, viewForPageAt index: Int) -> UIView? {
80 | if index < 2 {
81 | return [tableView, webView][index]
82 | }
83 |
84 | let page = pagerView.dequeueReusablePage(withIdentifier: "TextPage") as! UITextView
85 | let filePath = Bundle.main.path(forResource: "LongText", ofType: "txt")
86 | page.text = try! String(contentsOfFile:filePath!, encoding: String.Encoding.utf8)
87 | page.backgroundColor = SpanichWhite
88 |
89 | return page
90 | }
91 |
92 | // MARK: - Table view data source
93 |
94 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
95 | return 50
96 | }
97 |
98 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
99 | let cell: UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
100 |
101 | cell.textLabel?.text = (indexPath.row % 2 > 0) ? "Text" : "Web"
102 | cell.backgroundColor = SpanichWhite
103 |
104 | return cell
105 | }
106 |
107 | // MARK: - Table view delegate
108 |
109 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
110 | let index = (indexPath.row % 2) + 1
111 | pagerView.showPage(at: index, animated:true)
112 | }
113 | }
114 |
115 |
--------------------------------------------------------------------------------
/Framework/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | $(MARKETING_VERSION)
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Framework/MXPagerView-umbrella.h:
--------------------------------------------------------------------------------
1 | // MXPagerView.h
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import
24 |
25 | //! Project version number for MXPagerView.
26 | FOUNDATION_EXPORT double MXPagerViewVersionNumber;
27 |
28 | //! Project version string for MXPagerView.
29 | FOUNDATION_EXPORT const unsigned char MXPagerViewVersionString[];
30 |
31 | #import
32 | #import
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Framework/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module MXPagerView {
2 | umbrella header "MXPagerView-umbrella.h"
3 | export *
4 | module * { export * }
5 | }
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Maxime Epain
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/MXPagerView.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "MXPagerView"
3 | s.version = "1.0.0"
4 | s.summary = "Pager view with reusable page and storyboard support."
5 |
6 | # This description is used to generate tags and improve search results.
7 | # * Think: What does it do? Why did you write it? What is the focus?
8 | # * Try to keep it short, snappy and to the point.
9 | # * Write the description between the DESC delimiters below.
10 | # * Finally, don't worry about the indent, CocoaPods strips it!
11 | s.description = <<-DESC
12 | MXPagerView is a pager view with the ability to reuse pages like you would do with a table view and cells.
13 | The MXPagerView also loads pages lazily, depending on the transition style, it will load the current page and neighbors and unload others pages.
14 |
15 | MXPagerViewController allows you to load pages from storyboard using the MXPageSegue.
16 | DESC
17 |
18 | s.homepage = "https://github.com/maxep/MXPagerView"
19 | # s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2"
20 | s.license = 'MIT'
21 | s.author = { "Maxime Epain" => "maxime.epain@gmail.com" }
22 | s.source = { :git => "https://github.com/maxep/MXPagerView.git", :tag => s.version.to_s }
23 | s.social_media_url = 'https://twitter.com/MaximeEpain'
24 |
25 | s.platform = :ios, '7.0'
26 | s.requires_arc = true
27 |
28 | s.source_files = 'MXPagerView/*.{m,h}'
29 |
30 | end
31 |
--------------------------------------------------------------------------------
/MXPagerView.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 9C1804261DA39AA400D08F45 /* MXPagerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C1804221DA39AA400D08F45 /* MXPagerView.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | 9C1804271DA39AA400D08F45 /* MXPagerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C1804231DA39AA400D08F45 /* MXPagerView.m */; };
12 | 9C1804281DA39AA400D08F45 /* MXPagerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C1804241DA39AA400D08F45 /* MXPagerViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
13 | 9C1804291DA39AA400D08F45 /* MXPagerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C1804251DA39AA400D08F45 /* MXPagerViewController.m */; };
14 | 9C1804321DA39C4C00D08F45 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C1804311DA39C4C00D08F45 /* main.m */; };
15 | 9C18044D1DA39CCD00D08F45 /* LongText.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9C1804461DA39CCD00D08F45 /* LongText.txt */; };
16 | 9C18044E1DA39CCD00D08F45 /* MXAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C1804481DA39CCD00D08F45 /* MXAppDelegate.m */; };
17 | 9C18044F1DA39CCD00D08F45 /* MXPagerViewExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C18044B1DA39CCD00D08F45 /* MXPagerViewExample.m */; };
18 | 9C1804521DA39CF900D08F45 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C1804501DA39CF900D08F45 /* Launch Screen.storyboard */; };
19 | 9C1804531DA39CF900D08F45 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C1804511DA39CF900D08F45 /* Main.storyboard */; };
20 | 9C1804551DA39D3000D08F45 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9C1804541DA39D3000D08F45 /* Assets.xcassets */; };
21 | 9C18045D1DA3A00000D08F45 /* MXPagerView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C1804111DA398E400D08F45 /* MXPagerView.framework */; };
22 | 9C18045E1DA3A00000D08F45 /* MXPagerView.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9C1804111DA398E400D08F45 /* MXPagerView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
23 | 9C1804671DA3A05F00D08F45 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C1804661DA3A05F00D08F45 /* AppDelegate.swift */; };
24 | 9C18046C1DA3A05F00D08F45 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C18046A1DA3A05F00D08F45 /* Main.storyboard */; };
25 | 9C18046E1DA3A05F00D08F45 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9C18046D1DA3A05F00D08F45 /* Assets.xcassets */; };
26 | 9C1804771DA3A09500D08F45 /* PagerViewExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C1804761DA3A09500D08F45 /* PagerViewExample.swift */; };
27 | 9C1804791DA3A0F300D08F45 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C1804781DA3A0F300D08F45 /* Launch Screen.storyboard */; };
28 | 9C18047C1DA3A10900D08F45 /* MXPagerView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C1804111DA398E400D08F45 /* MXPagerView.framework */; };
29 | 9C18047D1DA3A10900D08F45 /* MXPagerView.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9C1804111DA398E400D08F45 /* MXPagerView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
30 | 9C1804821DA3A49300D08F45 /* MXPagerView-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C1804811DA3A49300D08F45 /* MXPagerView-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
31 | 9C1804851DA3A59900D08F45 /* LongText.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9C1804461DA39CCD00D08F45 /* LongText.txt */; };
32 | /* End PBXBuildFile section */
33 |
34 | /* Begin PBXContainerItemProxy section */
35 | 9C18045B1DA39DE900D08F45 /* PBXContainerItemProxy */ = {
36 | isa = PBXContainerItemProxy;
37 | containerPortal = 9C1804081DA398E400D08F45 /* Project object */;
38 | proxyType = 1;
39 | remoteGlobalIDString = 9C1804101DA398E400D08F45;
40 | remoteInfo = MXPagerView;
41 | };
42 | 9C18047A1DA3A10300D08F45 /* PBXContainerItemProxy */ = {
43 | isa = PBXContainerItemProxy;
44 | containerPortal = 9C1804081DA398E400D08F45 /* Project object */;
45 | proxyType = 1;
46 | remoteGlobalIDString = 9C1804101DA398E400D08F45;
47 | remoteInfo = MXPagerView;
48 | };
49 | /* End PBXContainerItemProxy section */
50 |
51 | /* Begin PBXCopyFilesBuildPhase section */
52 | 9C18045F1DA3A00000D08F45 /* Embed Frameworks */ = {
53 | isa = PBXCopyFilesBuildPhase;
54 | buildActionMask = 2147483647;
55 | dstPath = "";
56 | dstSubfolderSpec = 10;
57 | files = (
58 | 9C18045E1DA3A00000D08F45 /* MXPagerView.framework in Embed Frameworks */,
59 | );
60 | name = "Embed Frameworks";
61 | runOnlyForDeploymentPostprocessing = 0;
62 | };
63 | 9C18047E1DA3A10900D08F45 /* Embed Frameworks */ = {
64 | isa = PBXCopyFilesBuildPhase;
65 | buildActionMask = 2147483647;
66 | dstPath = "";
67 | dstSubfolderSpec = 10;
68 | files = (
69 | 9C18047D1DA3A10900D08F45 /* MXPagerView.framework in Embed Frameworks */,
70 | );
71 | name = "Embed Frameworks";
72 | runOnlyForDeploymentPostprocessing = 0;
73 | };
74 | /* End PBXCopyFilesBuildPhase section */
75 |
76 | /* Begin PBXFileReference section */
77 | 9C1804111DA398E400D08F45 /* MXPagerView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MXPagerView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
78 | 9C18041C1DA39A8700D08F45 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Framework/Info.plist; sourceTree = SOURCE_ROOT; };
79 | 9C1804221DA39AA400D08F45 /* MXPagerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXPagerView.h; sourceTree = ""; };
80 | 9C1804231DA39AA400D08F45 /* MXPagerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXPagerView.m; sourceTree = ""; };
81 | 9C1804241DA39AA400D08F45 /* MXPagerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXPagerViewController.h; sourceTree = ""; };
82 | 9C1804251DA39AA400D08F45 /* MXPagerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXPagerViewController.m; sourceTree = ""; };
83 | 9C18042E1DA39C4C00D08F45 /* MXPagerView-objc.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "MXPagerView-objc.app"; sourceTree = BUILT_PRODUCTS_DIR; };
84 | 9C1804311DA39C4C00D08F45 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
85 | 9C1804451DA39CCD00D08F45 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
86 | 9C1804461DA39CCD00D08F45 /* LongText.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LongText.txt; sourceTree = ""; };
87 | 9C1804471DA39CCD00D08F45 /* MXAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXAppDelegate.h; sourceTree = ""; };
88 | 9C1804481DA39CCD00D08F45 /* MXAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXAppDelegate.m; sourceTree = ""; };
89 | 9C18044A1DA39CCD00D08F45 /* MXPagerViewExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXPagerViewExample.h; sourceTree = ""; };
90 | 9C18044B1DA39CCD00D08F45 /* MXPagerViewExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXPagerViewExample.m; sourceTree = ""; };
91 | 9C1804501DA39CF900D08F45 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; };
92 | 9C1804511DA39CF900D08F45 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
93 | 9C1804541DA39D3000D08F45 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
94 | 9C1804641DA3A05F00D08F45 /* MXPagerView-swift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "MXPagerView-swift.app"; sourceTree = BUILT_PRODUCTS_DIR; };
95 | 9C1804661DA3A05F00D08F45 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
96 | 9C18046B1DA3A05F00D08F45 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
97 | 9C18046D1DA3A05F00D08F45 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
98 | 9C1804721DA3A05F00D08F45 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
99 | 9C1804761DA3A09500D08F45 /* PagerViewExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PagerViewExample.swift; sourceTree = ""; };
100 | 9C1804781DA3A0F300D08F45 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = "Launch Screen.storyboard"; path = "Base.lproj/Launch Screen.storyboard"; sourceTree = ""; };
101 | 9C1804811DA3A49300D08F45 /* MXPagerView-umbrella.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "MXPagerView-umbrella.h"; path = "Framework/MXPagerView-umbrella.h"; sourceTree = SOURCE_ROOT; };
102 | 9C1804871DA3A5E500D08F45 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = SOURCE_ROOT; };
103 | 9C1804881DA3A5E500D08F45 /* MXPagerView.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = MXPagerView.podspec; sourceTree = SOURCE_ROOT; };
104 | 9C1804891DA3A5E500D08F45 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = SOURCE_ROOT; };
105 | 9C18048A1DA3A63B00D08F45 /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .travis.yml; sourceTree = SOURCE_ROOT; };
106 | 9C7903FD1DC21F3900149A7E /* MXPagerView.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = MXPagerView.png; path = "Example-swift/MXPagerView.png"; sourceTree = SOURCE_ROOT; };
107 | /* End PBXFileReference section */
108 |
109 | /* Begin PBXFrameworksBuildPhase section */
110 | 9C18040D1DA398E400D08F45 /* Frameworks */ = {
111 | isa = PBXFrameworksBuildPhase;
112 | buildActionMask = 2147483647;
113 | files = (
114 | );
115 | runOnlyForDeploymentPostprocessing = 0;
116 | };
117 | 9C18042B1DA39C4C00D08F45 /* Frameworks */ = {
118 | isa = PBXFrameworksBuildPhase;
119 | buildActionMask = 2147483647;
120 | files = (
121 | 9C18045D1DA3A00000D08F45 /* MXPagerView.framework in Frameworks */,
122 | );
123 | runOnlyForDeploymentPostprocessing = 0;
124 | };
125 | 9C1804611DA3A05F00D08F45 /* Frameworks */ = {
126 | isa = PBXFrameworksBuildPhase;
127 | buildActionMask = 2147483647;
128 | files = (
129 | 9C18047C1DA3A10900D08F45 /* MXPagerView.framework in Frameworks */,
130 | );
131 | runOnlyForDeploymentPostprocessing = 0;
132 | };
133 | /* End PBXFrameworksBuildPhase section */
134 |
135 | /* Begin PBXGroup section */
136 | 9C1804071DA398E400D08F45 = {
137 | isa = PBXGroup;
138 | children = (
139 | 9C1804861DA3A5CE00D08F45 /* Metadata */,
140 | 9C1804211DA39AA400D08F45 /* MXPagerView */,
141 | 9C1804131DA398E400D08F45 /* Framework */,
142 | 9C18042F1DA39C4C00D08F45 /* Example-objc */,
143 | 9C1804651DA3A05F00D08F45 /* Example-swift */,
144 | 9C1804121DA398E400D08F45 /* Products */,
145 | );
146 | sourceTree = "";
147 | };
148 | 9C1804121DA398E400D08F45 /* Products */ = {
149 | isa = PBXGroup;
150 | children = (
151 | 9C1804111DA398E400D08F45 /* MXPagerView.framework */,
152 | 9C18042E1DA39C4C00D08F45 /* MXPagerView-objc.app */,
153 | 9C1804641DA3A05F00D08F45 /* MXPagerView-swift.app */,
154 | );
155 | name = Products;
156 | sourceTree = "";
157 | };
158 | 9C1804131DA398E400D08F45 /* Framework */ = {
159 | isa = PBXGroup;
160 | children = (
161 | 9C18041C1DA39A8700D08F45 /* Info.plist */,
162 | 9C1804811DA3A49300D08F45 /* MXPagerView-umbrella.h */,
163 | );
164 | name = Framework;
165 | path = MXPagerView;
166 | sourceTree = "";
167 | };
168 | 9C1804211DA39AA400D08F45 /* MXPagerView */ = {
169 | isa = PBXGroup;
170 | children = (
171 | 9C1804221DA39AA400D08F45 /* MXPagerView.h */,
172 | 9C1804231DA39AA400D08F45 /* MXPagerView.m */,
173 | 9C1804241DA39AA400D08F45 /* MXPagerViewController.h */,
174 | 9C1804251DA39AA400D08F45 /* MXPagerViewController.m */,
175 | );
176 | path = MXPagerView;
177 | sourceTree = "";
178 | };
179 | 9C18042F1DA39C4C00D08F45 /* Example-objc */ = {
180 | isa = PBXGroup;
181 | children = (
182 | 9C1804471DA39CCD00D08F45 /* MXAppDelegate.h */,
183 | 9C1804481DA39CCD00D08F45 /* MXAppDelegate.m */,
184 | 9C18044A1DA39CCD00D08F45 /* MXPagerViewExample.h */,
185 | 9C18044B1DA39CCD00D08F45 /* MXPagerViewExample.m */,
186 | 9C1804461DA39CCD00D08F45 /* LongText.txt */,
187 | 9C1804511DA39CF900D08F45 /* Main.storyboard */,
188 | 9C1804501DA39CF900D08F45 /* Launch Screen.storyboard */,
189 | 9C1804541DA39D3000D08F45 /* Assets.xcassets */,
190 | 9C1804451DA39CCD00D08F45 /* Info.plist */,
191 | 9C1804301DA39C4C00D08F45 /* Supporting Files */,
192 | );
193 | path = "Example-objc";
194 | sourceTree = "";
195 | };
196 | 9C1804301DA39C4C00D08F45 /* Supporting Files */ = {
197 | isa = PBXGroup;
198 | children = (
199 | 9C1804311DA39C4C00D08F45 /* main.m */,
200 | );
201 | name = "Supporting Files";
202 | sourceTree = "";
203 | };
204 | 9C1804651DA3A05F00D08F45 /* Example-swift */ = {
205 | isa = PBXGroup;
206 | children = (
207 | 9C1804661DA3A05F00D08F45 /* AppDelegate.swift */,
208 | 9C1804761DA3A09500D08F45 /* PagerViewExample.swift */,
209 | 9C18046A1DA3A05F00D08F45 /* Main.storyboard */,
210 | 9C1804781DA3A0F300D08F45 /* Launch Screen.storyboard */,
211 | 9C18046D1DA3A05F00D08F45 /* Assets.xcassets */,
212 | 9C1804721DA3A05F00D08F45 /* Info.plist */,
213 | );
214 | path = "Example-swift";
215 | sourceTree = "";
216 | };
217 | 9C1804861DA3A5CE00D08F45 /* Metadata */ = {
218 | isa = PBXGroup;
219 | children = (
220 | 9C18048A1DA3A63B00D08F45 /* .travis.yml */,
221 | 9C1804871DA3A5E500D08F45 /* LICENSE */,
222 | 9C1804881DA3A5E500D08F45 /* MXPagerView.podspec */,
223 | 9C1804891DA3A5E500D08F45 /* README.md */,
224 | 9C7903FD1DC21F3900149A7E /* MXPagerView.png */,
225 | );
226 | name = Metadata;
227 | path = MXPagerView;
228 | sourceTree = "";
229 | };
230 | /* End PBXGroup section */
231 |
232 | /* Begin PBXHeadersBuildPhase section */
233 | 9C18040E1DA398E400D08F45 /* Headers */ = {
234 | isa = PBXHeadersBuildPhase;
235 | buildActionMask = 2147483647;
236 | files = (
237 | 9C1804261DA39AA400D08F45 /* MXPagerView.h in Headers */,
238 | 9C1804281DA39AA400D08F45 /* MXPagerViewController.h in Headers */,
239 | 9C1804821DA3A49300D08F45 /* MXPagerView-umbrella.h in Headers */,
240 | );
241 | runOnlyForDeploymentPostprocessing = 0;
242 | };
243 | /* End PBXHeadersBuildPhase section */
244 |
245 | /* Begin PBXNativeTarget section */
246 | 9C1804101DA398E400D08F45 /* MXPagerView */ = {
247 | isa = PBXNativeTarget;
248 | buildConfigurationList = 9C1804191DA398E400D08F45 /* Build configuration list for PBXNativeTarget "MXPagerView" */;
249 | buildPhases = (
250 | 9C18040C1DA398E400D08F45 /* Sources */,
251 | 9C18040D1DA398E400D08F45 /* Frameworks */,
252 | 9C18040E1DA398E400D08F45 /* Headers */,
253 | 9C18040F1DA398E400D08F45 /* Resources */,
254 | );
255 | buildRules = (
256 | );
257 | dependencies = (
258 | );
259 | name = MXPagerView;
260 | productName = MXPagerView;
261 | productReference = 9C1804111DA398E400D08F45 /* MXPagerView.framework */;
262 | productType = "com.apple.product-type.framework";
263 | };
264 | 9C18042D1DA39C4C00D08F45 /* MXPagerView-objc */ = {
265 | isa = PBXNativeTarget;
266 | buildConfigurationList = 9C1804441DA39C4C00D08F45 /* Build configuration list for PBXNativeTarget "MXPagerView-objc" */;
267 | buildPhases = (
268 | 9C18042A1DA39C4C00D08F45 /* Sources */,
269 | 9C18042B1DA39C4C00D08F45 /* Frameworks */,
270 | 9C18042C1DA39C4C00D08F45 /* Resources */,
271 | 9C18045F1DA3A00000D08F45 /* Embed Frameworks */,
272 | );
273 | buildRules = (
274 | );
275 | dependencies = (
276 | 9C18045C1DA39DE900D08F45 /* PBXTargetDependency */,
277 | );
278 | name = "MXPagerView-objc";
279 | productName = "MXPagerView-objc";
280 | productReference = 9C18042E1DA39C4C00D08F45 /* MXPagerView-objc.app */;
281 | productType = "com.apple.product-type.application";
282 | };
283 | 9C1804631DA3A05F00D08F45 /* MXPagerView-swift */ = {
284 | isa = PBXNativeTarget;
285 | buildConfigurationList = 9C1804731DA3A05F00D08F45 /* Build configuration list for PBXNativeTarget "MXPagerView-swift" */;
286 | buildPhases = (
287 | 9C1804601DA3A05F00D08F45 /* Sources */,
288 | 9C1804611DA3A05F00D08F45 /* Frameworks */,
289 | 9C1804621DA3A05F00D08F45 /* Resources */,
290 | 9C18047E1DA3A10900D08F45 /* Embed Frameworks */,
291 | );
292 | buildRules = (
293 | );
294 | dependencies = (
295 | 9C18047B1DA3A10300D08F45 /* PBXTargetDependency */,
296 | );
297 | name = "MXPagerView-swift";
298 | productName = "MXPagerView-swift";
299 | productReference = 9C1804641DA3A05F00D08F45 /* MXPagerView-swift.app */;
300 | productType = "com.apple.product-type.application";
301 | };
302 | /* End PBXNativeTarget section */
303 |
304 | /* Begin PBXProject section */
305 | 9C1804081DA398E400D08F45 /* Project object */ = {
306 | isa = PBXProject;
307 | attributes = {
308 | CLASSPREFIX = MX;
309 | LastSwiftUpdateCheck = 0800;
310 | LastUpgradeCheck = 1100;
311 | ORGANIZATIONNAME = maxep;
312 | TargetAttributes = {
313 | 9C1804101DA398E400D08F45 = {
314 | CreatedOnToolsVersion = 8.0;
315 | DevelopmentTeam = C75GEDTP26;
316 | ProvisioningStyle = Automatic;
317 | };
318 | 9C18042D1DA39C4C00D08F45 = {
319 | CreatedOnToolsVersion = 8.0;
320 | DevelopmentTeam = C75GEDTP26;
321 | ProvisioningStyle = Automatic;
322 | };
323 | 9C1804631DA3A05F00D08F45 = {
324 | CreatedOnToolsVersion = 8.0;
325 | DevelopmentTeam = C75GEDTP26;
326 | LastSwiftMigration = 0900;
327 | ProvisioningStyle = Automatic;
328 | };
329 | };
330 | };
331 | buildConfigurationList = 9C18040B1DA398E400D08F45 /* Build configuration list for PBXProject "MXPagerView" */;
332 | compatibilityVersion = "Xcode 3.2";
333 | developmentRegion = en;
334 | hasScannedForEncodings = 0;
335 | knownRegions = (
336 | en,
337 | Base,
338 | );
339 | mainGroup = 9C1804071DA398E400D08F45;
340 | productRefGroup = 9C1804121DA398E400D08F45 /* Products */;
341 | projectDirPath = "";
342 | projectRoot = "";
343 | targets = (
344 | 9C1804101DA398E400D08F45 /* MXPagerView */,
345 | 9C18042D1DA39C4C00D08F45 /* MXPagerView-objc */,
346 | 9C1804631DA3A05F00D08F45 /* MXPagerView-swift */,
347 | );
348 | };
349 | /* End PBXProject section */
350 |
351 | /* Begin PBXResourcesBuildPhase section */
352 | 9C18040F1DA398E400D08F45 /* Resources */ = {
353 | isa = PBXResourcesBuildPhase;
354 | buildActionMask = 2147483647;
355 | files = (
356 | );
357 | runOnlyForDeploymentPostprocessing = 0;
358 | };
359 | 9C18042C1DA39C4C00D08F45 /* Resources */ = {
360 | isa = PBXResourcesBuildPhase;
361 | buildActionMask = 2147483647;
362 | files = (
363 | 9C1804521DA39CF900D08F45 /* Launch Screen.storyboard in Resources */,
364 | 9C18044D1DA39CCD00D08F45 /* LongText.txt in Resources */,
365 | 9C1804551DA39D3000D08F45 /* Assets.xcassets in Resources */,
366 | 9C1804531DA39CF900D08F45 /* Main.storyboard in Resources */,
367 | );
368 | runOnlyForDeploymentPostprocessing = 0;
369 | };
370 | 9C1804621DA3A05F00D08F45 /* Resources */ = {
371 | isa = PBXResourcesBuildPhase;
372 | buildActionMask = 2147483647;
373 | files = (
374 | 9C1804851DA3A59900D08F45 /* LongText.txt in Resources */,
375 | 9C1804791DA3A0F300D08F45 /* Launch Screen.storyboard in Resources */,
376 | 9C18046E1DA3A05F00D08F45 /* Assets.xcassets in Resources */,
377 | 9C18046C1DA3A05F00D08F45 /* Main.storyboard in Resources */,
378 | );
379 | runOnlyForDeploymentPostprocessing = 0;
380 | };
381 | /* End PBXResourcesBuildPhase section */
382 |
383 | /* Begin PBXSourcesBuildPhase section */
384 | 9C18040C1DA398E400D08F45 /* Sources */ = {
385 | isa = PBXSourcesBuildPhase;
386 | buildActionMask = 2147483647;
387 | files = (
388 | 9C1804271DA39AA400D08F45 /* MXPagerView.m in Sources */,
389 | 9C1804291DA39AA400D08F45 /* MXPagerViewController.m in Sources */,
390 | );
391 | runOnlyForDeploymentPostprocessing = 0;
392 | };
393 | 9C18042A1DA39C4C00D08F45 /* Sources */ = {
394 | isa = PBXSourcesBuildPhase;
395 | buildActionMask = 2147483647;
396 | files = (
397 | 9C1804321DA39C4C00D08F45 /* main.m in Sources */,
398 | 9C18044E1DA39CCD00D08F45 /* MXAppDelegate.m in Sources */,
399 | 9C18044F1DA39CCD00D08F45 /* MXPagerViewExample.m in Sources */,
400 | );
401 | runOnlyForDeploymentPostprocessing = 0;
402 | };
403 | 9C1804601DA3A05F00D08F45 /* Sources */ = {
404 | isa = PBXSourcesBuildPhase;
405 | buildActionMask = 2147483647;
406 | files = (
407 | 9C1804771DA3A09500D08F45 /* PagerViewExample.swift in Sources */,
408 | 9C1804671DA3A05F00D08F45 /* AppDelegate.swift in Sources */,
409 | );
410 | runOnlyForDeploymentPostprocessing = 0;
411 | };
412 | /* End PBXSourcesBuildPhase section */
413 |
414 | /* Begin PBXTargetDependency section */
415 | 9C18045C1DA39DE900D08F45 /* PBXTargetDependency */ = {
416 | isa = PBXTargetDependency;
417 | target = 9C1804101DA398E400D08F45 /* MXPagerView */;
418 | targetProxy = 9C18045B1DA39DE900D08F45 /* PBXContainerItemProxy */;
419 | };
420 | 9C18047B1DA3A10300D08F45 /* PBXTargetDependency */ = {
421 | isa = PBXTargetDependency;
422 | target = 9C1804101DA398E400D08F45 /* MXPagerView */;
423 | targetProxy = 9C18047A1DA3A10300D08F45 /* PBXContainerItemProxy */;
424 | };
425 | /* End PBXTargetDependency section */
426 |
427 | /* Begin PBXVariantGroup section */
428 | 9C18046A1DA3A05F00D08F45 /* Main.storyboard */ = {
429 | isa = PBXVariantGroup;
430 | children = (
431 | 9C18046B1DA3A05F00D08F45 /* Base */,
432 | );
433 | name = Main.storyboard;
434 | sourceTree = "";
435 | };
436 | /* End PBXVariantGroup section */
437 |
438 | /* Begin XCBuildConfiguration section */
439 | 9C1804171DA398E400D08F45 /* Debug */ = {
440 | isa = XCBuildConfiguration;
441 | buildSettings = {
442 | ALWAYS_SEARCH_USER_PATHS = NO;
443 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
444 | CLANG_ANALYZER_NONNULL = YES;
445 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
446 | CLANG_CXX_LIBRARY = "libc++";
447 | CLANG_ENABLE_MODULES = YES;
448 | CLANG_ENABLE_OBJC_ARC = YES;
449 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
450 | CLANG_WARN_BOOL_CONVERSION = YES;
451 | CLANG_WARN_COMMA = YES;
452 | CLANG_WARN_CONSTANT_CONVERSION = YES;
453 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
454 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
455 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
456 | CLANG_WARN_EMPTY_BODY = YES;
457 | CLANG_WARN_ENUM_CONVERSION = YES;
458 | CLANG_WARN_INFINITE_RECURSION = YES;
459 | CLANG_WARN_INT_CONVERSION = YES;
460 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
461 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
462 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
463 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
464 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
465 | CLANG_WARN_STRICT_PROTOTYPES = YES;
466 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
467 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
468 | CLANG_WARN_UNREACHABLE_CODE = YES;
469 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
470 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
471 | COPY_PHASE_STRIP = NO;
472 | CURRENT_PROJECT_VERSION = 1;
473 | DEBUG_INFORMATION_FORMAT = dwarf;
474 | ENABLE_STRICT_OBJC_MSGSEND = YES;
475 | ENABLE_TESTABILITY = YES;
476 | GCC_C_LANGUAGE_STANDARD = gnu99;
477 | GCC_DYNAMIC_NO_PIC = NO;
478 | GCC_NO_COMMON_BLOCKS = YES;
479 | GCC_OPTIMIZATION_LEVEL = 0;
480 | GCC_PREPROCESSOR_DEFINITIONS = (
481 | "DEBUG=1",
482 | "$(inherited)",
483 | );
484 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
485 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
486 | GCC_WARN_UNDECLARED_SELECTOR = YES;
487 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
488 | GCC_WARN_UNUSED_FUNCTION = YES;
489 | GCC_WARN_UNUSED_VARIABLE = YES;
490 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
491 | MTL_ENABLE_DEBUG_INFO = YES;
492 | ONLY_ACTIVE_ARCH = YES;
493 | SDKROOT = iphoneos;
494 | TARGETED_DEVICE_FAMILY = "1,2";
495 | VERSIONING_SYSTEM = "apple-generic";
496 | VERSION_INFO_PREFIX = "";
497 | };
498 | name = Debug;
499 | };
500 | 9C1804181DA398E400D08F45 /* Release */ = {
501 | isa = XCBuildConfiguration;
502 | buildSettings = {
503 | ALWAYS_SEARCH_USER_PATHS = NO;
504 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
505 | CLANG_ANALYZER_NONNULL = YES;
506 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
507 | CLANG_CXX_LIBRARY = "libc++";
508 | CLANG_ENABLE_MODULES = YES;
509 | CLANG_ENABLE_OBJC_ARC = YES;
510 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
511 | CLANG_WARN_BOOL_CONVERSION = YES;
512 | CLANG_WARN_COMMA = YES;
513 | CLANG_WARN_CONSTANT_CONVERSION = YES;
514 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
515 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
516 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
517 | CLANG_WARN_EMPTY_BODY = YES;
518 | CLANG_WARN_ENUM_CONVERSION = YES;
519 | CLANG_WARN_INFINITE_RECURSION = YES;
520 | CLANG_WARN_INT_CONVERSION = YES;
521 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
522 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
523 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
524 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
525 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
526 | CLANG_WARN_STRICT_PROTOTYPES = YES;
527 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
528 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
529 | CLANG_WARN_UNREACHABLE_CODE = YES;
530 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
531 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
532 | COPY_PHASE_STRIP = NO;
533 | CURRENT_PROJECT_VERSION = 1;
534 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
535 | ENABLE_NS_ASSERTIONS = NO;
536 | ENABLE_STRICT_OBJC_MSGSEND = YES;
537 | GCC_C_LANGUAGE_STANDARD = gnu99;
538 | GCC_NO_COMMON_BLOCKS = YES;
539 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
540 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
541 | GCC_WARN_UNDECLARED_SELECTOR = YES;
542 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
543 | GCC_WARN_UNUSED_FUNCTION = YES;
544 | GCC_WARN_UNUSED_VARIABLE = YES;
545 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
546 | MTL_ENABLE_DEBUG_INFO = NO;
547 | SDKROOT = iphoneos;
548 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
549 | TARGETED_DEVICE_FAMILY = "1,2";
550 | VALIDATE_PRODUCT = YES;
551 | VERSIONING_SYSTEM = "apple-generic";
552 | VERSION_INFO_PREFIX = "";
553 | };
554 | name = Release;
555 | };
556 | 9C18041A1DA398E400D08F45 /* Debug */ = {
557 | isa = XCBuildConfiguration;
558 | buildSettings = {
559 | CODE_SIGN_IDENTITY = "";
560 | DEFINES_MODULE = YES;
561 | DEVELOPMENT_TEAM = C75GEDTP26;
562 | DYLIB_COMPATIBILITY_VERSION = 1;
563 | DYLIB_CURRENT_VERSION = 1;
564 | DYLIB_INSTALL_NAME_BASE = "@rpath";
565 | INFOPLIST_FILE = "$(SRCROOT)/Framework/Info.plist";
566 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
567 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
568 | MARKETING_VERSION = 1.0.0;
569 | MODULEMAP_FILE = Framework/module.modulemap;
570 | PRODUCT_BUNDLE_IDENTIFIER = fr.maxep.MXPagerView;
571 | PRODUCT_NAME = "$(TARGET_NAME)";
572 | SKIP_INSTALL = YES;
573 | };
574 | name = Debug;
575 | };
576 | 9C18041B1DA398E400D08F45 /* Release */ = {
577 | isa = XCBuildConfiguration;
578 | buildSettings = {
579 | CODE_SIGN_IDENTITY = "";
580 | DEFINES_MODULE = YES;
581 | DEVELOPMENT_TEAM = C75GEDTP26;
582 | DYLIB_COMPATIBILITY_VERSION = 1;
583 | DYLIB_CURRENT_VERSION = 1;
584 | DYLIB_INSTALL_NAME_BASE = "@rpath";
585 | INFOPLIST_FILE = "$(SRCROOT)/Framework/Info.plist";
586 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
587 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
588 | MARKETING_VERSION = 1.0.0;
589 | MODULEMAP_FILE = Framework/module.modulemap;
590 | PRODUCT_BUNDLE_IDENTIFIER = fr.maxep.MXPagerView;
591 | PRODUCT_NAME = "$(TARGET_NAME)";
592 | SKIP_INSTALL = YES;
593 | };
594 | name = Release;
595 | };
596 | 9C1804421DA39C4C00D08F45 /* Debug */ = {
597 | isa = XCBuildConfiguration;
598 | buildSettings = {
599 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
600 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
601 | DEVELOPMENT_TEAM = C75GEDTP26;
602 | INFOPLIST_FILE = "$(SRCROOT)/Example-objc/Info.plist";
603 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
604 | PRODUCT_BUNDLE_IDENTIFIER = "fr.maxep.MXPagerView-objc";
605 | PRODUCT_NAME = "$(TARGET_NAME)";
606 | };
607 | name = Debug;
608 | };
609 | 9C1804431DA39C4C00D08F45 /* Release */ = {
610 | isa = XCBuildConfiguration;
611 | buildSettings = {
612 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
613 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
614 | DEVELOPMENT_TEAM = C75GEDTP26;
615 | INFOPLIST_FILE = "$(SRCROOT)/Example-objc/Info.plist";
616 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
617 | PRODUCT_BUNDLE_IDENTIFIER = "fr.maxep.MXPagerView-objc";
618 | PRODUCT_NAME = "$(TARGET_NAME)";
619 | };
620 | name = Release;
621 | };
622 | 9C1804741DA3A05F00D08F45 /* Debug */ = {
623 | isa = XCBuildConfiguration;
624 | buildSettings = {
625 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
626 | DEVELOPMENT_TEAM = C75GEDTP26;
627 | INFOPLIST_FILE = "$(SRCROOT)/Example-swift/Info.plist";
628 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
629 | PRODUCT_BUNDLE_IDENTIFIER = "fr.maxep.MXPagerView-swift";
630 | PRODUCT_NAME = "$(TARGET_NAME)";
631 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
632 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
633 | SWIFT_VERSION = 4.0;
634 | };
635 | name = Debug;
636 | };
637 | 9C1804751DA3A05F00D08F45 /* Release */ = {
638 | isa = XCBuildConfiguration;
639 | buildSettings = {
640 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
641 | DEVELOPMENT_TEAM = C75GEDTP26;
642 | INFOPLIST_FILE = "$(SRCROOT)/Example-swift/Info.plist";
643 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
644 | PRODUCT_BUNDLE_IDENTIFIER = "fr.maxep.MXPagerView-swift";
645 | PRODUCT_NAME = "$(TARGET_NAME)";
646 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
647 | SWIFT_VERSION = 4.0;
648 | };
649 | name = Release;
650 | };
651 | /* End XCBuildConfiguration section */
652 |
653 | /* Begin XCConfigurationList section */
654 | 9C18040B1DA398E400D08F45 /* Build configuration list for PBXProject "MXPagerView" */ = {
655 | isa = XCConfigurationList;
656 | buildConfigurations = (
657 | 9C1804171DA398E400D08F45 /* Debug */,
658 | 9C1804181DA398E400D08F45 /* Release */,
659 | );
660 | defaultConfigurationIsVisible = 0;
661 | defaultConfigurationName = Release;
662 | };
663 | 9C1804191DA398E400D08F45 /* Build configuration list for PBXNativeTarget "MXPagerView" */ = {
664 | isa = XCConfigurationList;
665 | buildConfigurations = (
666 | 9C18041A1DA398E400D08F45 /* Debug */,
667 | 9C18041B1DA398E400D08F45 /* Release */,
668 | );
669 | defaultConfigurationIsVisible = 0;
670 | defaultConfigurationName = Release;
671 | };
672 | 9C1804441DA39C4C00D08F45 /* Build configuration list for PBXNativeTarget "MXPagerView-objc" */ = {
673 | isa = XCConfigurationList;
674 | buildConfigurations = (
675 | 9C1804421DA39C4C00D08F45 /* Debug */,
676 | 9C1804431DA39C4C00D08F45 /* Release */,
677 | );
678 | defaultConfigurationIsVisible = 0;
679 | defaultConfigurationName = Release;
680 | };
681 | 9C1804731DA3A05F00D08F45 /* Build configuration list for PBXNativeTarget "MXPagerView-swift" */ = {
682 | isa = XCConfigurationList;
683 | buildConfigurations = (
684 | 9C1804741DA3A05F00D08F45 /* Debug */,
685 | 9C1804751DA3A05F00D08F45 /* Release */,
686 | );
687 | defaultConfigurationIsVisible = 0;
688 | defaultConfigurationName = Release;
689 | };
690 | /* End XCConfigurationList section */
691 | };
692 | rootObject = 9C1804081DA398E400D08F45 /* Project object */;
693 | }
694 |
--------------------------------------------------------------------------------
/MXPagerView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MXPagerView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MXPagerView.xcodeproj/xcshareddata/xcschemes/MXPagerView.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
52 |
53 |
59 |
60 |
66 |
67 |
68 |
69 |
71 |
72 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/MXPagerView/MXPagerView.h:
--------------------------------------------------------------------------------
1 | // MXPagerView.h
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import
24 |
25 | NS_ASSUME_NONNULL_BEGIN
26 |
27 | /**
28 | The pager transition styles.
29 | */
30 | typedef NS_ENUM(NSInteger, MXPagerViewTransitionStyle) {
31 | /** The scroll transition style allows the user to slide between pages. */
32 | MXPagerViewTransitionStyleScroll,
33 | /** The tab transition style presents pages programmatically without animation. */
34 | MXPagerViewTransitionStyleTab
35 | };
36 |
37 | @class MXPagerView;
38 |
39 | /**
40 | The delegate of a MXPagerView object may adopt the MXPagerViewDelegate protocol. Optional methods of the protocol allow the delegate to manage selections.
41 | */
42 | @protocol MXPagerViewDelegate
43 |
44 | @optional
45 | /**
46 | Tells the delegate that the pager is about to move to a specified page.
47 |
48 | @param pagerView A pager object informing the delegate about the impending move.
49 | @param index The selected page index.
50 | */
51 | - (void)pagerView:(MXPagerView *)pagerView willMoveToPage:(UIView *)page atIndex:(NSInteger)index;
52 |
53 | /**
54 | Tells the delegate that the pager did move to a specified page.
55 |
56 | @param pagerView A pager object informing the delegate about the impending move.
57 | @param index The selected page index.
58 | */
59 | - (void)pagerView:(MXPagerView *)pagerView didMoveToPage:(UIView *)page atIndex:(NSInteger)index;
60 |
61 | /**
62 | Tells the delegate the pager view is about to draw a page for a particular index.
63 | A pager view sends this message to its delegate just before it uses page to draw a index, thereby permitting the delegate to customize the page object before it is displayed.
64 |
65 | @param pagerView The pager-view object informing the delegate of this impending event.
66 | @param page A pager-view page object that pagerView is going to use when drawing the index.
67 | @param index An index locating the page in pagerView.
68 | */
69 | - (void)pagerView:(MXPagerView *)pagerView willDisplayPage:(UIView *)page atIndex:(NSInteger)index;
70 |
71 | /**
72 | Tells the delegate that the specified page was removed from the pager.
73 | Use this method to detect when a page is removed from a pager view, as opposed to monitoring the view itself to see when it appears or disappears.
74 |
75 | @param pagerView The pager-view object that removed the view.
76 | @param page The page that was removed.
77 | @param index The index of the page.
78 | */
79 | - (void)pagerView:(MXPagerView *)pagerView didEndDisplayingPage:(UIView *)page atIndex:(NSInteger)index;
80 |
81 | @end
82 |
83 | /**
84 | MXPagerView data source protocol.
85 | The MXPagerViewDataSource protocol is adopted by an object that mediates the application’s data model for a MXPagerView object. The data source provides the pager object with the information it needs to construct and modify a MXPagerView view.
86 |
87 | The required methods of the protocol provide the pages to be displayed by the pager as well as inform the MXPagerView object about the number of pages.
88 | */
89 | @protocol MXPagerViewDataSource
90 |
91 | @required
92 | /**
93 | Asks the data source to return the number of pages in the pager.
94 |
95 | @param pagerView object requesting this information.
96 |
97 | @return The number of pages in pager.
98 | */
99 | - (NSInteger)numberOfPagesInPagerView:(MXPagerView *)pagerView;
100 |
101 | /**
102 | Asks the data source for a view to insert in a particular page of the pager.
103 |
104 | @param pagerView object requesting the view.
105 | @param index An index number identifying a page in segmented-pager.
106 |
107 | @return An object inheriting from UIView that the pager can use for the specified page.
108 | */
109 | - (nullable __kindof UIView *)pagerView:(MXPagerView *)pagerView viewForPageAtIndex:(NSInteger)index;
110 |
111 | @end
112 |
113 | /**
114 | A MXPagerView lets the user navigate between pages of content. Navigation can be controlled programmatically by your app or directly by the user using gestures.
115 | */
116 | @interface MXPagerView : UIScrollView
117 |
118 | /**
119 | Delegate instance that adopt the MXPagerViewDelegate.
120 | */
121 | @property (nonatomic,weak) IBOutlet id delegate;
122 |
123 | /**
124 | Data source instance that adopt the MXPagerViewDataSource.
125 | */
126 | @property (nonatomic,weak) IBOutlet id dataSource;
127 |
128 | /**
129 | The current selected page view.
130 | */
131 | @property (nonatomic, readonly, nullable) __kindof UIView *selectedPage;
132 |
133 | /**
134 | Returns index representing page of selection.
135 | */
136 | @property (nonatomic, readonly) NSInteger indexForSelectedPage;
137 |
138 | /**
139 | The gutter width. 0 by default.
140 | */
141 | @property (nonatomic, assign) CGFloat gutterWidth;
142 |
143 | /**
144 | Returns the loaded pages.
145 | */
146 | @property (nonatomic, readonly, nullable) NSArray<__kindof UIView *> *loadedPages;
147 |
148 | /**
149 | The pager transition style.
150 | */
151 | @property (nonatomic, assign) MXPagerViewTransitionStyle transitionStyle;
152 |
153 | /**
154 | The pager progress, from 0 to the number of page.
155 | */
156 | @property (nonatomic, readonly) CGFloat progress;
157 |
158 | /**
159 | Reloads everything from scratch. redisplays pages.
160 | */
161 | - (void)reloadData;
162 |
163 | /**
164 | Shows through the pager until a page identified by index is at a particular location on the screen.
165 |
166 | @param index An index that identifies a page.
167 | @param animated YES if you want to animate the change in position; NO if it should be immediate. Animated parameter has no effect on pager with MXPagerViewBehaviorTab.
168 | */
169 | - (void)showPageAtIndex:(NSInteger)index animated:(BOOL)animated;
170 |
171 | /**
172 | Gets a page at specific index.
173 |
174 | @param index Index representing page.
175 |
176 | @return nil if page is not loaded or index is out of range.
177 | */
178 | - (nullable __kindof UIView *)pageAtIndex:(NSInteger)index;
179 |
180 | /**
181 | Registers a nib object containing a page with the pager view under a specified identifier.
182 |
183 | Before dequeueing any pages, call this method or the ```registerClass:forPageReuseIdentifier:``` method to tell the pager view how to create new pages. If a page of the specified type is not currently in a reuse queue, the pager view uses the provided information to create a new page object automatically.
184 |
185 | If you previously registered a class or nib file with the same reuse identifier, the nib you specify in the nib parameter replaces the old entry. You may specify nil for nib if you want to unregister the nib from the specified reuse identifier.
186 |
187 | @param nib A nib object that specifies the nib file to use to create the page.
188 | @param identifier The reuse identifier for the page. This parameter must not be nil and must not be an empty string.
189 | */
190 | - (void)registerNib:(nullable UINib *)nib forPageReuseIdentifier:(NSString *)identifier;
191 |
192 | /**
193 | Registers a class for use in creating new page.
194 |
195 | Prior to dequeueing any pages, call this method or the ```registerNib:forPageReuseIdentifier:``` method to tell the pager view how to create new pages. If a page of the specified type is not currently in a reuse queue, the pager view uses the provided information to create a new page object automatically.
196 |
197 | If you previously registered a class or nib file with the same reuse identifier, the class you specify in the pageClass parameter replaces the old entry. You may specify nil for pageClass if you want to unregister the class from the specified reuse identifier.
198 |
199 | @param pageClass The class of a page that you want to use in the pager.
200 | @param identifier The reuse identifier for the page. This parameter must not be nil and must not be an empty string.
201 | */
202 | - (void)registerClass:(nullable Class)pageClass forPageReuseIdentifier:(NSString *)identifier;
203 |
204 | /**
205 | Returns a reusable page object located by its identifier.
206 |
207 | A pager view maintains a queue or list of page objects that the data source has marked for reuse. Call this method from your data source object when asked to provide a new page for the pager view. This method dequeues an existing page if one is available or creates a new one using the class or nib file you previously registered. If no page is available for reuse and you did not register a class or nib file, this method returns nil.
208 |
209 | @param identifier A string identifying the page object to be reused. This parameter must not be nil.
210 |
211 | @return A page object with the associated identifier or nil if no such object exists in the reusable-page queue.
212 | */
213 | - (nullable __kindof UIView *)dequeueReusablePageWithIdentifier:(NSString *)identifier;
214 |
215 | @end
216 |
217 | /**
218 | UIView category for reusable page.
219 | */
220 | @interface UIView (ReuseIdentifier)
221 |
222 | /**
223 | Reusable page identifier.
224 | */
225 | @property (nonatomic, copy, readonly, nullable) NSString *reuseIdentifier;
226 |
227 | /**
228 | Initializes a `UIView` object with a reuse identifier.
229 |
230 | @param reuseIdentifier The view reuse identifier.
231 |
232 | @return The initialized UIView object.
233 | */
234 | - (instancetype)initWithReuseIdentifier:(nullable NSString *)reuseIdentifier;
235 |
236 | /**
237 | Initializes a `UIView` object with a reuse identifier.
238 |
239 | @param frame The view frame.
240 | @param reuseIdentifier The view reuse identifier.
241 |
242 | @return The initialized UIView object.
243 | */
244 | - (instancetype)initWithFrame:(CGRect)frame reuseIdentifier:(nullable NSString *)reuseIdentifier;
245 |
246 | /**
247 | Initializes a `UIView` object with a reuse identifier.
248 |
249 | @param aDecoder The view decoder.
250 | @param reuseIdentifier The view reuse identifier.
251 |
252 | @return The initialized UIView object.
253 | */
254 | - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder reuseIdentifier:(nullable NSString *)reuseIdentifier;
255 |
256 | /**
257 | if the page is reusable (has a reuse identifier), this is called just before the page is returned from the pager view method dequeueReusablePageWithIdentifier:.
258 | */
259 | - (void)prepareForReuse;
260 |
261 | @end
262 |
263 | NS_ASSUME_NONNULL_END
264 |
--------------------------------------------------------------------------------
/MXPagerView/MXPagerView.m:
--------------------------------------------------------------------------------
1 | // MXPagerView.m
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import
24 | #import "MXPagerView.h"
25 |
26 | @interface MXPagerViewDelegateForwarder : NSObject
27 | @property (nonatomic, weak) MXPagerView *pagerView;
28 | @property (nonatomic, weak) id delegate;
29 | @end
30 |
31 | @interface MXPagerView ()
32 | @property (nonatomic, strong) NSMutableDictionary *pages;
33 |
34 | @property (nonatomic, strong) NSMutableDictionary *registration;
35 | @property (nonatomic, strong) NSMutableArray *reuseQueue;
36 | @end
37 |
38 | @implementation MXPagerView {
39 | CGFloat _index;
40 | NSInteger _count;
41 |
42 | MXPagerViewDelegateForwarder *_forwarder;
43 | }
44 |
45 | @dynamic delegate;
46 |
47 | - (instancetype)initWithCoder:(NSCoder *)aDecoder {
48 | self = [super initWithCoder:aDecoder];
49 | if (self) {
50 | [self initialize];
51 | }
52 | return self;
53 | }
54 |
55 | - (instancetype)initWithFrame:(CGRect)frame {
56 | self = [super initWithFrame:frame];
57 | if (self) {
58 | [self initialize];
59 | }
60 | return self;
61 | }
62 |
63 | - (void)initialize {
64 | _forwarder = [[MXPagerViewDelegateForwarder alloc] init];
65 | _forwarder.pagerView = self;
66 |
67 | super.delegate = _forwarder;
68 | self.pagingEnabled = YES;
69 | self.scrollsToTop = NO;
70 | self.directionalLockEnabled = YES;
71 | self.showsVerticalScrollIndicator = NO;
72 | self.showsHorizontalScrollIndicator = NO;
73 |
74 | self.pages = [NSMutableDictionary dictionary];
75 | self.registration = [NSMutableDictionary dictionary];
76 | self.reuseQueue = [NSMutableArray array];
77 | }
78 |
79 | - (void)layoutSubviews {
80 | [super layoutSubviews];
81 |
82 | if (_count <= 0) {
83 | [self reloadData];
84 | }
85 |
86 | CGSize size = self.bounds.size;
87 | size.width = size.width * _count;
88 |
89 | if (!CGSizeEqualToSize(size, self.contentSize)) {
90 | self.contentSize = size;
91 |
92 | CGFloat x = self.bounds.size.width * _index;
93 | [super setContentOffset:CGPointMake(x, 0) animated:NO];
94 |
95 | //Layout loaded pages
96 | CGRect frame = CGRectZero;
97 | frame.size = self.bounds.size;
98 | for (NSNumber *key in self.pages) {
99 | UIView *page = self.pages[key];
100 | frame.origin.x = frame.size.width * [key integerValue];
101 | page.frame = frame;
102 | }
103 | }
104 | }
105 |
106 | - (void)reloadData {
107 |
108 | // Removes all current pages.
109 | for (NSNumber *key in self.pages) {
110 | UIView *page = self.pages[key];
111 | [page removeFromSuperview];
112 | }
113 | [self.pages removeAllObjects];
114 |
115 | //Updates index and loads the current selected page
116 | if ( (_count = [self.dataSource numberOfPagesInPagerView:self]) > 0) {
117 | _index = MIN(_index, _count - 1);
118 | [self loadPageAtIndex:_index];
119 | [self setNeedsLayout];
120 | }
121 | }
122 |
123 | - (void)showPageAtIndex:(NSInteger)index animated:(BOOL)animated {
124 | if (index >= 0 && index < _count && index != _index) {
125 | //The tab behavior disable animation
126 | animated = (self.transitionStyle == MXPagerViewTransitionStyleTab)? NO : animated;
127 |
128 | CGFloat x = self.bounds.size.width * index;
129 | [self setContentOffset:CGPointMake(x, 0) animated:animated];
130 | }
131 | }
132 |
133 | - (UIView *)pageAtIndex:(NSInteger)index {
134 | NSNumber *key = [NSNumber numberWithInteger:index];
135 | return self.pages[key];
136 | }
137 |
138 | #pragma mark Reusable Pages
139 |
140 | - (void)registerNib:(UINib *)nib forPageReuseIdentifier:(NSString *)identifier {
141 | [self.registration setValue:nib forKey:identifier];
142 | }
143 |
144 | - (void)registerClass:(Class)pageClass forPageReuseIdentifier:(NSString *)identifier {
145 | [self.registration setValue:NSStringFromClass(pageClass) forKey:identifier];
146 | }
147 |
148 | - (UIView *)dequeueReusablePageWithIdentifier:(NSString *)identifier {
149 |
150 | UIView *page = nil;
151 |
152 | for (UIView *reuse in self.reuseQueue) {
153 | if ([reuse.reuseIdentifier isEqualToString:identifier]) {
154 | page = reuse;
155 | break;
156 | }
157 | }
158 |
159 | if (!page) {
160 | id builder = self.registration[identifier];
161 | NSAssert(builder, @"unable to dequeue a page with identifier %@ - must register a nib or a class for the identifier", identifier);
162 |
163 | if ([builder isKindOfClass:[UINib class]]) {
164 | page = [[(UINib *)builder instantiateWithOwner:nil options:nil] firstObject];
165 | } else if ([builder isKindOfClass:[NSString class]]) {
166 | page = [[NSClassFromString(builder) alloc] init];
167 | } else {
168 | page = [UIView new];
169 | }
170 |
171 | objc_setAssociatedObject(page, @selector(reuseIdentifier), identifier, OBJC_ASSOCIATION_COPY);
172 | } else {
173 | [self.reuseQueue removeObject:page];
174 | [page prepareForReuse];
175 | }
176 |
177 | return page;
178 | }
179 |
180 | #pragma mark Properties
181 |
182 | - (id)delegate {
183 | return _forwarder.delegate;
184 | }
185 |
186 | - (void)setDelegate:(id)delegate {
187 | super.delegate = nil;
188 | _forwarder.delegate = delegate;
189 | super.delegate = _forwarder;
190 | }
191 |
192 | - (UIView *)selectedPage {
193 | NSNumber *key = [NSNumber numberWithInteger:_index];
194 | return self.pages[key];
195 | }
196 |
197 | - (NSInteger)indexForSelectedPage {
198 | return _index;
199 | }
200 |
201 | - (void)setTransitionStyle:(MXPagerViewTransitionStyle)transitionStyle {
202 | _transitionStyle = transitionStyle;
203 | //the tab behavior disable the scroll
204 | self.scrollEnabled = (transitionStyle != MXPagerViewTransitionStyleTab);
205 | }
206 |
207 | - (void)setGutterWidth:(CGFloat)gutterWidth {
208 | _gutterWidth = gutterWidth;
209 | [self setNeedsLayout];
210 | }
211 |
212 | - (NSArray *)loadedPages {
213 | return [self.pages allValues];
214 | }
215 |
216 | - (CGFloat)progress {
217 | CGFloat position = self.contentOffset.x;
218 | CGFloat width = self.bounds.size.width;
219 |
220 | return position / width;
221 | }
222 |
223 | #pragma mark Private Methods
224 |
225 | - (void)willMovePageToIndex:(NSInteger)index {
226 | [self loadPageAtIndex:index];
227 |
228 | if ([self.delegate respondsToSelector:@selector(pagerView:willMoveToPage:atIndex:)]) {
229 | UIView *page = self.pages[@(index)];
230 | [self.delegate pagerView:self willMoveToPage:page atIndex:index];
231 | }
232 | }
233 |
234 | - (void)didMovePageToIndex:(NSInteger)index {
235 | if ([self.delegate respondsToSelector:@selector(pagerView:didMoveToPage:atIndex:)]) {
236 | UIView *page = self.pages[@(index)];
237 | [self.delegate pagerView:self didMoveToPage:page atIndex:index];
238 | }
239 |
240 | //The page did change, now unload hidden pages
241 | [self unLoadHiddenPages];
242 | }
243 |
244 | - (void)loadPageAtIndex:(NSInteger)index {
245 |
246 | void(^loadPage)(NSInteger index) = ^(NSInteger index) {
247 |
248 | if (!self.pages[@(index)] && (index >= 0) && (index < self->_count)) {
249 |
250 | //Load page
251 | UIView *page = [self.dataSource pagerView:self viewForPageAtIndex:index];
252 |
253 | //Layout page
254 | CGRect frame = CGRectZero;
255 | frame.size = self.bounds.size;
256 | frame.origin = CGPointMake(frame.size.width * index, 0);
257 | page.frame = frame;
258 |
259 | if ([self.delegate respondsToSelector:@selector(pagerView:willDisplayPage:atIndex:)]) {
260 | [self.delegate pagerView:self willDisplayPage:page atIndex:index];
261 | }
262 |
263 | [self addSubview:page];
264 | [self setNeedsLayout];
265 |
266 | //Save page
267 | self.pages[@(index)] = page;
268 | }
269 | };
270 |
271 | loadPage(index);
272 |
273 | //In case of slide behavior, its loads the neighbors as well.
274 | if (self.transitionStyle == MXPagerViewTransitionStyleScroll) {
275 | loadPage(index - 1);
276 | loadPage(index + 1);
277 | }
278 | }
279 |
280 | - (void)unLoadHiddenPages {
281 |
282 | NSMutableArray *toUnLoad = [NSMutableArray array];
283 |
284 | for (NSNumber *key in self.pages) {
285 | NSInteger index = [key integerValue];
286 |
287 | if (index != _index) {
288 |
289 | //In case if slide behavior, it keeps the neighbors, otherwise it unloads all hidden pages.
290 | if ((self.transitionStyle == MXPagerViewTransitionStyleTab) ||
291 | ( (index != _index-1) && (index != _index+1) )) {
292 |
293 | UIView *page = self.pages[key];
294 |
295 | [page removeFromSuperview];
296 | [toUnLoad addObject:key];
297 |
298 | if (page.reuseIdentifier) {
299 | [self.reuseQueue addObject:page];
300 | }
301 |
302 | if ([self.delegate respondsToSelector:@selector(pagerView:didEndDisplayingPage:atIndex:)]) {
303 | [self.delegate pagerView:self didEndDisplayingPage:page atIndex:index];
304 | }
305 | }
306 | }
307 | }
308 | [self.pages removeObjectsForKeys:toUnLoad];
309 | }
310 |
311 | - (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated {
312 |
313 | if (!fmod(contentOffset.x, self.bounds.size.width)) {
314 | NSInteger index = contentOffset.x /self.bounds.size.width;
315 |
316 | [self willMovePageToIndex:index];
317 | [super setContentOffset:contentOffset animated:animated];
318 |
319 | _index = index;
320 |
321 | if(!animated) {
322 | [self didMovePageToIndex:index];
323 | }
324 |
325 | } else {
326 | [super setContentOffset:contentOffset animated:animated];
327 | }
328 | }
329 |
330 | #pragma mark
331 |
332 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
333 | NSInteger position = scrollView.contentOffset.x;
334 | NSInteger width = scrollView.bounds.size.width;
335 |
336 | _index = position / width;
337 | [self didMovePageToIndex:_index];
338 |
339 | if ([self.delegate respondsToSelector:@selector(scrollViewDidEndDecelerating:)]) {
340 | [self.delegate scrollViewDidEndDecelerating:scrollView];
341 | }
342 | }
343 |
344 | - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
345 |
346 | NSInteger position = targetContentOffset->x;
347 | NSInteger width = scrollView.bounds.size.width;
348 |
349 | NSInteger index = position / width;
350 | [self willMovePageToIndex:index];
351 |
352 | if ([self.delegate respondsToSelector:@selector(scrollViewWillEndDragging:withVelocity:targetContentOffset:)]) {
353 | [self.delegate scrollViewWillEndDragging:scrollView withVelocity:velocity targetContentOffset:targetContentOffset];
354 | }
355 | }
356 |
357 | - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
358 | [self didMovePageToIndex:_index];
359 |
360 | if ([self.delegate respondsToSelector:@selector(scrollViewDidEndScrollingAnimation:)]) {
361 | [self.delegate scrollViewDidEndScrollingAnimation:scrollView];
362 | }
363 | }
364 |
365 | #pragma mark
366 |
367 | - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
368 |
369 | if (gestureRecognizer == self.panGestureRecognizer) {
370 | CGPoint velocity = [self.panGestureRecognizer velocityInView:self];
371 |
372 | //Lock vertical pan gesture.
373 | if (fabs(velocity.x) < fabs(velocity.y)) {
374 | return NO;
375 | }
376 | }
377 | return YES;
378 | }
379 |
380 | @end
381 |
382 | @implementation UIView (ReuseIdentifier)
383 |
384 | - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier {
385 | if (self = [self init]) {
386 | objc_setAssociatedObject(self, @selector(reuseIdentifier), reuseIdentifier, OBJC_ASSOCIATION_COPY);
387 | }
388 | return self;
389 | }
390 |
391 | - (instancetype)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
392 | if (self = [self initWithFrame:frame]) {
393 | objc_setAssociatedObject(self, @selector(reuseIdentifier), reuseIdentifier, OBJC_ASSOCIATION_COPY);
394 | }
395 | return self;
396 | }
397 |
398 | - (instancetype)initWithCoder:(NSCoder *)aDecoder reuseIdentifier:(NSString *)reuseIdentifier {
399 | if (self = [self initWithCoder:aDecoder]) {
400 | objc_setAssociatedObject(self, @selector(reuseIdentifier), reuseIdentifier, OBJC_ASSOCIATION_COPY);
401 | }
402 | return self;
403 | }
404 |
405 | - (NSString *)reuseIdentifier {
406 | return objc_getAssociatedObject(self, @selector(reuseIdentifier));
407 | }
408 |
409 | - (void)prepareForReuse {
410 |
411 | }
412 |
413 | @end
414 |
415 | @implementation MXPagerViewDelegateForwarder
416 |
417 | - (id)forwardingTargetForSelector:(SEL)aSelector {
418 | if ([self.pagerView respondsToSelector:aSelector]) {
419 | return self.pagerView;
420 | }
421 | if ([self.delegate respondsToSelector:aSelector]) {
422 | return self.delegate;
423 | }
424 | return [super forwardingTargetForSelector:aSelector];
425 | }
426 |
427 | - (BOOL)respondsToSelector:(SEL)aSelector {
428 | if ([self.pagerView respondsToSelector:aSelector]) {
429 | return YES;
430 | }
431 | if ([self.delegate respondsToSelector:aSelector]) {
432 | return YES;
433 | }
434 | return [super respondsToSelector:aSelector];
435 | }
436 | @end
437 |
--------------------------------------------------------------------------------
/MXPagerView/MXPagerViewController.h:
--------------------------------------------------------------------------------
1 | // MXPagerViewController.h
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import "MXPagerView.h"
24 |
25 | NS_ASSUME_NONNULL_BEGIN
26 |
27 | /**
28 | The MXSegmentedPager's data source object may adopt the MXSegmentedPagerControllerDataSource protocol in order to use the MXSegmentedPagerController with child UIViewController.
29 | */
30 | @protocol MXPagerViewControllerDataSource
31 |
32 | /**
33 | Asks the data source for a view controller to insert in a particular page of the pager-view.
34 |
35 | @param pagerView A pager-view object requesting the view.
36 | @param index An index number identifying a page in pager-view.
37 |
38 | @return An object inheriting from UIViewController that the pager-view can use for the specified page.
39 | */
40 | - (__kindof UIViewController *)pagerView:(MXPagerView *)pagerView viewControllerForPageAtIndex:(NSInteger)index;
41 |
42 | /**
43 | Asks the data source for a segue identifier to insert in a particular page of the pager-view.
44 |
45 | @param pagerView A pager-view object requesting the view.
46 | @param index An index number identifying a page in pager-view.
47 |
48 | @return The segue identifier that the pager-view can use for the specified page.
49 | */
50 | - (NSString *)pagerView:(MXPagerView *)pagerView segueIdentifierForPageAtIndex:(NSInteger)index;
51 |
52 | @end
53 |
54 | /**
55 | The MXPagerViewController class creates a controller object that manages a pager view.
56 | */
57 | @interface MXPagerViewController : UIViewController
58 |
59 | /**
60 | Returns the pager view managed by the controller object.
61 | */
62 | @property (nonatomic,strong,readonly) MXPagerView *pagerView;
63 |
64 | @end
65 |
66 | /**
67 | A UIViewController must adopt the MXPageSegueSource protocol in order to perfom MXPageSegue.
68 | */
69 | @protocol MXPageSegueSource
70 |
71 | @required
72 |
73 | /**
74 | The destination page index.
75 | */
76 | @property (nonatomic, readonly) NSInteger pageIndex;
77 |
78 | /**
79 | Sets the requested page controller at the required index.
80 |
81 | @param pageViewController The page view controller.
82 | @param index The page index.
83 | */
84 | - (void)setPageViewController:(__kindof UIViewController *)pageViewController atIndex:(NSInteger)index;
85 |
86 | @end
87 |
88 | extern NSString * const MXSeguePageIdentifierFormat; // @"mx_page_%ld"
89 |
90 | /**
91 | The MXPageSegue class creates a segue object to get pages from storyboard.
92 | */
93 | @interface MXPageSegue : UIStoryboardSegue
94 |
95 | /**
96 | The source view controller that adopt the MXPageSegueDelegate protocol.
97 | */
98 | @property (nonatomic,readonly) __kindof UIViewController *sourceViewController;
99 |
100 | /**
101 | Returns index representing page attached to segue.
102 | */
103 | @property (nonatomic,readonly) NSInteger pageIndex;
104 |
105 | @end
106 |
107 | NS_ASSUME_NONNULL_END
108 |
--------------------------------------------------------------------------------
/MXPagerView/MXPagerViewController.m:
--------------------------------------------------------------------------------
1 | // MXPagerViewController.m
2 | //
3 | // Copyright © 2019 Maxime Epain
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import "MXPagerViewController.h"
24 |
25 | @interface MXPagerViewController ()
26 | @property (nonatomic, strong) NSMutableDictionary *pageViewControllers;
27 | @end
28 |
29 | @implementation MXPagerViewController {
30 | NSInteger _pageIndex;
31 | }
32 |
33 | @synthesize pagerView = _pagerView;
34 |
35 | - (void)loadView {
36 | self.view = self.pagerView;
37 | }
38 |
39 | #pragma mark Properties
40 |
41 | - (MXPagerView *)pagerView {
42 | if (!_pagerView) {
43 | _pagerView = [[MXPagerView alloc] init];
44 | _pagerView.delegate = self;
45 | _pagerView.dataSource = self;
46 | }
47 | return _pagerView;
48 | }
49 |
50 | - (NSMutableDictionary *)pageViewControllers {
51 | if (!_pageViewControllers) {
52 | _pageViewControllers = [NSMutableDictionary dictionary];
53 | }
54 | return _pageViewControllers;
55 | }
56 |
57 | #pragma mark
58 |
59 | - (NSInteger)numberOfPagesInPagerView:(nonnull MXPagerView *)pagerView {
60 | NSArray *segues = [self valueForKey:@"storyboardSegueTemplates"] ;
61 | return segues.count;
62 | }
63 |
64 | - (UIView *)pagerView:(MXPagerView *)pagerView viewForPageAtIndex:(NSInteger)index {
65 | return [self pagerView:pagerView viewControllerForPageAtIndex:index].view;
66 | }
67 |
68 | - (UIViewController *)pagerView:(MXPagerView *)pagerView viewControllerForPageAtIndex:(NSInteger)index {
69 | UIViewController *pageViewController = self.pageViewControllers[@(index)];
70 |
71 | if (!pageViewController && self.storyboard) {
72 | @try {
73 | _pageIndex = index;
74 | NSString *identifier = [self pagerView:pagerView segueIdentifierForPageAtIndex:index];
75 | [self performSegueWithIdentifier:identifier sender:nil];
76 | return self.pageViewControllers[@(index)];
77 | }
78 | @catch(NSException *exception) {}
79 | }
80 | return pageViewController;
81 | }
82 |
83 | - (NSString *)pagerView:(MXPagerView *)pagerView segueIdentifierForPageAtIndex:(NSInteger)index {
84 | return [NSString stringWithFormat:MXSeguePageIdentifierFormat, (long)index];
85 | }
86 |
87 | #pragma mark
88 |
89 | - (NSInteger)pageIndex {
90 | return _pageIndex;
91 | }
92 |
93 | - (void)setPageViewController:(__kindof UIViewController *)pageViewController atIndex:(NSInteger)index {
94 | self.pageViewControllers[@(index)] = pageViewController;
95 | }
96 |
97 | @end
98 |
99 | #pragma mark MXPageSegue class
100 |
101 | NSString * const MXSeguePageIdentifierFormat = @"mx_page_%ld";
102 |
103 | @implementation MXPageSegue
104 |
105 | @dynamic sourceViewController;
106 | @synthesize pageIndex = _pageIndex;
107 |
108 | - (instancetype)initWithIdentifier:(nullable NSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination {
109 | if (self = [super initWithIdentifier:identifier source:source destination:destination]) {
110 |
111 | if ([source respondsToSelector:@selector(pageIndex)]) {
112 | _pageIndex = source.pageIndex;
113 | }
114 | }
115 | return self;
116 | }
117 |
118 | - (void)perform {
119 | [self.destinationViewController willMoveToParentViewController:self.sourceViewController];
120 | [self.sourceViewController addChildViewController:self.destinationViewController];
121 | [self.sourceViewController setPageViewController:self.destinationViewController atIndex:self.pageIndex];
122 | [self.destinationViewController didMoveToParentViewController:self.sourceViewController];
123 | }
124 |
125 | @end
126 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MXPagerView
2 |
3 | [](https://travis-ci.org/maxep/MXPagerView)
4 | [](http://cocoapods.org/pods/MXPagerView)
5 | [](https://github.com/Carthage/Carthage)
6 | [](http://cocoapods.org/pods/MXPagerView)
7 | [](http://cocoapods.org/pods/MXPagerView)
8 |
9 | MXPagerView is a pager view with the ability to reuse pages like you would do with a table view and cells. Depending on the transition style, it will load the current page and neighbors and unload others pages.
10 |
11 | MXPagerViewController allows you to load pages from storyboard using the MXPageSegue.
12 |
13 | ## Usage
14 |
15 | If you want to try it, simply run:
16 |
17 | ```
18 | pod try MXPagerView
19 | ```
20 |
21 | Or clone the repo and run `pod install` from the Example directory first.
22 |
23 | + As a UITableView, the MXPagerView calls data source methods to load pages.
24 |
25 | ```objective-c
26 | #pragma mark
27 |
28 | // Asks the data source to return the number of pages in the pager.
29 | - (NSInteger)numberOfPagesInPagerView:(MXPagerView *)pagerView {
30 | return 10;
31 | }
32 |
33 | // Asks the data source for a view to insert in a particular page of the pager.
34 | - (UIView *)pagerView:(MXPagerView *)pagerView viewForPageAtIndex:(NSInteger)index {
35 |
36 | UILabel *label = [UILabel new];
37 | label.text = [NSString stringWithFormat:@"Page #%i", index];
38 | [label sizeToFit];
39 |
40 | return label;
41 | }
42 | ```
43 |
44 | + In order to reuse pages, first register the reusable view, e.g:
45 |
46 | ```objective-c
47 | - (void)viewDidLoad {
48 | [super viewDidLoad];
49 |
50 | //Register UITextView as page
51 | [self.pagerView registerClass:[UITextView class] forPageReuseIdentifier:@"TextPage"];
52 | }
53 | ```
54 |
55 | Then, dequeue a reusable page in the data source:
56 |
57 | ```objective-c
58 | // Asks the data source for a view to insert in a particular page of the pager.
59 | - (UIView *)pagerView:(MXPagerView *)pagerView viewForPageAtIndex:(NSInteger)index {
60 |
61 | //Dequeue reusable page
62 | UITextView *page = [self.pagerView dequeueReusablePageWithIdentifier:@"TextPage"];
63 | page.text = @"This is a text";
64 |
65 | return page;
66 | }
67 | ```
68 |
69 | The MXPagerView comes with a UIView category which exposed the reuse identifier of the page as well as the ```prepareForReuse``` method, this is called just before the page is returned from the pager view method ```dequeueReusablePageWithIdentifier:```.
70 |
71 | + Using MXPagerViewController in storyboard is super easy:
72 |
73 | 
74 |
75 | ## Installation
76 |
77 | MXPagerView is available through [CocoaPods](http://cocoapods.org). To install
78 | it, simply add the following line to your Podfile:
79 |
80 | ```ruby
81 | pod "MXPagerView"
82 | ```
83 |
84 | ## Documentation
85 |
86 | Documentation is available through [CocoaDocs](http://cocoadocs.org/docsets/MXPagerView/).
87 |
88 | ## Author
89 |
90 | [Maxime Epain](http://maxep.github.io)
91 |
92 | [](https://twitter.com/MaximeEpain)
93 |
94 | ## License
95 |
96 | MXPagerView is available under the MIT license. See the [LICENSE](LICENSE) file for more info.
97 |
--------------------------------------------------------------------------------