├── .gitignore
├── Demo
├── 11.华丽的TableView刷新动效
│ ├── TableViewRefreshAnimation.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── TableViewRefreshAnimation
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── TableViewAnimator.swift
│ │ ├── UITableView+Extension.swift
│ │ └── ViewController.swift
├── 35.使用系统自带气泡弹框
│ ├── PopoverView.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── PopoverView
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── ViewController.swift
├── 40.给UICollectionView的Cell添加左滑删除
│ ├── EditingCollectionView.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── EditingCollectionView
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ └── trash.imageset
│ │ │ ├── Contents.json
│ │ │ ├── trash-1.png
│ │ │ ├── trash-2.png
│ │ │ └── trash.png
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── EditingCollectionViewCell.swift
│ │ ├── Info.plist
│ │ ├── ItemCollectionViewCell.swift
│ │ ├── UIView+Extensions.swift
│ │ └── ViewController.swift
├── 44.自定义带动画效果的模态框
│ ├── CustomPresentation.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── CustomPresentation
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── CustomActionsheetController.swift
│ │ ├── Info.plist
│ │ ├── PresentationController.swift
│ │ ├── ToastViewController.swift
│ │ └── ViewController.swift
├── 47.给App的某个功能添加快捷方式
│ ├── AddHomeShortcuts.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── AddHomeShortcuts.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── AddHomeShortcuts
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ └── feature_icon.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── feature_icon.png
│ │ ├── Base.lproj
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── FeatureViewController.swift
│ │ ├── HomeViewController.swift
│ │ ├── Info.plist
│ │ └── shortcuts.html
│ ├── Podfile
│ ├── Podfile.lock
│ └── Pods
│ │ ├── Manifest.lock
│ │ ├── Pods.xcodeproj
│ │ └── project.pbxproj
│ │ ├── Swifter
│ │ ├── LICENSE
│ │ ├── README.md
│ │ └── Sources
│ │ │ ├── DemoServer.swift
│ │ │ ├── Errno.swift
│ │ │ ├── Files.swift
│ │ │ ├── HttpParser.swift
│ │ │ ├── HttpRequest.swift
│ │ │ ├── HttpResponse.swift
│ │ │ ├── HttpRouter.swift
│ │ │ ├── HttpServer.swift
│ │ │ ├── HttpServerIO.swift
│ │ │ ├── MimeTypes.swift
│ │ │ ├── Process.swift
│ │ │ ├── Scopes.swift
│ │ │ ├── Socket+File.swift
│ │ │ ├── Socket+Server.swift
│ │ │ ├── Socket.swift
│ │ │ ├── String+BASE64.swift
│ │ │ ├── String+File.swift
│ │ │ ├── String+Misc.swift
│ │ │ ├── String+SHA1.swift
│ │ │ └── WebSockets.swift
│ │ └── Target Support Files
│ │ ├── Pods-AddHomeShortcuts
│ │ ├── Info.plist
│ │ ├── Pods-AddHomeShortcuts-acknowledgements.markdown
│ │ ├── Pods-AddHomeShortcuts-acknowledgements.plist
│ │ ├── Pods-AddHomeShortcuts-dummy.m
│ │ ├── Pods-AddHomeShortcuts-frameworks.sh
│ │ ├── Pods-AddHomeShortcuts-resources.sh
│ │ ├── Pods-AddHomeShortcuts-umbrella.h
│ │ ├── Pods-AddHomeShortcuts.debug.xcconfig
│ │ ├── Pods-AddHomeShortcuts.modulemap
│ │ └── Pods-AddHomeShortcuts.release.xcconfig
│ │ └── Swifter
│ │ ├── Info.plist
│ │ ├── Swifter-dummy.m
│ │ ├── Swifter-prefix.pch
│ │ ├── Swifter-umbrella.h
│ │ ├── Swifter.modulemap
│ │ └── Swifter.xcconfig
├── 49.线程保活的封装
│ ├── keepThreadAlive.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── keepThreadAlive
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── PermenantThread.swift
│ │ ├── TestViewController.swift
│ │ └── ViewController.swift
├── 50.GCD定时器
│ ├── GCDTimer.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── GCDTimer
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── GCD
│ │ ├── GCDGroup.swift
│ │ ├── GCDQueue.swift
│ │ ├── GCDQueuePriority.swift
│ │ ├── GCDSemaphore.swift
│ │ └── GCDTimer.swift
│ │ ├── Info.plist
│ │ └── ViewController.swift
├── 55.使用协调器模式管理控制器
│ ├── CoordinateDemo.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── CoordinateDemo
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Auth
│ │ ├── Auth.storyboard
│ │ └── AuthViewController.swift
│ │ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ │ ├── Coordinate
│ │ ├── AppCoordinator.swift
│ │ ├── AuthCoordinator.swift
│ │ ├── MessageCoordinator.swift
│ │ └── UIStoryboard+Extensions.swift
│ │ ├── Info.plist
│ │ ├── Main
│ │ ├── Main.storyboard
│ │ └── MainViewController.swift
│ │ └── Message
│ │ ├── MessageDetailController.swift
│ │ └── MessageViewController.swift
├── 58.恢复非正常终止的应用状态
│ ├── RestoreApp.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── RestoreApp
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── FirstViewController.swift
│ │ ├── Info.plist
│ │ ├── LastViewController.swift
│ │ ├── NavController.swift
│ │ └── SecondViewController.swift
├── 62.插件化TableView
│ ├── PluginTableView.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── PluginTableView
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── chili.imageset
│ │ │ ├── Contents.json
│ │ │ └── chili.png
│ │ ├── lemon.imageset
│ │ │ ├── Contents.json
│ │ │ └── lemon.png
│ │ ├── mushroom.imageset
│ │ │ ├── Contents.json
│ │ │ └── mushroom.png
│ │ ├── orange.imageset
│ │ │ ├── Contents.json
│ │ │ └── orange.png
│ │ ├── radish.imageset
│ │ │ ├── Contents.json
│ │ │ └── radish.png
│ │ └── watermelon.imageset
│ │ │ ├── Contents.json
│ │ │ └── watermelon.png
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── BaseController.swift
│ │ ├── Cell
│ │ ├── CodeableViewCell.swift
│ │ ├── NibTableViewCell.swift
│ │ └── NibTableViewCell.xib
│ │ ├── FirstViewController.swift
│ │ ├── Info.plist
│ │ ├── Model
│ │ └── CellModel.swift
│ │ ├── PluginTableView
│ │ ├── Configurator.swift
│ │ ├── DataSource.swift
│ │ ├── PluginTableView.swift
│ │ └── Section.swift
│ │ ├── SecondViewController.swift
│ │ └── ThirdViewController.swift
├── 63.自定义底部弹层控制器
│ ├── PresentPartController.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── PresentPartController
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── PresentPartController.swift
│ │ ├── SceneDelegate.swift
│ │ └── ViewController.swift
└── 9.使用面向协议实现app的主题功能
│ ├── DCTheme.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── DCTheme
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ ├── one.imageset
│ │ ├── Contents.json
│ │ ├── one@2x.png
│ │ └── one@3x.png
│ └── two.imageset
│ │ ├── Contents.json
│ │ ├── two@2x.png
│ │ └── two@3x.png
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Extensions
│ ├── UIColor+Extension.swift
│ ├── UITableViewCell+Extension.swift
│ ├── UIView+Extension.swift
│ └── UIWindow+Extension.swift
│ ├── Info.plist
│ ├── MainViewController.swift
│ ├── Theme
│ ├── BlueTheme.swift
│ ├── DarkTheme.swift
│ ├── LightTheme.swift
│ └── Theme.swift
│ └── View
│ └── BackgroundView.swift
├── LICENSE
├── MyPlayground.playground
├── Pages
│ ├── 1.常用的几个高阶函数.xcplaygroundpage
│ │ └── Contents.swift
│ ├── 13.实现多重代理.xcplaygroundpage
│ │ └── Contents.swift
│ ├── 2.高阶函数扩展.xcplaygroundpage
│ │ └── Contents.swift
│ ├── 3.优雅的判断多个值中是否包含某一个值.xcplaygroundpage
│ │ └── Contents.swift
│ ├── 4. Hashable、Equatable和Comparable协议.xcplaygroundpage
│ │ └── Contents.swift
│ ├── 5.可变参数函数.xcplaygroundpage
│ │ └── Contents.swift
│ └── 6.where关键字.xcplaygroundpage
│ │ └── Contents.swift
└── contents.xcplayground
├── README.md
├── Source
├── IBDesignableView.png
├── TableViewRefreshAnimation2.gif
├── addContainerView.png
├── addshortcuts.png
├── addshortcutsgif.gif
├── anchor_autoLayout.png
├── attributed_url.png
├── blink_scale_corner.gif
├── changeStatusBarStyle2.gif
├── color_wheel.png
├── custom_actionsheet.gif
├── embedTableViewController.png
├── namespace_module.png
├── padding.png
├── popOverView.gif
├── present_part_controller.gif
├── restoration_id.png
├── shadow_move.gif
├── showStyle.png
├── tabbarAnimating.gif
├── themeDemo.gif
├── toast_view.gif
└── yellow_pixel.png
├── SwiftTipsDemo
├── DCTool
│ ├── DCTool
│ │ ├── DCTool.swift
│ │ ├── EdgeInsetLabel.swift
│ │ ├── LayoutProxy.swift
│ │ ├── MutexLock.swift
│ │ ├── Observable.swift
│ │ ├── Regex.swift
│ │ ├── Registerable.swift
│ │ ├── StackViewControllerProtocol.swift
│ │ └── ViewControllerInjector.swift
│ └── Extension
│ │ ├── Collection+Extension.swift
│ │ ├── Date+Extension.swift
│ │ ├── Dictionary+Extension.swift
│ │ ├── NSObject+Extension.swift
│ │ ├── Optional+Extension.swift
│ │ ├── UIButton+Extension.swift
│ │ ├── UIColor+Extension.swift
│ │ ├── UITableView+Extension.swift
│ │ ├── UIView+Extension.swift
│ │ ├── UIViewController+Extension.swift
│ │ └── UIWindow+Extension.swift
├── Podfile
├── Podfile.lock
├── Pods
│ ├── Manifest.lock
│ ├── Pods.xcodeproj
│ │ └── project.pbxproj
│ ├── SwiftLint
│ │ ├── LICENSE
│ │ └── swiftlint
│ └── Target Support Files
│ │ └── Pods-SwiftTipsDemo
│ │ ├── Info.plist
│ │ ├── Pods-SwiftTipsDemo-acknowledgements.markdown
│ │ ├── Pods-SwiftTipsDemo-acknowledgements.plist
│ │ ├── Pods-SwiftTipsDemo-dummy.m
│ │ ├── Pods-SwiftTipsDemo-frameworks.sh
│ │ ├── Pods-SwiftTipsDemo-resources.sh
│ │ ├── Pods-SwiftTipsDemo-umbrella.h
│ │ ├── Pods-SwiftTipsDemo.debug.xcconfig
│ │ ├── Pods-SwiftTipsDemo.modulemap
│ │ └── Pods-SwiftTipsDemo.release.xcconfig
├── SwiftTipsDemo.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── SwiftTipsDemo.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── SwiftTipsDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── DetailViewController.swift
│ ├── Info.plist
│ └── ViewController.swift
└── XcodeTips
├── XcodeTips.md
└── source
├── after_refactor_storyboard.png
├── breakpoint_view.png
├── control_distance.png
├── lock_control.png
├── more_layer.png
├── refactor_storyboard.png
├── rename.png
├── set_storyboard_reference.png
└── storyboard_reference.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 | .DS_Store
9 |
10 | ## Various settings
11 | *.pbxuser
12 | !default.pbxuser
13 | *.mode1v3
14 | !default.mode1v3
15 | *.mode2v3
16 | !default.mode2v3
17 | *.perspectivev3
18 | !default.perspectivev3
19 | xcuserdata/
20 |
21 | ## Other
22 | *.moved-aside
23 | *.xccheckout
24 | *.xcscmblueprint
25 |
26 | ## Obj-C/Swift specific
27 | *.hmap
28 | *.ipa
29 | *.dSYM.zip
30 | *.dSYM
31 |
32 | ## Playgrounds
33 | timeline.xctimeline
34 | playground.xcworkspace
35 |
36 | # Swift Package Manager
37 | #
38 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
39 | # Packages/
40 | # Package.pins
41 | # Package.resolved
42 | .build/
43 |
44 | # CocoaPods
45 | #
46 | # We recommend against adding the Pods directory to your .gitignore. However
47 | # you should judge for yourself, the pros and cons are mentioned at:
48 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
49 | #
50 | # Pods/
51 |
52 | # Carthage
53 | #
54 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
55 | # Carthage/Checkouts
56 |
57 | Carthage/Build
58 |
59 | # fastlane
60 | #
61 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
62 | # screenshots whenever they are needed.
63 | # For more information about the recommended setup visit:
64 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
65 |
66 | fastlane/report.xml
67 | fastlane/Preview.html
68 | fastlane/screenshots/**/*.png
69 | fastlane/test_output
70 |
--------------------------------------------------------------------------------
/Demo/11.华丽的TableView刷新动效/TableViewRefreshAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/11.华丽的TableView刷新动效/TableViewRefreshAnimation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/11.华丽的TableView刷新动效/TableViewRefreshAnimation/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Demo/11.华丽的TableView刷新动效/TableViewRefreshAnimation/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/11.华丽的TableView刷新动效/TableViewRefreshAnimation/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/11.华丽的TableView刷新动效/TableViewRefreshAnimation/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Demo/11.华丽的TableView刷新动效/TableViewRefreshAnimation/UITableView+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UITableView+Extension.swift
3 | // TableViewRefreshAnimation
4 | //
5 | // Created by Dariel on 2018/10/12.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UITableView {
12 | func isLastVisibleCell(at indexPath: IndexPath) -> Bool {
13 | guard let lastIndexPath = indexPathsForVisibleRows?.last else {
14 | return false
15 | }
16 | return lastIndexPath == indexPath
17 | }
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/Demo/35.使用系统自带气泡弹框/PopoverView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/35.使用系统自带气泡弹框/PopoverView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/35.使用系统自带气泡弹框/PopoverView/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Demo/35.使用系统自带气泡弹框/PopoverView/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/35.使用系统自带气泡弹框/PopoverView/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/35.使用系统自带气泡弹框/PopoverView/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Demo/35.使用系统自带气泡弹框/PopoverView/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // PopoverView
4 | //
5 | // Created by Dariel on 2018/12/10.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | }
16 | }
17 |
18 | extension ViewController: UIPopoverPresentationControllerDelegate {
19 |
20 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
21 | if segue.identifier == "popoverSegue" {
22 | let popoverViewController = segue.destination
23 | popoverViewController.popoverPresentationController!.delegate = self
24 | }
25 | }
26 | func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
27 | return .none
28 | }
29 |
30 | func popoverPresentationControllerDidDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) {
31 | setAlphaOfBackgroundViews(alpha: 1)
32 | }
33 |
34 | func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
35 | setAlphaOfBackgroundViews(alpha: 0.8)
36 | }
37 |
38 | func setAlphaOfBackgroundViews(alpha: CGFloat) {
39 | let statusBarWindow = UIApplication.shared.value(forKey: "statusBarWindow") as? UIWindow
40 | UIView.animate(withDuration: 0.2) {
41 | statusBarWindow?.alpha = alpha
42 | self.view.alpha = alpha
43 | self.navigationController?.navigationBar.alpha = alpha
44 | }
45 | }
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // EditingCollectionView
4 | //
5 | // Created by Dariel on 2019/1/8.
6 | // Copyright © 2019年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 |
19 |
20 |
21 | return true
22 | }
23 |
24 | func applicationWillResignActive(_ application: UIApplication) {
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | }
29 |
30 | func applicationWillEnterForeground(_ application: UIApplication) {
31 | }
32 |
33 | func applicationDidBecomeActive(_ application: UIApplication) {
34 | }
35 |
36 | func applicationWillTerminate(_ application: UIApplication) {
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/Assets.xcassets/trash.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "trash-2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "trash-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "trash.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/Assets.xcassets/trash.imageset/trash-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/Assets.xcassets/trash.imageset/trash-1.png
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/Assets.xcassets/trash.imageset/trash-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/Assets.xcassets/trash.imageset/trash-2.png
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/Assets.xcassets/trash.imageset/trash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/Assets.xcassets/trash.imageset/trash.png
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/ItemCollectionViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ItemCollectionViewCell.swift
3 | // EditingCollectionView
4 | //
5 | // Created by Dariel on 2019/1/8.
6 | // Copyright © 2019年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ItemCollectionViewCell: EditingCollectionViewCell {
12 |
13 | let itemNameLabel: UILabel = {
14 | let label = UILabel()
15 | label.font = UIFont.systemFont(ofSize: 20)
16 | label.textColor = UIColor(white: 0.2, alpha: 1)
17 | label.textAlignment = .center
18 | return label
19 | }()
20 |
21 | let deleteImageView: UIImageView = {
22 | let image = UIImage(named: "trash")?.withRenderingMode(.alwaysTemplate)
23 | let imageView = UIImageView(image: image)
24 | imageView.tintColor = .white
25 | return imageView
26 | }()
27 |
28 | override init(frame: CGRect) {
29 | super.init(frame: frame)
30 | setupSubviews()
31 | }
32 |
33 | required init?(coder aDecoder: NSCoder) {
34 | fatalError("init(coder:) has not been implemented")
35 | }
36 |
37 | private func setupSubviews() {
38 | visibleContainerView.backgroundColor = .white
39 | visibleContainerView.addSubview(itemNameLabel)
40 | itemNameLabel.pinEdgesToSuperView()
41 |
42 | hiddenContainerView.backgroundColor = UIColor(red: 231.0 / 255.0, green: 76.0 / 255.0, blue: 60.0 / 255.0, alpha: 1)
43 | hiddenContainerView.addSubview(deleteImageView)
44 | deleteImageView.translatesAutoresizingMaskIntoConstraints = false
45 | deleteImageView.centerXAnchor.constraint(equalTo: hiddenContainerView.centerXAnchor).isActive = true
46 | deleteImageView.centerYAnchor.constraint(equalTo: hiddenContainerView.centerYAnchor).isActive = true
47 | deleteImageView.widthAnchor.constraint(equalToConstant: 25).isActive = true
48 | deleteImageView.heightAnchor.constraint(equalToConstant: 30).isActive = true
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Demo/40.给UICollectionView的Cell添加左滑删除/EditingCollectionView/UIView+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Extensions.swift
3 | // EditingCollectionView
4 | //
5 | // Created by Dariel on 2019/1/8.
6 | // Copyright © 2019年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIView {
12 |
13 | func pinEdgesToSuperView() {
14 | guard let superView = superview else { return }
15 | translatesAutoresizingMaskIntoConstraints = false
16 | topAnchor.constraint(equalTo: superView.topAnchor).isActive = true
17 | leftAnchor.constraint(equalTo: superView.leftAnchor).isActive = true
18 | bottomAnchor.constraint(equalTo: superView.bottomAnchor).isActive = true
19 | rightAnchor.constraint(equalTo: superView.rightAnchor).isActive = true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Demo/44.自定义带动画效果的模态框/CustomPresentation.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/44.自定义带动画效果的模态框/CustomPresentation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/44.自定义带动画效果的模态框/CustomPresentation/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Demo/44.自定义带动画效果的模态框/CustomPresentation/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/44.自定义带动画效果的模态框/CustomPresentation/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/44.自定义带动画效果的模态框/CustomPresentation/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Demo/44.自定义带动画效果的模态框/CustomPresentation/PresentationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PresentationController.swift
3 | // CustomPresentation
4 | //
5 | // Created by Dariel on 2019/2/19.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PresentationController: UIPresentationController {
12 |
13 | private var calculatedFrameOfPresentedViewInContainerView = CGRect.zero
14 | private var shouldSetFrameWhenAccessingPresentedView = false
15 |
16 | override var presentedView: UIView? {
17 | if shouldSetFrameWhenAccessingPresentedView {
18 | super.presentedView?.frame = calculatedFrameOfPresentedViewInContainerView
19 | }
20 | return super.presentedView
21 | }
22 |
23 | override func presentationTransitionDidEnd(_ completed: Bool) {
24 | super.presentationTransitionDidEnd(completed)
25 | shouldSetFrameWhenAccessingPresentedView = completed
26 | }
27 |
28 | override func dismissalTransitionWillBegin() {
29 | super.dismissalTransitionWillBegin()
30 | shouldSetFrameWhenAccessingPresentedView = false
31 | }
32 |
33 | override func containerViewDidLayoutSubviews() {
34 | super.containerViewDidLayoutSubviews()
35 | calculatedFrameOfPresentedViewInContainerView = frameOfPresentedViewInContainerView
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Demo/44.自定义带动画效果的模态框/CustomPresentation/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // CustomPresentation
4 | //
5 | // Created by Dariel on 2019/2/19.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | // alert actionSheet
17 | _ = UIAlertController(title: "", message: "", preferredStyle: .actionSheet)
18 | }
19 |
20 | @IBAction func addtoastViewAction(_ sender: Any) {
21 |
22 | presentToast(title: "这是一条从底部弹出来的Toast,当文本过长的话可以支持自动换行哦")
23 | }
24 |
25 | @IBAction func addActionSheetAction(_ sender: Any) {
26 |
27 | let viewController = CustomActionsheetController()
28 | present(viewController, animated: true, completion: nil)
29 | }
30 |
31 | private func presentToast(title: String) {
32 | let toast = ToastViewController(title: title)
33 | present(toast, animated: true)
34 | Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { _ in
35 | toast.dismiss(animated: true)
36 | }
37 | }
38 |
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts/Assets.xcassets/feature_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "feature_icon.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts/Assets.xcassets/feature_icon.imageset/feature_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts/Assets.xcassets/feature_icon.imageset/feature_icon.png
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts/FeatureViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FeatureViewController.swift
3 | // AddHomeShortcuts
4 | //
5 | // Created by Dariel on 2019/3/12.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Swifter
11 |
12 | class FeatureViewController: UIViewController {
13 | lazy var server = HttpServer()
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 |
18 | }
19 | @IBAction func addShortcutsTouch(_ sender: Any) {
20 |
21 | guard let deeplink = URL(string: "addshortcuts://profile") else {
22 | return
23 | }
24 | guard let shortcutUrl = URL(string: "http://localhost:8244/s") else {
25 | return
26 | }
27 |
28 | guard let iconData = UIImage(named: "feature_icon")?.jpegData(compressionQuality: 0.5) else {
29 | return
30 | }
31 |
32 | let html = htmlFor(title: "功能快捷方式", urlToRedirect: deeplink.absoluteString, icon: iconData.base64EncodedString())
33 |
34 | guard let base64 = html.data(using: .utf8)?.base64EncodedString() else {
35 | return
36 | }
37 | server["/s"] = { request in
38 | return .movedPermanently("data:text/html;base64,\(base64)")
39 | }
40 | try? server.start(8244)
41 | UIApplication.shared.open(shortcutUrl)
42 |
43 | }
44 |
45 | func htmlFor(title: String, urlToRedirect: String, icon: String) -> String {
46 | let shortcutsPath = Bundle.main.path(forResource: "shortcuts", ofType: "html")
47 |
48 | var shortcutsContent = try! String(contentsOfFile: shortcutsPath!) as String
49 | shortcutsContent = shortcutsContent.replacingOccurrences(of: "\\(title)", with: title)
50 | shortcutsContent = shortcutsContent.replacingOccurrences(of: "\\(urlToRedirect.absoluteString)", with: urlToRedirect)
51 | shortcutsContent = shortcutsContent.replacingOccurrences(of: "\\(feature_icon)", with: icon)
52 |
53 | print(shortcutsContent)
54 | return shortcutsContent
55 | }
56 |
57 |
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts/HomeViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // AddHomeShortcuts
4 | //
5 | // Created by Dariel on 2019/3/12.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class HomeViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 |
17 |
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/AddHomeShortcuts/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleURLTypes
20 |
21 |
22 | CFBundleTypeRole
23 | Editor
24 | CFBundleURLSchemes
25 |
26 | addshortcuts
27 |
28 |
29 |
30 | CFBundleVersion
31 | 1
32 | LSRequiresIPhoneOS
33 |
34 | UILaunchStoryboardName
35 | LaunchScreen
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 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | target 'AddHomeShortcuts' do
5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
6 | use_frameworks!
7 |
8 | pod 'Swifter'
9 |
10 | # Pods for AddHomeShortcuts
11 |
12 | end
13 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Swifter (1.4.5)
3 |
4 | DEPENDENCIES:
5 | - Swifter
6 |
7 | SPEC REPOS:
8 | https://github.com/cocoapods/specs.git:
9 | - Swifter
10 |
11 | SPEC CHECKSUMS:
12 | Swifter: eb2bc1d192a1c09169c7fefd01971565fa940521
13 |
14 | PODFILE CHECKSUM: 181acaa524d3e7395c5a86ceca4de47c5e5bb0a8
15 |
16 | COCOAPODS: 1.5.3
17 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Swifter (1.4.5)
3 |
4 | DEPENDENCIES:
5 | - Swifter
6 |
7 | SPEC REPOS:
8 | https://github.com/cocoapods/specs.git:
9 | - Swifter
10 |
11 | SPEC CHECKSUMS:
12 | Swifter: eb2bc1d192a1c09169c7fefd01971565fa940521
13 |
14 | PODFILE CHECKSUM: 181acaa524d3e7395c5a86ceca4de47c5e5bb0a8
15 |
16 | COCOAPODS: 1.5.3
17 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Swifter/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014, Damian Kołakowski
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * Neither the name of the {organization} nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Swifter/Sources/Errno.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Errno.swift
3 | // Swifter
4 | //
5 | // Copyright © 2016 Damian Kołakowski. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | public class Errno {
11 |
12 | public class func description() -> String {
13 | return String(cString: UnsafePointer(strerror(errno)))
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Swifter/Sources/Process.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Process
3 | // Swifter
4 | //
5 | // Copyright (c) 2014-2016 Damian Kołakowski. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | public class Process {
11 |
12 | public static var pid: Int {
13 | return Int(getpid())
14 | }
15 |
16 | public static var tid: UInt64 {
17 | #if os(Linux)
18 | return UInt64(pthread_self())
19 | #else
20 | var tid: __uint64_t = 0
21 | pthread_threadid_np(nil, &tid);
22 | return UInt64(tid)
23 | #endif
24 | }
25 |
26 | private static var signalsWatchers = Array<(Int32) -> Void>()
27 | private static var signalsObserved = false
28 |
29 | public static func watchSignals(_ callback: @escaping (Int32) -> Void) {
30 | if !signalsObserved {
31 | [SIGTERM, SIGHUP, SIGSTOP, SIGINT].forEach { item in
32 | signal(item) {
33 | signum in Process.signalsWatchers.forEach { $0(signum) }
34 | }
35 | }
36 | signalsObserved = true
37 | }
38 | signalsWatchers.append(callback)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Swifter/Sources/Socket+File.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Socket+File.swift
3 | // Swifter
4 | //
5 | // Created by Damian Kolakowski on 13/07/16.
6 | //
7 |
8 | import Foundation
9 |
10 | #if os(iOS) || os(tvOS) || os (Linux)
11 | struct sf_hdtr { }
12 |
13 | private func sendfileImpl(_ source: UnsafeMutablePointer, _ target: Int32, _: off_t, _: UnsafeMutablePointer, _: UnsafeMutablePointer, _: Int32) -> Int32 {
14 | var buffer = [UInt8](repeating: 0, count: 1024)
15 | while true {
16 | let readResult = fread(&buffer, 1, buffer.count, source)
17 | guard readResult > 0 else {
18 | return Int32(readResult)
19 | }
20 | var writeCounter = 0
21 | while writeCounter < readResult {
22 | #if os(Linux)
23 | let writeResult = send(target, &buffer + writeCounter, readResult - writeCounter, Int32(MSG_NOSIGNAL))
24 | #else
25 | let writeResult = write(target, &buffer + writeCounter, readResult - writeCounter)
26 | #endif
27 | guard writeResult > 0 else {
28 | return Int32(writeResult)
29 | }
30 | writeCounter = writeCounter + writeResult
31 | }
32 | }
33 | }
34 | #endif
35 |
36 | extension Socket {
37 |
38 | public func writeFile(_ file: String.File) throws -> Void {
39 | var offset: off_t = 0
40 | var sf: sf_hdtr = sf_hdtr()
41 |
42 | #if os(iOS) || os(tvOS) || os (Linux)
43 | let result = sendfileImpl(file.pointer, self.socketFileDescriptor, 0, &offset, &sf, 0)
44 | #else
45 | let result = sendfile(fileno(file.pointer), self.socketFileDescriptor, 0, &offset, &sf, 0)
46 | #endif
47 |
48 | if result == -1 {
49 | throw SocketError.writeFailed("sendfile: " + Errno.description())
50 | }
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Swifter/Sources/String+BASE64.swift:
--------------------------------------------------------------------------------
1 | //
2 | // String+BASE64.swift
3 | // Swifter
4 | //
5 | // Copyright © 2016 Damian Kołakowski. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 |
11 | extension String {
12 |
13 | private static let CODES = [UInt8]("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".utf8)
14 |
15 | public static func toBase64(_ data: [UInt8]) -> String? {
16 |
17 | // Based on: https://en.wikipedia.org/wiki/Base64#Sample_Implementation_in_Java
18 |
19 | var result = [UInt8]()
20 | var tmp: UInt8
21 | for index in stride(from: 0, to: data.count, by: 3) {
22 | let byte = data[index]
23 | tmp = (byte & 0xFC) >> 2;
24 | result.append(CODES[Int(tmp)])
25 | tmp = (byte & 0x03) << 4;
26 | if index + 1 < data.count {
27 | tmp |= (data[index + 1] & 0xF0) >> 4;
28 | result.append(CODES[Int(tmp)]);
29 | tmp = (data[index + 1] & 0x0F) << 2;
30 | if (index + 2 < data.count) {
31 | tmp |= (data[index + 2] & 0xC0) >> 6;
32 | result.append(CODES[Int(tmp)]);
33 | tmp = data[index + 2] & 0x3F;
34 | result.append(CODES[Int(tmp)]);
35 | } else {
36 | result.append(CODES[Int(tmp)]);
37 | result.append(contentsOf: [UInt8]("=".utf8));
38 | }
39 | } else {
40 | result.append(CODES[Int(tmp)]);
41 | result.append(contentsOf: [UInt8]("==".utf8));
42 | }
43 | }
44 | return String(bytes: result, encoding: .utf8)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Swifter/Sources/String+Misc.swift:
--------------------------------------------------------------------------------
1 | //
2 | // String+Misc.swift
3 | // Swifter
4 | //
5 | // Copyright (c) 2014-2016 Damian Kołakowski. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 |
11 | extension String {
12 |
13 | public func unquote() -> String {
14 | var scalars = self.unicodeScalars;
15 | if scalars.first == "\"" && scalars.last == "\"" && scalars.count >= 2 {
16 | scalars.removeFirst();
17 | scalars.removeLast();
18 | return String(scalars)
19 | }
20 | return self
21 | }
22 | }
23 |
24 | extension UnicodeScalar {
25 |
26 | public func asWhitespace() -> UInt8? {
27 | if self.value >= 9 && self.value <= 13 {
28 | return UInt8(self.value)
29 | }
30 | if self.value == 32 {
31 | return UInt8(self.value)
32 | }
33 | return nil
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Pods-AddHomeShortcuts/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Pods-AddHomeShortcuts/Pods-AddHomeShortcuts-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## Swifter
5 |
6 | Copyright (c) 2014, Damian Kołakowski
7 | All rights reserved.
8 |
9 | Redistribution and use in source and binary forms, with or without
10 | modification, are permitted provided that the following conditions are met:
11 |
12 | * Redistributions of source code must retain the above copyright notice, this
13 | list of conditions and the following disclaimer.
14 |
15 | * Redistributions in binary form must reproduce the above copyright notice,
16 | this list of conditions and the following disclaimer in the documentation
17 | and/or other materials provided with the distribution.
18 |
19 | * Neither the name of the {organization} nor the names of its
20 | contributors may be used to endorse or promote products derived from
21 | this software without specific prior written permission.
22 |
23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 | Generated by CocoaPods - https://cocoapods.org
34 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Pods-AddHomeShortcuts/Pods-AddHomeShortcuts-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_AddHomeShortcuts : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_AddHomeShortcuts
5 | @end
6 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Pods-AddHomeShortcuts/Pods-AddHomeShortcuts-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_AddHomeShortcutsVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_AddHomeShortcutsVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Pods-AddHomeShortcuts/Pods-AddHomeShortcuts.debug.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Swifter"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/Swifter/Swifter.framework/Headers"
6 | OTHER_LDFLAGS = $(inherited) -framework "Swifter"
7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Pods-AddHomeShortcuts/Pods-AddHomeShortcuts.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_AddHomeShortcuts {
2 | umbrella header "Pods-AddHomeShortcuts-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Pods-AddHomeShortcuts/Pods-AddHomeShortcuts.release.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Swifter"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/Swifter/Swifter.framework/Headers"
6 | OTHER_LDFLAGS = $(inherited) -framework "Swifter"
7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Swifter/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.4.5
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Swifter/Swifter-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Swifter : NSObject
3 | @end
4 | @implementation PodsDummy_Swifter
5 | @end
6 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Swifter/Swifter-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Swifter/Swifter-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double SwifterVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char SwifterVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Swifter/Swifter.modulemap:
--------------------------------------------------------------------------------
1 | framework module Swifter {
2 | umbrella header "Swifter-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Demo/47.给App的某个功能添加快捷方式/Pods/Target Support Files/Swifter/Swifter.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Swifter
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
4 | PODS_BUILD_DIR = ${BUILD_DIR}
5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
6 | PODS_ROOT = ${SRCROOT}
7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Swifter
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 |
--------------------------------------------------------------------------------
/Demo/49.线程保活的封装/keepThreadAlive.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/49.线程保活的封装/keepThreadAlive.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/49.线程保活的封装/keepThreadAlive/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Demo/49.线程保活的封装/keepThreadAlive/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/49.线程保活的封装/keepThreadAlive/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/49.线程保活的封装/keepThreadAlive/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Demo/49.线程保活的封装/keepThreadAlive/PermenantThread.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PermenantThread.swift
3 | // keepThreadAlive
4 | //
5 | // Created by Dariel on 2019/3/26.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class DCThread: Thread {
12 | deinit {
13 | print("DCThread被销毁")
14 | }
15 | }
16 |
17 | class PermenantThread: NSObject {
18 |
19 | private var innerThread: DCThread?
20 | private var isStopped = false
21 |
22 | override init() {
23 | super.init()
24 |
25 | innerThread = DCThread(block: { [weak self] in
26 |
27 | RunLoop.current.add(Port(), forMode: RunLoop.Mode.default)
28 | while self?.isStopped == false {
29 | RunLoop.current.run(mode: RunLoop.Mode.default, before: NSDate.distantFuture)
30 | }
31 | })
32 |
33 | innerThread?.name = "PermenantThread"
34 | innerThread?.start()
35 | }
36 |
37 | func executeTask(task: @escaping @convention(block)() -> Void) {
38 |
39 | guard let innerThread = innerThread else{
40 | return
41 | }
42 |
43 | self.perform(#selector(innerExecuteTask(task:)), on: innerThread, with: task, waitUntilDone: false)
44 | }
45 |
46 | func stop() {
47 |
48 | guard let innerThread = innerThread else{
49 | return
50 | }
51 | self.perform(#selector(innerStop), on: innerThread, with: nil, waitUntilDone: true)
52 | }
53 |
54 | @objc private func innerExecuteTask(task: @escaping @convention(block)() -> Void) {
55 | task()
56 | }
57 |
58 | @objc private func innerStop() {
59 | isStopped = true
60 | CFRunLoopStop(CFRunLoopGetCurrent());
61 | self.innerThread = nil
62 | }
63 |
64 | deinit {
65 | stop()
66 | print("PermenantThread被销毁")
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Demo/49.线程保活的封装/keepThreadAlive/TestViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestViewController.swift
3 | // keepThreadAlive
4 | //
5 | // Created by Dariel on 2019/3/26.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TestViewController: UIViewController {
12 |
13 | let thread = PermenantThread()
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 |
18 | }
19 |
20 | @IBAction func excuteTaskTouch(_ sender: Any) {
21 | thread.executeTask {
22 | print(Thread.current)
23 | }
24 | }
25 | @IBAction func stopTaskTouch(_ sender: Any) {
26 | thread.stop()
27 | }
28 |
29 | deinit {
30 | print("TestViewController被销毁")
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Demo/49.线程保活的封装/keepThreadAlive/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // keepThreadAlive
4 | //
5 | // Created by Dariel on 2019/3/26.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | }
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/Demo/50.GCD定时器/GCDTimer.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/50.GCD定时器/GCDTimer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/50.GCD定时器/GCDTimer/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Demo/50.GCD定时器/GCDTimer/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/50.GCD定时器/GCDTimer/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/50.GCD定时器/GCDTimer/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 |
--------------------------------------------------------------------------------
/Demo/50.GCD定时器/GCDTimer/GCD/GCDGroup.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GCDGroup.swift
3 | // GCDTimer
4 | //
5 | // Created by Dariel on 2019/4/2.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class GCDGroup {
12 |
13 | public let dispatchGroup : DispatchGroup
14 |
15 | init() {
16 |
17 | self.dispatchGroup = DispatchGroup()
18 | }
19 |
20 | /// 在指定的queue里面获取消息
21 | ///
22 | /// - Parameters:
23 | /// - queue: 指定的queue
24 | /// - execute: 执行的block
25 | func notifyIn(_ queue : GCDQueue, execute: @escaping () -> Void) {
26 |
27 | self.dispatchGroup.notify(queue: queue.dispatchQueue, execute: execute)
28 | }
29 |
30 | /// 进入group
31 | func enter() {
32 |
33 | self.dispatchGroup.enter()
34 | }
35 |
36 | /// 从group出来
37 | func leave() {
38 |
39 | self.dispatchGroup.leave()
40 | }
41 |
42 | /// [阻塞操作] 无限等待
43 | func wait() {
44 |
45 | self.dispatchGroup.wait()
46 | }
47 |
48 | /// [阻塞操作] 等待指定的时间
49 | ///
50 | /// - Parameter seconds: 等待的时间,最多精确到1ms
51 | /// - Returns: DispatchTimeoutResult对象
52 | func waitForSeconds(seconds : Float) -> DispatchTimeoutResult {
53 |
54 | return self.dispatchGroup.wait(timeout: .now() + .milliseconds(Int(seconds * 1000)))
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Demo/50.GCD定时器/GCDTimer/GCD/GCDSemaphore.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GCDSemaphore.swift
3 | // GCDTimer
4 | //
5 | // Created by Dariel on 2019/4/2.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class GCDSemaphore {
12 |
13 | public let dispatchSemaphore : DispatchSemaphore
14 |
15 | init(initialSignal : Int = 0) {
16 |
17 | self.dispatchSemaphore = DispatchSemaphore(value: initialSignal)
18 | }
19 |
20 | // MARK: Singal
21 |
22 | /// 发信号
23 | func signal() {
24 |
25 | self.dispatchSemaphore.signal()
26 | }
27 |
28 | // MARK: Wait
29 |
30 | /// [阻塞操作] 无限等待
31 | func wait() {
32 |
33 | self.dispatchSemaphore.wait()
34 | }
35 |
36 | /// [阻塞操作] 等待指定的时间
37 | ///
38 | /// - Parameter seconds: 等待的时间,最多精确到1ms
39 | /// - Returns: DispatchTimeoutResult对象
40 | func waitForSeconds(_ seconds : Float) -> DispatchTimeoutResult {
41 |
42 | return self.dispatchSemaphore.wait(timeout: DispatchTime.now() + .milliseconds(Int(seconds * 1000)))
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Demo/50.GCD定时器/GCDTimer/GCD/GCDTimer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GCDTimer.swift
3 | // GCDTimer
4 | //
5 | // Created by Dariel on 2019/4/2.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class GCDTimer {
12 |
13 | public let dispatchSourceTimer : DispatchSourceTimer
14 |
15 | init(in : GCDQueue, delay : Float = 0, interval : Float) {
16 | dispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: `in`.dispatchQueue)
17 | dispatchSourceTimer.schedule(deadline: .now() + .milliseconds(Int(delay * 1000)), repeating: .milliseconds(Int(interval * 1000)))
18 | }
19 |
20 | /// 设定定时器任务的回调函数
21 | ///
22 | /// - Parameter eventHandler: 回调函数
23 | func setTimerEventHandler(eventHandler: @escaping (GCDTimer) -> Void) {
24 | dispatchSourceTimer.setEventHandler {
25 | eventHandler(self)
26 | }
27 | }
28 |
29 | /// 设定定时器销毁时候的回调函数
30 | ///
31 | /// - Parameter eventHandler: 回调函数
32 | func setDestroyEventHandler(eventHandler: @escaping () -> Void) {
33 |
34 | dispatchSourceTimer.setCancelHandler {
35 | eventHandler()
36 | }
37 | }
38 |
39 | /// 挂起
40 | func suspend() {
41 | dispatchSourceTimer.suspend()
42 | }
43 |
44 | /// 开始定时
45 | func start() {
46 | dispatchSourceTimer.resume()
47 | }
48 |
49 | /// 定时器销毁(执行了此方法后,start就会变得无效)
50 | func destroy() {
51 | dispatchSourceTimer.cancel()
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Demo/50.GCD定时器/GCDTimer/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // CoordinateDemo
4 | //
5 | // Created by Dariel on 2019/5/29.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 | var app: AppCoordinator?
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 |
19 | let window = UIWindow(frame: UIScreen.main.bounds)
20 | let navController = UINavigationController()
21 | app = AppCoordinator(navController: navController, window: window)
22 |
23 | app?.start()
24 |
25 | return true
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Auth/AuthViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthViewController.swift
3 | // CoordinateDemo
4 | //
5 | // Created by Dariel on 2019/5/29.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol AuthViewControllerDelegate: AnyObject {
12 | func signIn()
13 | }
14 |
15 | class AuthViewController: UIViewController {
16 |
17 | weak var delegate: AuthViewControllerDelegate?
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 |
22 | }
23 |
24 | @IBAction func signInTouch(_ sender: Any) {
25 | delegate?.signIn()
26 | }
27 |
28 | deinit {
29 | print("AuthViewController销毁")
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Coordinate/AppCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppCoordinator.swift
3 | // CoordinateDemo
4 | //
5 | // Created by Dariel on 2019/5/29.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol Coordinator {
12 | func start()
13 | }
14 |
15 | final class AppCoordinator: Coordinator {
16 |
17 | // MARK: - 属性
18 | private let navController: UINavigationController
19 | private let window: UIWindow
20 | private var childCoordinators: [Coordinator] = []
21 |
22 |
23 | // MARK: - 构造方法
24 | init(navController: UINavigationController, window: UIWindow) {
25 | self.navController = navController
26 | self.window = window
27 | }
28 |
29 |
30 | func start() {
31 | window.rootViewController = navController
32 | window.makeKeyAndVisible()
33 |
34 | // showMain()
35 | showAuth()
36 | }
37 |
38 | // MARK: - 导航
39 | private func showMain() {
40 | let mainVc = UIStoryboard.instantiateMainViewController(delegate: self)
41 | navController.setViewControllers([mainVc], animated: true)
42 |
43 | // childCoordinators.removeAll()
44 | }
45 |
46 | private func showAuth() {
47 | let authCoordinator = AuthCoordinator(navController: navController, delegate: self)
48 | childCoordinators.append(authCoordinator)
49 |
50 | authCoordinator.start()
51 | }
52 |
53 | private func showMessage() {
54 | let messageCoordinator = MessageCoordinator(navController: navController)
55 |
56 | messageCoordinator.start()
57 | }
58 |
59 | }
60 |
61 |
62 | extension AppCoordinator: MainViewControllerDelegate {
63 | func toMessage() {
64 | showMessage()
65 | }
66 |
67 | func logout() {
68 | showAuth()
69 | }
70 | }
71 |
72 | extension AppCoordinator: AuthCoordinatorDelegate {
73 | func didAuthenticate() {
74 | showMain()
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Coordinate/AuthCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthCoordinator.swift
3 | // CoordinateDemo
4 | //
5 | // Created by Dariel on 2019/5/29.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol AuthCoordinatorDelegate: AnyObject {
12 | func didAuthenticate()
13 | }
14 |
15 | // 用户授权模块的Coordinator
16 | final class AuthCoordinator: Coordinator {
17 |
18 | private let navController: UINavigationController
19 | weak var delegate: AuthCoordinatorDelegate?
20 |
21 | init(navController: UINavigationController, delegate: AuthCoordinatorDelegate) {
22 | self.navController = navController
23 | self.delegate = delegate
24 | }
25 |
26 | func start() {
27 | let authVc = UIStoryboard.instantiateAuthViewController(delegate: self)
28 | navController.setViewControllers([authVc], animated: true)
29 | }
30 | }
31 |
32 | extension AuthCoordinator: AuthViewControllerDelegate {
33 | func signIn() {
34 | delegate?.didAuthenticate()
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Coordinate/MessageCoordinator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessageCoordinator.swift
3 | // CoordinateDemo
4 | //
5 | // Created by Dariel on 2019/5/29.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | final class MessageCoordinator: Coordinator {
12 |
13 | private let navController: UINavigationController
14 |
15 | init(navController: UINavigationController) {
16 | self.navController = navController
17 | }
18 |
19 | func start() {
20 | let messageVc = MessageViewController()
21 | messageVc.delegate = self
22 | navController.pushViewController(messageVc, animated: true)
23 | }
24 |
25 | private func toDetailMessageVc() {
26 | let messageDetailVc = MessageDetailController()
27 | navController.pushViewController(messageDetailVc, animated: true)
28 | }
29 | }
30 |
31 |
32 | extension MessageCoordinator: MessageViewControllerDelegate {
33 | func toDetailMessage() {
34 | toDetailMessageVc()
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Coordinate/UIStoryboard+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIStoryboard+Extension.swift
3 | // CoordinateDemo
4 | //
5 | // Created by Dariel on 2019/5/29.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIStoryboard {
12 |
13 | // MARK: - 获取对应的Storyboard
14 | private static var main: UIStoryboard {
15 | return UIStoryboard(name: "Main", bundle: nil)
16 | }
17 |
18 | private static var auth: UIStoryboard {
19 | return UIStoryboard(name: "Auth", bundle: nil)
20 | }
21 |
22 | // MARK: - Storyboard中控制器管理
23 | static func instantiateMainViewController(delegate: MainViewControllerDelegate) -> MainViewController {
24 | let mainVc = main.instantiateViewController(withIdentifier: "MainViewController") as! MainViewController
25 | mainVc.delegate = delegate
26 | return mainVc
27 | }
28 |
29 | static func instantiateAuthViewController(delegate: AuthViewControllerDelegate) -> AuthViewController {
30 | let authVc = auth.instantiateViewController(withIdentifier: "AuthViewController") as! AuthViewController
31 | authVc.delegate = delegate
32 | return authVc
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 |
33 | UISupportedInterfaceOrientations~ipad
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationPortraitUpsideDown
37 | UIInterfaceOrientationLandscapeLeft
38 | UIInterfaceOrientationLandscapeRight
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Main/MainViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // CoordinateDemo
4 | //
5 | // Created by Dariel on 2019/5/29.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol MainViewControllerDelegate: AnyObject {
12 | func logout()
13 | func toMessage()
14 | }
15 |
16 | class MainViewController: UIViewController {
17 | weak var delegate: MainViewControllerDelegate?
18 |
19 | override func viewDidLoad() {
20 | super.viewDidLoad()
21 | }
22 |
23 | @IBAction func logoutAction(_ sender: Any) {
24 | delegate?.logout()
25 | }
26 |
27 | @IBAction func messageTouch(_ sender: Any) {
28 | delegate?.toMessage()
29 | }
30 |
31 | deinit {
32 | print("MainViewController销毁")
33 | }
34 |
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Message/MessageDetailController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessageDetailController.swift
3 | // CoordinateDemo
4 | //
5 | // Created by Dariel on 2019/5/29.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MessageDetailController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | view.backgroundColor = UIColor.white
16 |
17 | let label = UILabel()
18 | label.text = "MessageDetailController"
19 | label.font = UIFont.systemFont(ofSize: 22)
20 |
21 | view.addSubview(label)
22 |
23 | label.sizeToFit()
24 | label.center = view.center
25 | }
26 |
27 | deinit {
28 | print("MessageDetailController销毁")
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Demo/55.使用协调器模式管理控制器/CoordinateDemo/Message/MessageViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessageViewController.swift
3 | // CoordinateDemo
4 | //
5 | // Created by Dariel on 2019/5/29.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol MessageViewControllerDelegate: AnyObject {
12 | func toDetailMessage()
13 | }
14 |
15 | class MessageViewController: UIViewController {
16 | var delegate: MessageViewControllerDelegate?
17 |
18 | override func viewDidLoad() {
19 | super.viewDidLoad()
20 | view.backgroundColor = UIColor.white
21 |
22 | let label = UILabel()
23 | label.text = "MessageViewController"
24 | label.font = UIFont.systemFont(ofSize: 22)
25 |
26 | view.addSubview(label)
27 |
28 | label.sizeToFit()
29 | label.center = view.center
30 | }
31 |
32 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
33 | delegate?.toDetailMessage()
34 | }
35 |
36 | deinit {
37 | print("MessageViewController销毁")
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Demo/58.恢复非正常终止的应用状态/RestoreApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/58.恢复非正常终止的应用状态/RestoreApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/58.恢复非正常终止的应用状态/RestoreApp/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // RestoreApp
4 | //
5 | // Created by Dariel on 2019/6/19.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func application(_ application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool {
23 |
24 | return true
25 | }
26 |
27 | func application(_ application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
28 |
29 | return true
30 | }
31 |
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/Demo/58.恢复非正常终止的应用状态/RestoreApp/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Demo/58.恢复非正常终止的应用状态/RestoreApp/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/58.恢复非正常终止的应用状态/RestoreApp/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/58.恢复非正常终止的应用状态/RestoreApp/FirstViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FirstViewController.swift
3 | // RestoreApp
4 | //
5 | // Created by Dariel on 2019/6/19.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class FirstViewController: UIViewController {
12 |
13 | @IBOutlet weak var sliderView: UISlider!
14 | override func viewDidLoad() {
15 | super.viewDidLoad()
16 |
17 | restorationIdentifier = String(describing: type(of: self))
18 | }
19 |
20 |
21 | }
22 |
23 |
24 | extension FirstViewController {
25 |
26 | override func encodeRestorableState(with coder: NSCoder) {
27 | super.encodeRestorableState(with: coder)
28 |
29 | guard let loadedSlider = sliderView, isViewLoaded else {
30 | return
31 | }
32 | coder.encode(loadedSlider.value, forKey: .encodingKeySliderValue)
33 | }
34 |
35 | override func decodeRestorableState(with coder: NSCoder) {
36 | super.decodeRestorableState(with: coder)
37 | assert(isViewLoaded, "We assume the controller is never restored without loading its view first.")
38 | sliderView?.value = coder.decodeFloat(forKey: .encodingKeySliderValue)
39 | }
40 |
41 | override func applicationFinishedRestoringState() {
42 | print("Finished restoring everything.")
43 | }
44 | }
45 |
46 |
47 | fileprivate extension String {
48 | static let encodingKeySliderValue = "encodingKeySliderValue"
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/Demo/58.恢复非正常终止的应用状态/RestoreApp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Demo/58.恢复非正常终止的应用状态/RestoreApp/LastViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LastViewController.swift
3 | // RestoreApp
4 | //
5 | // Created by Dariel on 2019/6/19.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class LastViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | view.backgroundColor = UIColor.white
17 | navigationItem.title = "LastViewController"
18 |
19 | restorationIdentifier = "LastViewController"
20 | restorationClass = LastViewController.self
21 |
22 | }
23 |
24 | override func applicationFinishedRestoringState() {
25 | print("Finished restoring everything.")
26 | }
27 | }
28 |
29 | extension LastViewController: UIViewControllerRestoration {
30 | static func viewController(withRestorationIdentifierPath identifierComponents: [String], coder: NSCoder) -> UIViewController? {
31 | let vc = LastViewController()
32 | return vc
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Demo/58.恢复非正常终止的应用状态/RestoreApp/NavController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // RestoreApp
4 | //
5 | // Created by Dariel on 2019/6/19.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class NavController: UINavigationController {
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/Demo/58.恢复非正常终止的应用状态/RestoreApp/SecondViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SecondViewController.swift
3 | // RestoreApp
4 | //
5 | // Created by Dariel on 2019/6/19.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SecondViewController: UIViewController {
12 |
13 | @IBOutlet weak var inputField: UITextField!
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 | }
18 |
19 | @IBAction func touch(_ sender: Any) {
20 | let vc = LastViewController()
21 | navigationController?.pushViewController(vc, animated: true)
22 | }
23 | }
24 |
25 | extension SecondViewController {
26 |
27 | override func encodeRestorableState(with coder: NSCoder) {
28 | super.encodeRestorableState(with: coder)
29 |
30 | guard let input = inputField.text, isViewLoaded else {
31 | return
32 | }
33 | coder.encode(input, forKey: .encodingKeyFieldValue)
34 | }
35 |
36 | override func decodeRestorableState(with coder: NSCoder) {
37 | super.decodeRestorableState(with: coder)
38 | assert(isViewLoaded, "We assume the controller is never restored without loading its view first.")
39 | inputField.text = coder.decodeObject(forKey: .encodingKeyFieldValue) as? String
40 | }
41 |
42 | override func applicationFinishedRestoringState() {
43 | print("Finished restoring everything.")
44 | }
45 | }
46 |
47 |
48 | fileprivate extension String {
49 | static let encodingKeyFieldValue = "encodingKeyFieldValue"
50 | }
51 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/chili.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "chili.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/chili.imageset/chili.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/chili.imageset/chili.png
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/lemon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "lemon.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/lemon.imageset/lemon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/lemon.imageset/lemon.png
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/mushroom.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "mushroom.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/mushroom.imageset/mushroom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/mushroom.imageset/mushroom.png
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/orange.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "orange.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/orange.imageset/orange.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/orange.imageset/orange.png
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/radish.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "radish.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/radish.imageset/radish.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/radish.imageset/radish.png
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/watermelon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "watermelon.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/watermelon.imageset/watermelon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/62.插件化TableView/PluginTableView/Assets.xcassets/watermelon.imageset/watermelon.png
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/BaseController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // PluginTableView
4 | //
5 | // Created by Dariel on 2019/8/6.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class BaseController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | setUpTableView()
17 | }
18 |
19 | func setUpTableView() {
20 |
21 | let section = Section(items: ["1.纯代码创建Cell", "2.Xib创建Cell", "3.不同类型cell分组"])
22 | let dataSource = DataSource(sections: [section])
23 |
24 | let configuartor = Configurator{ (cell, model: String, tableView, indexPath) -> UITableViewCell in
25 | cell.textLabel?.text = model
26 | return cell
27 | }
28 |
29 | let pluginTableView = PluginTableView(frame: view.bounds, style: .plain, dataSource: dataSource, configurator: configuartor)
30 | pluginTableView.tableView.tableFooterView = UIView()
31 | view.addSubview(pluginTableView)
32 |
33 | pluginTableView.didSelectRow = { [weak self] (tableView, indexPath) in
34 |
35 | switch indexPath.row {
36 |
37 | case 0:
38 | self?.navigationController?.pushViewController(FirstViewController(), animated: true)
39 | break
40 | case 1:
41 | self?.navigationController?.pushViewController(SecondViewController(), animated: true)
42 | break
43 | case 2:
44 | self?.navigationController?.pushViewController(ThirdViewController(), animated: true)
45 | break
46 | default:
47 | break
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Cell/CodeableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CustomTableViewCell.swift
3 | // PluginTableView
4 | //
5 | // Created by Dariel on 2019/8/7.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CodeTableViewCell: UITableViewCell {
12 | var iconLabel: UILabel
13 | var iconView: UIImageView
14 |
15 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
16 |
17 | iconLabel = UILabel()
18 | iconView = UIImageView()
19 |
20 | super.init(style: style, reuseIdentifier: reuseIdentifier)
21 |
22 | self.contentView.addSubview(iconLabel)
23 | self.contentView.addSubview(iconView)
24 |
25 | setUpViews()
26 | }
27 |
28 | @available(*, unavailable)
29 | required init?(coder aDecoder: NSCoder) {
30 | fatalError("init(coder:) has not been implemented")
31 | }
32 |
33 | private func setUpViews() {
34 | iconLabel.translatesAutoresizingMaskIntoConstraints = false
35 | iconView.translatesAutoresizingMaskIntoConstraints = false
36 |
37 | NSLayoutConstraint.activate([
38 |
39 | iconView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 8),
40 | iconView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 8),
41 | iconView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -8),
42 | iconView.widthAnchor.constraint(equalTo: iconView.heightAnchor),
43 |
44 | iconLabel.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor),
45 | iconLabel.leadingAnchor.constraint(equalTo: iconView.trailingAnchor, constant: 16)
46 | ])
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Cell/NibTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NibTableViewCell.swift
3 | // PluginTableView
4 | //
5 | // Created by Dariel on 2019/8/7.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class NibTableViewCell: UITableViewCell {
12 |
13 | @IBOutlet weak var iconView: UIImageView!
14 | @IBOutlet weak var iconLabel: UILabel!
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/FirstViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FirstViewController.swift
3 | // PluginTableView
4 | //
5 | // Created by Dariel on 2019/8/7.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class FirstViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | view.backgroundColor = .groupTableViewBackground
17 | setUpTableView()
18 | }
19 |
20 | func setUpTableView() {
21 |
22 | let section = Section(items: [
23 | CNCellModel(name: "柠檬", imageStr: "lemon"),
24 | CNCellModel(name: "橙子", imageStr: "orange"),
25 | CNCellModel(name: "西瓜", imageStr: "watermelon")
26 | ])
27 | let dataSource = DataSource(sections: [section])
28 |
29 | let configuartor = Configurator { (cell, model: CNCellModel, tableView, indexPath) -> CodeTableViewCell in
30 | cell.iconLabel.text = model.name
31 | cell.iconView.image = UIImage(named: model.imageStr)
32 | return cell
33 | }
34 |
35 | let pluginTableView = PluginTableView(frame: view.bounds, style: .plain, dataSource: dataSource, configurator: configuartor)
36 | pluginTableView.tableView.tableFooterView = UIView()
37 | pluginTableView.tableView.rowHeight = 80
38 | view.addSubview(pluginTableView)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/Model/CellModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CellModel.swift
3 | // PluginTableView
4 | //
5 | // Created by Dariel on 2019/8/7.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct CNCellModel {
12 | var name: String
13 | var imageStr: String
14 | }
15 |
16 | struct ENCellModel {
17 | var name: String
18 | var imageStr: String
19 | }
20 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/PluginTableView/Configurator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Configurator.swift
3 | // PluginTableView
4 | //
5 | // Created by Dariel on 2019/8/7.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol ConfiguratorType {
12 | associatedtype Item
13 | associatedtype Cell: UITableViewCell
14 |
15 | func reuseIdentifier(for item: Item, indexPath: IndexPath) -> String
16 | func registerCells(in tableView: UITableView)
17 | func configure(cell: Cell, item: Item, tableView: UITableView, indexPath: IndexPath) -> Cell
18 |
19 | }
20 | extension ConfiguratorType {
21 |
22 | func configuredCell(for item: Item, tableView: UITableView, indexPath: IndexPath) -> Cell {
23 | let reuseIdentifier = self.reuseIdentifier(for: item, indexPath: indexPath)
24 | let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! Cell
25 | return self.configure(cell: cell, item: item, tableView: tableView, indexPath: indexPath)
26 | }
27 | }
28 | struct Configurator- : ConfiguratorType {
29 |
30 | func configure(cell: Cell, item: Item, tableView: UITableView, indexPath: IndexPath) -> Cell {
31 | return configurator(cell, item, tableView, indexPath)
32 | }
33 |
34 | typealias CellConfigurator = (Cell, Item, UITableView, IndexPath) -> Cell
35 |
36 | let configurator: CellConfigurator
37 | let reuseIdentifier = "\(Cell.self)"
38 |
39 | func reuseIdentifier(for item: Item, indexPath: IndexPath) -> String {
40 | return reuseIdentifier
41 | }
42 |
43 | func registerCells(in tableView: UITableView) {
44 | if let path = Bundle.main.path(forResource: "\(Cell.self)", ofType: "nib"),
45 | FileManager.default.fileExists(atPath: path) {
46 | let nib = UINib(nibName: "\(Cell.self)", bundle: .main)
47 | tableView.register(nib, forCellReuseIdentifier: reuseIdentifier)
48 | } else {
49 | tableView.register(Cell.self, forCellReuseIdentifier: reuseIdentifier)
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/PluginTableView/DataSource.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DataSource.swift
3 | // PluginTableView
4 | //
5 | // Created by Dariel on 2019/8/7.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct DataSource
- {
12 | var sections: [Section
- ]
13 |
14 | func numberOfSections() -> Int {
15 | return sections.count
16 | }
17 |
18 | func numberOfItems(in section: Int) -> Int {
19 | guard section < sections.count else { return 0 }
20 | return sections[section].items.count
21 | }
22 |
23 | func item(at indexPath: IndexPath) -> Item {
24 | return sections[indexPath.section].items[indexPath.row]
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/PluginTableView/PluginTableView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PluginTableView.swift
3 | // PluginTableView
4 | //
5 | // Created by Dariel on 2019/8/7.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PluginTableView: UIView, UITableViewDataSource, UITableViewDelegate {
12 |
13 | var tableView: UITableView
14 | private let dataSource: DataSource
15 | private let configurator: Configurator
16 |
17 | var didSelectRow: ((UITableView, IndexPath) -> Void)?
18 |
19 | init(frame: CGRect, style: UITableView.Style, dataSource: DataSource, configurator: Configurator) {
20 | self.dataSource = dataSource
21 | self.configurator = configurator
22 |
23 | self.tableView = UITableView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height), style: style)
24 | super.init(frame: frame)
25 |
26 | tableView.dataSource = self
27 | tableView.delegate = self
28 | self.addSubview(tableView)
29 | configurator.registerCells(in: tableView)
30 | }
31 |
32 | @available(*, unavailable)
33 | required init?(coder aDecoder: NSCoder) {
34 | fatalError("init(coder:) has not been implemented")
35 | }
36 |
37 |
38 | // MARK: - 数据源
39 | func numberOfSections(in tableView: UITableView) -> Int {
40 | return dataSource.numberOfSections()
41 | }
42 |
43 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
44 | return dataSource.numberOfItems(in: section)
45 | }
46 |
47 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
48 | let item = dataSource.item(at: indexPath)
49 | return configurator.configuredCell(for: item, tableView: tableView, indexPath: indexPath)
50 | }
51 |
52 | // MARK: - 代理
53 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
54 | didSelectRow?(tableView, indexPath)
55 | }
56 |
57 | // ...
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/PluginTableView/Section.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Section.swift
3 | // PluginTableView
4 | //
5 | // Created by Dariel on 2019/8/7.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct Section
- {
12 | var items: [Item]
13 | }
14 |
--------------------------------------------------------------------------------
/Demo/62.插件化TableView/PluginTableView/SecondViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SecondViewController.swift
3 | // PluginTableView
4 | //
5 | // Created by Dariel on 2019/8/7.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SecondViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | view.backgroundColor = .groupTableViewBackground
17 | setUpTableView()
18 | }
19 |
20 | func setUpTableView() {
21 |
22 | let section = Section(items: [
23 | ENCellModel(name: "chili", imageStr: "chili"),
24 | ENCellModel(name: "mushroom", imageStr: "mushroom"),
25 | ENCellModel(name: "radish", imageStr: "radish")
26 | ])
27 | let dataSource = DataSource(sections: [section])
28 |
29 | let configuartor = Configurator{ (cell, model: ENCellModel, tableView, indexPath) -> NibTableViewCell in
30 | cell.iconLabel.text = model.name
31 | cell.iconView.image = UIImage(named: model.imageStr)
32 | return cell
33 | }
34 |
35 | let pluginTableView = PluginTableView(frame: view.bounds, style: .plain, dataSource: dataSource, configurator: configuartor)
36 | pluginTableView.tableView.tableFooterView = UIView()
37 | pluginTableView.tableView.rowHeight = 80
38 | view.addSubview(pluginTableView)
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/Demo/63.自定义底部弹层控制器/PresentPartController.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/63.自定义底部弹层控制器/PresentPartController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/63.自定义底部弹层控制器/PresentPartController/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // PresentPartController
4 | //
5 | // Created by Dariel on 2020/4/8.
6 | // Copyright © 2020 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Demo/63.自定义底部弹层控制器/PresentPartController/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | }
93 | ],
94 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Demo/63.自定义底部弹层控制器/PresentPartController/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Demo/63.自定义底部弹层控制器/PresentPartController/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/63.自定义底部弹层控制器/PresentPartController/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // PresentPartController
4 | //
5 | // Created by Dariel on 2020/4/8.
6 | // Copyright © 2020 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | }
16 | @IBAction func btnTouch(_ sender: Any) {
17 | present(PresentPartController(), animated: true, completion: nil)
18 |
19 | }
20 |
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // DCTheme
4 | //
5 | // Created by Dariel on 2018/10/9.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 |
19 | return true
20 | }
21 | }
22 |
23 |
24 |
25 |
26 |
27 | public protocol With {}
28 |
29 | public extension With where Self: Any {
30 |
31 | /// 初始化之后通过闭包设置属性
32 | ///
33 | /// let label = UILabel().with {
34 | /// $0.textAlignment = .center
35 | /// $0.textColor = UIColor.black
36 | /// $0.text = "Hello, World!"
37 | /// }
38 | @discardableResult
39 | func with(_ block: (Self) -> Void) -> Self {
40 | // https://github.com/devxoul/Then
41 | block(self)
42 | return self
43 | }
44 | }
45 | extension NSObject: With {}
46 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/one.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "one@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "one@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/one.imageset/one@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/one.imageset/one@2x.png
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/one.imageset/one@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/one.imageset/one@3x.png
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/two.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "two@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "two@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/two.imageset/two@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/two.imageset/two@2x.png
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/two.imageset/two@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Demo/9.使用面向协议实现app的主题功能/DCTheme/Assets.xcassets/two.imageset/two@3x.png
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Extensions/UIColor+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Extension.swift
3 | // DCTheme
4 | //
5 | // Created by Dariel on 2018/10/10.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIColor {
12 | public class var darkNight: UIColor {
13 | return UIColor(2, 21, 40)
14 | }
15 | public class var dayBlue: UIColor {
16 | return UIColor(43, 89, 185)
17 | }
18 | public class var darkText: UIColor {
19 | return UIColor(75, 79, 103)
20 | }
21 | public class var lightText: UIColor {
22 | return UIColor(83, 115, 169)
23 | }
24 | public class var selectdLightBlue: UIColor {
25 | return UIColor(153, 189, 223)
26 | }
27 | public convenience init(_ r: CGFloat, _ g: CGFloat, _ b: CGFloat, _ a: CGFloat = 1) {
28 | self.init(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: a)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Extensions/UITableViewCell+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UITableViewCell+Extension.swift
3 | // DCTheme
4 | //
5 | // Created by Dariel on 2018/10/10.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UITableViewCell {
12 | /// cell选中时的颜色
13 | @objc dynamic var selectedColor: UIColor? {
14 | get { return selectedBackgroundView?.backgroundColor }
15 | set {
16 | guard selectionStyle != .none else { return }
17 | selectedBackgroundView = UIView().with {
18 | $0.backgroundColor = newValue
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Extensions/UIView+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Extension.swift
3 | // DCTheme
4 | //
5 | // Created by Dariel on 2018/10/10.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIView {
12 | /// 边框颜色
13 | @IBInspectable var borderColor: UIColor? {
14 | get {
15 | guard let color = layer.borderColor else { return nil }
16 | return UIColor(cgColor: color)
17 | }
18 |
19 | set {
20 | guard let color = newValue else {
21 | layer.borderColor = nil
22 | return
23 | }
24 |
25 | layer.borderColor = color.cgColor
26 | }
27 | }
28 | /// 边框宽度
29 | @IBInspectable var borderWidth: CGFloat {
30 | get { return layer.borderWidth }
31 | set { layer.borderWidth = newValue }
32 | }
33 | /// 圆角半径
34 | @IBInspectable var cornerRadius: CGFloat {
35 | get { return layer.cornerRadius }
36 |
37 | set {
38 | layer.masksToBounds = true
39 | layer.cornerRadius = newValue
40 | }
41 | }
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Extensions/UIWindow+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIWindow+Extension.swift
3 | // DCTheme
4 | //
5 | // Created by Dariel on 2018/10/10.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIWindow {
12 | /// 刷新所有子控件
13 | func reload() {
14 | subviews.forEach { view in
15 | view.removeFromSuperview()
16 | addSubview(view)
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/MainViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // DCTheme
4 | //
5 | // Created by Dariel on 2018/10/9.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MainViewController: UIViewController {
12 | @IBOutlet weak var segmentedControl: UISegmentedControl!
13 |
14 | override func viewDidLoad() {
15 | super.viewDidLoad()
16 |
17 | segmentedControl.selectedSegmentIndex = 0
18 | LightTheme().apply(for: UIApplication.shared)
19 | }
20 |
21 | @IBAction func themeSegmentedControlChanged(_ sender: UISegmentedControl) {
22 |
23 | let theme: Theme
24 | switch sender.selectedSegmentIndex {
25 | case 0: theme = LightTheme()
26 | case 1: theme = BlueTheme()
27 | default: theme = DarkTheme()
28 | }
29 | theme.apply(for: UIApplication.shared)
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Theme/BlueTheme.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BlueTheme.swift
3 | // DCTheme
4 | //
5 | // Created by Dariel on 2018/10/9.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | struct BlueTheme: Theme {
12 |
13 | let tint: UIColor = UIColor.dayBlue
14 | let barStyle: UIBarStyle = .black
15 |
16 | let labelColor: UIColor = UIColor(32, 42, 46)
17 | let labelSelectedColor: UIColor = UIColor.white
18 |
19 | let backgroundColor: UIColor = UIColor(219, 242, 255)
20 | let separatorColor: UIColor = UIColor(210, 234, 250)
21 | let selectedColor: UIColor = UIColor.selectdLightBlue
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Theme/DarkTheme.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DarkTheme.swift
3 | // DCTheme
4 | //
5 | // Created by Dariel on 2018/10/9.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | struct DarkTheme: Theme {
12 |
13 | let tint: UIColor = UIColor.darkNight
14 | let barStyle: UIBarStyle = .black
15 |
16 | let labelColor: UIColor = UIColor.lightText
17 | let labelSelectedColor: UIColor = .white
18 |
19 | let backgroundColor: UIColor = UIColor(23, 35, 61)
20 | let separatorColor: UIColor = UIColor(12, 23, 45)
21 | let selectedColor: UIColor = UIColor(22, 37, 66)
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/Theme/LightTheme.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LightTheme.swift
3 | // DCTheme
4 | //
5 | // Created by Dariel on 2018/10/9.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | struct LightTheme: Theme {
12 |
13 | let tint: UIColor = .white
14 | let barStyle: UIBarStyle = .default
15 |
16 | let labelColor: UIColor = UIColor.darkText
17 | let labelSelectedColor: UIColor = UIColor.lightText
18 |
19 | let backgroundColor: UIColor = .white
20 | let separatorColor: UIColor = .lightGray
21 | let selectedColor: UIColor = UIColor(236, 236, 236)
22 |
23 | }
24 |
25 | extension LightTheme {
26 |
27 | // 需要自定义的部分写在这边
28 | func extend() {
29 |
30 | UISegmentedControl.appearance().with {
31 | $0.tintColor = UIColor.darkText
32 | $0.setTitleTextAttributes([.foregroundColor : labelColor], for: .normal)
33 | $0.setTitleTextAttributes([.foregroundColor : UIColor.white], for: .selected)
34 | }
35 |
36 | UISlider.appearance().tintColor = UIColor.darkText
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Demo/9.使用面向协议实现app的主题功能/DCTheme/View/BackgroundView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BackgroundView.swift
3 | // DCTheme
4 | //
5 | // Created by Dariel on 2018/10/10.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class BackgroundView: UIView {
12 | }
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Dariel
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MyPlayground.playground/Pages/1.常用的几个高阶函数.xcplaygroundpage/Contents.swift:
--------------------------------------------------------------------------------
1 | //: [Previous](@previous)
2 |
3 | import Foundation
4 |
5 | let intArr = [13, 45, 27, 80, 22, 53]
6 |
7 | let sortOneArr = intArr.sorted { (a: Int, b: Int) -> Bool in
8 | return a < b
9 | }
10 | sortOneArr
11 |
12 | let sortTwoArr = intArr.sorted { (a: Int, b: Int) in
13 | return a < b
14 | }
15 | sortTwoArr
16 |
17 | let sortThreeArr = intArr.sorted { (a, b) in
18 | return a < b
19 | }
20 | sortThreeArr
21 |
22 | let sortFourArr = intArr.sorted {
23 | return $0 < $1
24 | }
25 | sortFourArr
26 |
27 | let sortFiveArr = intArr.sorted {
28 | $0 < $1
29 | }
30 | sortFiveArr
31 |
32 | let sortSixArr = intArr.sorted(by: <)
33 | sortSixArr
34 |
35 |
36 | let mapArr = intArr.map { $0 * $0 }
37 | mapArr
38 |
39 | let optionalArr = [nil, 4, 12, 7, Optional(3), 9]
40 | let compactMapArr = optionalArr.compactMap { $0 }
41 | compactMapArr
42 |
43 | let evenArr = intArr.filter { $0 % 2 == 0 }
44 | evenArr
45 |
46 | let stringArr = ["1", "2", "3", "*", "a"]
47 | let allStr = stringArr.reduce("") { $0 + $1 }
48 | allStr
49 |
50 |
51 | let chainArr = [4, 3, 5, 8, 6, 2, 4, 7]
52 | let resultArr = chainArr.filter {
53 | $0 % 2 == 0
54 | }.map {
55 | $0 * $0
56 | }.reduce(0) {
57 | $0 + $1
58 | }
59 | resultArr
60 |
--------------------------------------------------------------------------------
/MyPlayground.playground/Pages/2.高阶函数扩展.xcplaygroundpage/Contents.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | class Pet {
4 | let type: String
5 | let age: Int
6 |
7 | init(type: String, age: Int) {
8 | self.type = type
9 | self.age = age
10 | }
11 | }
12 |
13 | var pets = [
14 | Pet(type: "dog", age: 5),
15 | Pet(type: "cat", age: 3),
16 | Pet(type: "sheep", age: 1),
17 | Pet(type: "pig", age: 2),
18 | Pet(type: "cat", age: 3),
19 | ]
20 |
21 | pets.forEach { p in
22 | print(p.type)
23 | }
24 |
25 | let cc = pets.contains { $0.type == "cat" }
26 | cc
27 |
28 | let firstIndex = pets.firstIndex { $0.age == 3 }
29 | firstIndex
30 |
31 | let lastIndex = pets.lastIndex { $0.age == 3 }
32 | lastIndex
33 |
34 | let sortArr = pets.sorted { $0.age < $1.age }
35 | sortArr
36 |
37 | let arr1 = pets.prefix { $0.age > 3 }
38 | arr1
39 |
40 | let arr2 = pets.drop { $0.age > 3 }
41 | arr2
42 |
43 |
44 | let line = "BLANCHE: I don't want realism. I want magic!"
45 |
46 | let wordArr = line.split(whereSeparator: { $0 == " " })
47 | wordArr
48 |
--------------------------------------------------------------------------------
/MyPlayground.playground/Pages/3.优雅的判断多个值中是否包含某一个值.xcplaygroundpage/Contents.swift:
--------------------------------------------------------------------------------
1 | //: [Previous](@previous)
2 |
3 | import Foundation
4 |
5 | let string = "One"
6 |
7 | // 方案1
8 | if string == "One" || string == "Two" || string == "Three" {
9 | print("One")
10 | }
11 |
12 | // 方案2
13 | if ["One", "Two", "Three"].contains(where: { $0 == "One"}) {
14 | print("One")
15 | }
16 |
17 |
18 | // 方案3
19 | func any(of values: T...) -> EquatableValueSequence {
20 | return EquatableValueSequence(values: values)
21 | }
22 |
23 | struct EquatableValueSequence {
24 | static func ==(lhs: EquatableValueSequence, rhs: T) -> Bool {
25 | return lhs.values.contains(rhs)
26 | }
27 |
28 | static func ==(lhs: T, rhs: EquatableValueSequence) -> Bool {
29 | return rhs == lhs
30 | }
31 |
32 | fileprivate let values: [T]
33 | }
34 |
35 | if string == any(of: "One", "Two", "Three") {
36 | print("One")
37 | }
38 |
--------------------------------------------------------------------------------
/MyPlayground.playground/Pages/4. Hashable、Equatable和Comparable协议.xcplaygroundpage/Contents.swift:
--------------------------------------------------------------------------------
1 | //: [Previous](@previous)
2 |
3 | import Foundation
4 |
5 | struct Pet: Equatable {
6 | let name: String
7 | let age: Int
8 | }
9 |
10 |
11 | let p1 = Pet(name: "Cat", age: 2)
12 | let p2 = Pet(name: "Dog", age: 3)
13 |
14 | p1 == p2
15 |
16 |
17 | enum Season: Equatable {
18 | case spring(mouth: String)
19 | case summer
20 | case autumn(mouth: String)
21 | case winter
22 | }
23 |
24 | let season1 = Season.spring(mouth: "4")
25 | let season2 = Season.autumn(mouth: "4")
26 |
27 | season1 == season2
28 |
29 |
30 | class Animal: Equatable, Hashable, Comparable {
31 |
32 | static func < (lhs: Animal, rhs: Animal) -> Bool {
33 | if lhs.age < rhs.age{
34 | return true
35 | }else {
36 | return false
37 | }
38 | }
39 |
40 | static func == (lhs: Animal, rhs: Animal) -> Bool {
41 | if lhs.type == rhs.type && lhs.age == rhs.age{
42 | return true
43 | }else {
44 | return false
45 | }
46 | }
47 |
48 | var hashValue: Int {
49 | return self.type.hashValue ^ self.age.hashValue
50 |
51 | }
52 |
53 | let type: String
54 | let age: Int
55 |
56 | init(type: String, age: Int) {
57 | self.type = type
58 | self.age = age
59 | }
60 | }
61 |
62 |
63 | let a1 = Animal(type: "Cat", age: 3)
64 | let a2 = Animal(type: "Cat", age: 4)
65 | let a3 = Animal(type: "Cat", age: 1)
66 | let a4 = Animal(type: "Cat", age: 6)
67 |
68 |
69 | a1 == a2
70 |
71 | a1.hashValue
72 | a2.hashValue
73 |
74 |
75 | let animals = [a1, a2, a3, a4]
76 |
77 |
78 | let b = a1 < a2
79 | let sortedAnimals = animals.sorted(by: <)
80 | sortedAnimals
81 |
--------------------------------------------------------------------------------
/MyPlayground.playground/Pages/5.可变参数函数.xcplaygroundpage/Contents.swift:
--------------------------------------------------------------------------------
1 | //: [Previous](@previous)
2 |
3 | import Foundation
4 |
5 |
6 | /// 求和
7 | // 常用的姿势
8 | let sum2 = [2, 3, 4, 5, 6, 7, 8, 9].reduce(0) { $0 + $1 }
9 | sum2
10 |
11 | // 使用可变参数函数
12 | sum(values: 2, 3, 4, 5, 6, 7, 8, 9)
13 |
14 | // 可变参数的类型是个数组
15 | func sum(values:Int...) -> Int {
16 | var result = 0
17 | values.forEach({ a in
18 | result += a
19 | })
20 | return result
21 | }
22 |
23 |
24 |
--------------------------------------------------------------------------------
/MyPlayground.playground/Pages/6.where关键字.xcplaygroundpage/Contents.swift:
--------------------------------------------------------------------------------
1 | //: [Previous](@previous)
2 |
3 | import Foundation
4 |
5 | // for循环的时候添加限定条件
6 | let arr = [11, 12, 13, 14, 15, 16, 17, 18]
7 | for num in arr where num % 2 == 0 {
8 | // 12 14 16 18
9 | num
10 | }
11 |
12 |
13 | // 在try catch的时候做条件判断
14 | enum ExceptionError:Error{
15 | case httpCode(Int)
16 | }
17 |
18 | func throwError() throws {
19 | throw ExceptionError.httpCode(500)
20 | }
21 |
22 | do{
23 | try throwError()
24 | }catch ExceptionError.httpCode(let httpCode) where httpCode >= 500{
25 | print("server error")
26 | }catch {
27 | print("other error")
28 | }
29 |
30 |
31 | // switch语句做限定条件
32 | let student:(name:String, score:Int) = ("小明", 59)
33 | switch student {
34 | case let (_,score) where score < 60:
35 | print("不及格")
36 | default:
37 | print("及格")
38 | }
39 |
40 | // 限定泛型需要遵守的协议
41 | //第一种写法
42 | func genericFunctionA
(str:S) where S:ExpressibleByStringLiteral{
43 | print(str)
44 | }
45 | //第二种写法
46 | func genericFunctionB(str:S){
47 | print(str)
48 | }
49 |
50 |
51 | // 为指定的类添加对应的协议扩展
52 | extension Sequence where Element: Numeric {
53 | var sum: Element {
54 | var result: Element = 0
55 | for item in self {
56 | result += item
57 | }
58 | return result
59 | }
60 | }
61 |
62 | print([1,2,3,4].sum)
63 |
64 |
65 | // 做某些高阶函数的限定条件
66 | let names = ["Joan", "John", "Jack"]
67 | let firstJname = names.first(where: { (name) -> Bool in
68 | return name.first == "J"
69 | })
70 | firstJname
71 |
72 | let fruits = ["Banana", "Apple", "Kiwi"]
73 | let containsBanana = fruits.contains(where: { (fruit) in
74 | return fruit == "Banana"
75 | })
76 | containsBanana
77 |
--------------------------------------------------------------------------------
/MyPlayground.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Source/IBDesignableView.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/IBDesignableView.png
--------------------------------------------------------------------------------
/Source/TableViewRefreshAnimation2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/TableViewRefreshAnimation2.gif
--------------------------------------------------------------------------------
/Source/addContainerView.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/addContainerView.png
--------------------------------------------------------------------------------
/Source/addshortcuts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/addshortcuts.png
--------------------------------------------------------------------------------
/Source/addshortcutsgif.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/addshortcutsgif.gif
--------------------------------------------------------------------------------
/Source/anchor_autoLayout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/anchor_autoLayout.png
--------------------------------------------------------------------------------
/Source/attributed_url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/attributed_url.png
--------------------------------------------------------------------------------
/Source/blink_scale_corner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/blink_scale_corner.gif
--------------------------------------------------------------------------------
/Source/changeStatusBarStyle2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/changeStatusBarStyle2.gif
--------------------------------------------------------------------------------
/Source/color_wheel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/color_wheel.png
--------------------------------------------------------------------------------
/Source/custom_actionsheet.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/custom_actionsheet.gif
--------------------------------------------------------------------------------
/Source/embedTableViewController.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/embedTableViewController.png
--------------------------------------------------------------------------------
/Source/namespace_module.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/namespace_module.png
--------------------------------------------------------------------------------
/Source/padding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/padding.png
--------------------------------------------------------------------------------
/Source/popOverView.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/popOverView.gif
--------------------------------------------------------------------------------
/Source/present_part_controller.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/present_part_controller.gif
--------------------------------------------------------------------------------
/Source/restoration_id.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/restoration_id.png
--------------------------------------------------------------------------------
/Source/shadow_move.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/shadow_move.gif
--------------------------------------------------------------------------------
/Source/showStyle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/showStyle.png
--------------------------------------------------------------------------------
/Source/tabbarAnimating.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/tabbarAnimating.gif
--------------------------------------------------------------------------------
/Source/themeDemo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/themeDemo.gif
--------------------------------------------------------------------------------
/Source/toast_view.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/toast_view.gif
--------------------------------------------------------------------------------
/Source/yellow_pixel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/Source/yellow_pixel.png
--------------------------------------------------------------------------------
/SwiftTipsDemo/DCTool/DCTool/DCTool.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DCTool.swift
3 | // SwiftTipsDemo
4 | //
5 | // Created by Dariel on 2018/9/30.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | /// 判断多个值中是否包含某一个值
11 | ///
12 | /// - Parameter values: 需要比较的值,可以是多个
13 | /// - Returns: 可以用` ==`比较的类型
14 | ///
15 | /// let string = "One"
16 | ///
17 | /// if string == any(of: "One", "Two", "Three") {
18 | ///
19 | /// }
20 | func any(of values: T...) -> EquatableValueSequence {
21 | return EquatableValueSequence(values: values)
22 | }
23 |
24 | struct EquatableValueSequence {
25 | static func == (lhs: EquatableValueSequence, rhs: T) -> Bool {
26 | return lhs.values.contains(rhs)
27 | }
28 | static func == (lhs: T, rhs: EquatableValueSequence) -> Bool {
29 | return rhs == lhs
30 | }
31 | fileprivate let values: [T]
32 | }
33 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/DCTool/DCTool/EdgeInsetLabel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EdgeInsetLabel.swift
3 | // SwiftTipsDemo
4 | //
5 | // Created by Dariel on 2018/12/11.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @IBDesignable
12 | class EdgeInsetLabel: UILabel {
13 | var textInsets = UIEdgeInsets.zero {
14 | didSet { invalidateIntrinsicContentSize() }
15 | }
16 | override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
17 | let insetRect = bounds.inset(by: textInsets)
18 | let textRect = super.textRect(forBounds: insetRect, limitedToNumberOfLines: numberOfLines)
19 | let invertedInsets = UIEdgeInsets(top: -textInsets.top,
20 | left: -textInsets.left,
21 | bottom: -textInsets.bottom,
22 | right: -textInsets.right)
23 | return textRect.inset(by: invertedInsets)
24 | }
25 | override func drawText(in rect: CGRect) {
26 | super.drawText(in: rect.inset(by: textInsets))
27 | }
28 | }
29 |
30 | extension EdgeInsetLabel {
31 | @IBInspectable
32 | var leftTextInset: CGFloat {
33 | set { textInsets.left = newValue }
34 | get { return textInsets.left }
35 | }
36 | @IBInspectable
37 | var rightTextInset: CGFloat {
38 | set { textInsets.right = newValue }
39 | get { return textInsets.right }
40 | }
41 | @IBInspectable
42 | var topTextInset: CGFloat {
43 | set { textInsets.top = newValue }
44 | get { return textInsets.top }
45 | }
46 | @IBInspectable
47 | var bottomTextInset: CGFloat {
48 | set { textInsets.bottom = newValue }
49 | get { return textInsets.bottom }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/DCTool/DCTool/ViewControllerInjector.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewDidLoadInjector.swift
3 | // SwiftTipsDemo
4 | //
5 | // Created by Dariel on 2018/10/17.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import ObjectiveC.runtime
11 |
12 | class ViewControllerInjector {
13 | typealias MethodRef = @convention(c)(UIViewController, Selector) -> Void
14 | static func inject(into supportedClasses: [UIViewController.Type], selector: Selector,
15 | injection: @escaping (UIViewController) -> Void) {
16 | guard let originalMethod = class_getInstanceMethod(UIViewController.self, selector) else {
17 | fatalError("\(selector) must be implemented")
18 | }
19 | var originalIMP: IMP?
20 | let swizzledViewDidLoadBlock: @convention(block) (UIViewController) -> Void = { receiver in
21 | if let originalIMP = originalIMP {
22 | let castedIMP = unsafeBitCast(originalIMP, to: MethodRef.self)
23 | castedIMP(receiver, selector)
24 | }
25 | if ViewControllerInjector.canInject(to: receiver, supportedClasses: supportedClasses) {
26 | injection(receiver)
27 | }
28 | }
29 | let swizzledIMP = imp_implementationWithBlock(unsafeBitCast(swizzledViewDidLoadBlock, to: AnyObject.self))
30 | originalIMP = method_setImplementation(originalMethod, swizzledIMP)
31 | }
32 | private static func canInject(to receiver: Any, supportedClasses: [UIViewController.Type]) -> Bool {
33 | let supportedClassesIDs = supportedClasses.map { ObjectIdentifier($0) }
34 | let receiverType = type(of: receiver)
35 | return supportedClassesIDs.contains(ObjectIdentifier(receiverType))
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/DCTool/Extension/Collection+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Collection+Extension.swift
3 | // SwiftTipsDemo
4 | //
5 | // Created by Dariel on 2018/10/16.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension Collection {
12 | /// 判断是否有满足条件的元素
13 | ///
14 | /// [1, 2, 3, 4, 5].all { $0 > 10 }
15 | /// false
16 | func all(_ predicate: (Element) throws -> Bool) rethrows -> Bool {
17 | for item in self {
18 | let result = try predicate(item)
19 | if !result {
20 | return false
21 | }
22 | }
23 | return true
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/DCTool/Extension/UIColor+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Extension.swift
3 | // SwiftTipsDemo
4 | //
5 | // Created by Dariel on 2018/10/9.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIColor {
12 | class var darkNight: UIColor {
13 | return UIColor(2, 21, 51)
14 | }
15 | public convenience init(_ red: CGFloat, _ green: CGFloat, _ blue: CGFloat, _ alpha: CGFloat = 1) {
16 | self.init(red: red / 255.0, green: green / 255.0, blue: blue / 255.0, alpha: alpha)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/DCTool/Extension/UITableView+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UITableView+Extension.swift
3 | // SwiftTipsDemo
4 | //
5 | // Created by Dariel on 2019/3/19.
6 | // Copyright © 2019 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UITableView {
12 | /// 添加空白页
13 | ///
14 | /// - Parameter message: 空白页文字
15 | func setNoDataPlaceholder(_ message: String) {
16 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height))
17 | label.text = message
18 | label.textAlignment = .center
19 | label.sizeToFit()
20 | self.isScrollEnabled = false
21 | self.backgroundView = label
22 | self.separatorStyle = .none
23 | }
24 | /// 删除空白页
25 | func removeNoDataPlaceholder() {
26 | self.isScrollEnabled = true
27 | self.backgroundView = nil
28 | self.separatorStyle = .singleLine
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/DCTool/Extension/UIViewController+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+Extension.swift
3 | // SwiftTipsDemo
4 | //
5 | // Created by Dariel on 2018/10/15.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIViewController {
12 | public func dch_checkDeallocation(afterDelay delay: TimeInterval = 2.0) {
13 | let rootParentViewController = dchRootParentViewController
14 | if isMovingFromParent || rootParentViewController.isBeingDismissed {
15 | let disappearanceSource: String = isMovingFromParent ? "removed from its parent" : "dismissed"
16 | DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: { [weak self] in
17 | if let controller = self {
18 | assert(self == nil, "\(controller.description) not deallocated after being \(disappearanceSource)")
19 | }
20 | })
21 | }
22 | }
23 | private var dchRootParentViewController: UIViewController {
24 | var root = self
25 | while let parent = root.parent {
26 | root = parent
27 | }
28 | return root
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/DCTool/Extension/UIWindow+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIWindow+Extension.swift
3 | // SwiftTipsDemo
4 | //
5 | // Created by Dariel on 2018/10/9.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIWindow {
12 | /// 刷新所有的子控件
13 | func reload() {
14 | subviews.forEach { view in
15 | view.removeFromSuperview()
16 | addSubview(view)
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | target 'SwiftTipsDemo' do
5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
6 | use_frameworks!
7 |
8 | pod 'SwiftLint'
9 |
10 | # Pods for SwiftTipsDemo
11 |
12 | end
13 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - SwiftLint (0.27.0)
3 |
4 | DEPENDENCIES:
5 | - SwiftLint
6 |
7 | SPEC REPOS:
8 | https://github.com/cocoapods/specs.git:
9 | - SwiftLint
10 |
11 | SPEC CHECKSUMS:
12 | SwiftLint: 3207c1faa2240bf8973b191820a116113cd11073
13 |
14 | PODFILE CHECKSUM: 22de33a6ef19ed5ccc457ade870ff1ac04fbde91
15 |
16 | COCOAPODS: 1.5.3
17 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - SwiftLint (0.27.0)
3 |
4 | DEPENDENCIES:
5 | - SwiftLint
6 |
7 | SPEC REPOS:
8 | https://github.com/cocoapods/specs.git:
9 | - SwiftLint
10 |
11 | SPEC CHECKSUMS:
12 | SwiftLint: 3207c1faa2240bf8973b191820a116113cd11073
13 |
14 | PODFILE CHECKSUM: 22de33a6ef19ed5ccc457ade870ff1ac04fbde91
15 |
16 | COCOAPODS: 1.5.3
17 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/Pods/SwiftLint/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Realm Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/Pods/SwiftLint/swiftlint:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/SwiftTipsDemo/Pods/SwiftLint/swiftlint
--------------------------------------------------------------------------------
/SwiftTipsDemo/Pods/Target Support Files/Pods-SwiftTipsDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/Pods/Target Support Files/Pods-SwiftTipsDemo/Pods-SwiftTipsDemo-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## SwiftLint
5 |
6 | The MIT License (MIT)
7 |
8 | Copyright (c) 2015 Realm Inc.
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy
11 | of this software and associated documentation files (the "Software"), to deal
12 | in the Software without restriction, including without limitation the rights
13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | copies of the Software, and to permit persons to whom the Software is
15 | furnished to do so, subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in all
18 | copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 | SOFTWARE.
27 |
28 | Generated by CocoaPods - https://cocoapods.org
29 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/Pods/Target Support Files/Pods-SwiftTipsDemo/Pods-SwiftTipsDemo-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_SwiftTipsDemo : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_SwiftTipsDemo
5 | @end
6 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/Pods/Target Support Files/Pods-SwiftTipsDemo/Pods-SwiftTipsDemo-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_SwiftTipsDemoVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_SwiftTipsDemoVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/Pods/Target Support Files/Pods-SwiftTipsDemo/Pods-SwiftTipsDemo.debug.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
3 | PODS_BUILD_DIR = ${BUILD_DIR}
4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
6 | PODS_ROOT = ${SRCROOT}/Pods
7 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/Pods/Target Support Files/Pods-SwiftTipsDemo/Pods-SwiftTipsDemo.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_SwiftTipsDemo {
2 | umbrella header "Pods-SwiftTipsDemo-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/Pods/Target Support Files/Pods-SwiftTipsDemo/Pods-SwiftTipsDemo.release.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
3 | PODS_BUILD_DIR = ${BUILD_DIR}
4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
6 | PODS_ROOT = ${SRCROOT}/Pods
7 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/SwiftTipsDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/SwiftTipsDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/SwiftTipsDemo.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/SwiftTipsDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/SwiftTipsDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SwiftTipsDemo
4 | //
5 | // Created by Dariel on 2018/9/28.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(_ application: UIApplication,
17 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | return true
19 | }
20 | func applicationWillResignActive(_ application: UIApplication) {
21 | }
22 | func applicationDidEnterBackground(_ application: UIApplication) {
23 | }
24 | func applicationWillEnterForeground(_ application: UIApplication) {
25 | }
26 | func applicationDidBecomeActive(_ application: UIApplication) {
27 | }
28 | func applicationWillTerminate(_ application: UIApplication) {
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/SwiftTipsDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/SwiftTipsDemo/SwiftTipsDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/SwiftTipsDemo/SwiftTipsDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/SwiftTipsDemo/DetailViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DetailViewController.swift
3 | // SwiftTipsDemo
4 | //
5 | // Created by Dariel on 2018/10/18.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class DetailViewController: UIViewController {
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/SwiftTipsDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/SwiftTipsDemo/SwiftTipsDemo/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SwiftTipsDemo
4 | //
5 | // Created by Dariel on 2018/9/28.
6 | // Copyright © 2018年 Dariel. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/XcodeTips/source/after_refactor_storyboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/XcodeTips/source/after_refactor_storyboard.png
--------------------------------------------------------------------------------
/XcodeTips/source/breakpoint_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/XcodeTips/source/breakpoint_view.png
--------------------------------------------------------------------------------
/XcodeTips/source/control_distance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/XcodeTips/source/control_distance.png
--------------------------------------------------------------------------------
/XcodeTips/source/lock_control.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/XcodeTips/source/lock_control.png
--------------------------------------------------------------------------------
/XcodeTips/source/more_layer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/XcodeTips/source/more_layer.png
--------------------------------------------------------------------------------
/XcodeTips/source/refactor_storyboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/XcodeTips/source/refactor_storyboard.png
--------------------------------------------------------------------------------
/XcodeTips/source/rename.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/XcodeTips/source/rename.png
--------------------------------------------------------------------------------
/XcodeTips/source/set_storyboard_reference.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/XcodeTips/source/set_storyboard_reference.png
--------------------------------------------------------------------------------
/XcodeTips/source/storyboard_reference.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarielChen/iOSTips/0b1dcf69a63cf24c2858cf80ace0882580cd1072/XcodeTips/source/storyboard_reference.png
--------------------------------------------------------------------------------