[Swift通天遁地]九、拔剑吧-(13)创建页面的景深视差滚动效果
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10357961.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
景深视差经常被应用在游戏项目中。
本文将演示创建一个简单的景深视差滚动效果
首先确保已经安装了所需的第三方类库。双击查看安装配置文件【Podfile】
1 platform :ios, '12.0' 2 use_frameworks! 3 4 target 'DemoApp' do 5 source 'https://github.com/CocoaPods/Specs.git' 6 pod 'Presentation' 7 end
根据配置文件中的相关设置,安装第三方类库。
安装完成之后,双击打开项目文件【DemoApp.xcodeproj】
在左侧的项目导航区,打开应用程序的代理文件【AppDelegate.swift】。
1 import UIKit 2 //引入已经安装的第三方类库 3 import Presentation 4 5 @UIApplicationMain 6 class AppDelegate: UIResponder, UIApplicationDelegate { 7 8 var window: UIWindow? 9 10 //添加一个由第三方类库提供的控制器对象,作为当前类的一个属性。 11 lazy var presentationController: PresentationController = 12 { 13 //对控制器进行初始化操作, 14 let controller = PresentationController(pages: []) 15 //并隐藏导航条的标题 16 controller.setNavigationTitle = false 17 18 //返回设置好的控制器对象 19 return controller 20 }() 21 22 //添加一个导航条按钮控件,作为导航条左侧的按钮。 23 lazy var leftButton: UIBarButtonItem = { [unowned self] in 24 //对导航条按钮进行初始化操作, 25 //并设置它的标题,样式和动作属性。 26 let button = UIBarButtonItem(title: "Previous page", style: .plain, 27 target: self.presentationController, 28 action: #selector(PresentationController.moveBack)) 29 30 //设置标题的前景颜色为白色 31 button.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.white], for: .normal) 32 //返回设置好的按钮控件 33 return button 34 }() 35 36 //创建另一个导航条按钮控件,作为导航条右侧的按钮。 37 lazy var rightButton: UIBarButtonItem = { [unowned self] in 38 //对导航条按钮进行初始化操作,并设置它的标题、样式和动作属性。 39 let button = UIBarButtonItem(title: "Next page", style: .plain, 40 target: self.presentationController, 41 action: #selector(PresentationController.moveForward)) 42 43 //设置标题的前景颜色为白色, 44 button.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.white], for: .normal) 45 //并返回设置好的按钮控件 46 return button 47 }() 48 49 50 //在应用程序加载完成的方法中, 51 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 52 // Override point for customization after application launch. 53 54 //设置导航条的前景颜色为橙色。 55 UINavigationBar.appearance().barTintColor = UIColor.orange 56 //设置导航条的颜色为透明 57 UINavigationBar.appearance().barStyle = .blackTranslucent 58 59 //设置导航控制器左侧的导航按钮。 60 presentationController.navigationItem.leftBarButtonItem = leftButton 61 //设置导航控制器右侧的导航按钮。 62 presentationController.navigationItem.rightBarButtonItem = rightButton 63 64 //调用两个方法 65 //方法一:设置滚动的标题 66 configureSlides() 67 //方法二:设置具有景深效果的背景视图 68 configureBackground() 69 70 //初始化一个和屏幕尺寸相同的窗口对象 71 window = UIWindow(frame: UIScreen.main.bounds) 72 //初始化一个导航控制器对象,作为窗口对象的根视图控制器。 73 let navigationController = UINavigationController(rootViewController: self.presentationController) 74 //设置导航控制器的背景颜色为橙色。 75 navigationController.view.backgroundColor = UIColor.orange 76 77 //设置窗口对象的根视图控制器, 78 window?.rootViewController = navigationController 79 //并使窗口对象作为应用程序的主窗口 80 window?.makeKeyAndVisible() 81 82 return true 83 } 84 85 //添加一个方法,用来配置滚动标题 86 func configureSlides() 87 { 88 //初始化一个字体对象 89 let font = UIFont(name: "ArialRoundedMTBold", size: 32.0)! 90 //初始化一个颜色对象 91 let color = UIColor.white 92 //初始化一个段落样式对象, 93 let paragraphStyle = NSMutableParagraphStyle() 94 //并设置段落的对齐方式为居中 95 paragraphStyle.alignment = .center 96 97 //初始化一个属性常量,作为标题文字的字体、颜色和段落样式。 98 let attributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: color, NSAttributedString.Key.paragraphStyle: paragraphStyle] 99 100 //初始化一个字符串数组,作为五个滚动标题的内容。 101 let titles = ["Tutorial on how to make a profit", "Step I", "Step II", "Step III", "Thanks"].map { 102 //给每个滚动标题,设置相同的外观样式。 103 Content.content(forTitle: $0, attributes: attributes) 104 } 105 106 //初始化另一个字符串数组,作为滚动子标题的内容。 107 //并同样设置子标题的外观样式。 108 let texts = ["", "Collect underpants💭", "🎅🎅🏻🎅🏼🎅🏽🎅🏾🎅🏿", "Profit💸", ""].map { 109 Content.content(forText: $0, attributes: attributes) 110 } 111 112 //初始化一个滑动控制器类型的数组对象。 113 var slides = [SlideController]() 114 115 //添加一个执行五次的循环语句,用来往数组中添加控制器。 116 for index in 0...4 117 { 118 //初始化一个滑动控制器对象,并设置它的标题,子标题和滚动的动画效果 119 let controller = SlideController(contents: [titles[index], texts[index]]) 120 controller.add(animations: [Content.centerTransition(forSlideContent: titles[index]), Content.centerTransition(forSlideContent: texts[index])]) 121 122 //将滑动控制器对象添加到数组中。 123 slides.append(controller) 124 } 125 126 //滑动控制器对象可以添加多个内容,这里往数组的最后一个控制器中,添加一张图片。 127 slides[4].add(content: Content.content(forImage: UIImage(named: "HyperLogo")!)) 128 129 //将滑动控制器数组添加到景深视图控制器中。 130 presentationController.add(slides) 131 } 132 133 //添加另一个方法,用来配置具有景深效果的背景视图 134 func configureBackground() 135 { 136 //初始化一个图像视图数组,作为背景视图中的三张浮动图片。 137 let images = ["Cloud1", "Cloud2", "Cloud1"].map { 138 UIImageView(image: UIImage(named: $0)) 139 } 140 141 //添加一个视差内容,并设置它的初始位置在屏幕的最左边。 142 let content1 = Content(view: images[0], position: Position(left: -0.3, top: 0.2)) 143 //添加第二个视差内容,并设置它的初始位置在屏幕的最右边。 144 let content2 = Content(view: images[1], position: Position(right: -0.3, top: 0.22)) 145 //添加第三个视差内容,并设置它的初始位置在屏幕的中心。 146 //该视差内容将在标题滚动时,始终保持静止状态。 147 let content3 = Content(view: images[2], position: Position(left: 0.5, top: 0.5)) 148 149 //将三个视差内容,添加到背景视图。 150 presentationController.addToBackground([content1, content2, content3]) 151 152 //设置第一个页面的视差滚动效果, 153 presentationController.addAnimations([ 154 //将第一个视差内容,在水平方向上,向右滚动到0.2的位置 155 TransitionAnimation(content: content1, destination: Position(left: 0.2, top: 0.2)), 156 //将第二个视差内容,在水平方向上,向左滚动到0.3的位置 157 TransitionAnimation(content: content2, destination: Position(right: 0.3, top: 0.22)), 158 //给位于中心位置的视图内容,添加一个出栈动画。 159 PopAnimation(content: content3, duration: 1.0) 160 ], forPage: 0) 161 162 //设置第二个页面的视差滚动效果 163 presentationController.addAnimations([ 164 165 //将第一个视差内容,在水平方向上,向右滚动到0.3的位置 166 TransitionAnimation(content: content1, destination: Position(left: 0.3, top: 0.2)), 167 //将第二个视差内容,在水平方向上,向左滚动到0.4的位置 168 TransitionAnimation(content: content2, destination: Position(right: 0.4, top: 0.22)) 169 ], forPage: 1) 170 171 //设置第三个页面的视差滚动效果 172 presentationController.addAnimations([ 173 //将两个视差内容,在水平方向上都滚动到0.5的位置 174 TransitionAnimation(content: content1, destination: Position(left: 0.5, top: 0.2)), 175 TransitionAnimation(content: content2, destination: Position(right: 0.5, top: 0.22)) 176 ], forPage: 2) 177 178 //设置第四个页面的视差滚动效果 179 presentationController.addAnimations([ 180 //将第一个视差内容,在水平方向上,向右滚动到0.6的位置 181 TransitionAnimation(content: content1, destination: Position(left: 0.6, top: 0.2)), 182 //将第二个视差内容,在水平方向上,向左滚动到0.7的位置 183 TransitionAnimation(content: content2, destination: Position(right: 0.7, top: 0.22)) 184 ], forPage: 3) 185 186 //设置第五个页面的视差滚动效果 187 presentationController.addAnimations([ 188 //将第一个视差内容,在水平方向上,向右滚动到0.8的位置 189 TransitionAnimation(content: content1, destination: Position(left: 0.8, top: 0.2)), 190 //将第二个视差内容,在水平方向上,向左滚动到0.9的位置 191 TransitionAnimation(content: content2, destination: Position(right: 0.9, top: 0.22)) 192 ], forPage: 4) 193 } 194 195 func applicationWillResignActive(_ application: UIApplication) { 196 // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 197 // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 198 } 199 200 func applicationDidEnterBackground(_ application: UIApplication) { 201 // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 202 // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 203 } 204 205 func applicationWillEnterForeground(_ application: UIApplication) { 206 // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 207 } 208 209 func applicationDidBecomeActive(_ application: UIApplication) { 210 // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 211 } 212 213 func applicationWillTerminate(_ application: UIApplication) { 214 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 215 } 216 }