Swift - 启动时的向导页(新手引导)的制作
作者:hangge | 2015-03-25 10:24
(本文代码已升级至Swift4)
一、实现原理
1,如何检测应用是第一次登陆启动
我们可以使用 UserDefaults 类来解决这个问题。其特点是不会因应用的关闭、系统的重启而丢失。所以可以用来标记是否启动过。
2,新手引导视图控制器我们使用 UIScrollView
比如我们设置了一套新手引导图共三张,都添加到 UIScrollView 里,这时 UIScrollView 的内容宽度是 3 倍于照片或者屏幕的宽度。
3,为适应不同分辨率,需要设计几套不同尺寸的图
iOS 图片资源的命名规则是:basename + screen size modifier + urischeme + orientation + scale + device + .ext
- basename:文件名
- screen size modifier:屏幕尺寸修饰符(iPhone5出现后才有,如 -568h)
- urischeme:标识URI方案的字符串(一般情况不需要关心)
- orientation:屏幕方向(横屏为-Landscape,竖屏为-Portrait)
- scale:缩放尺寸(普通屏不需要,Retina屏为@2x,iPhone6后多了个@3x)
- device:设备类型(~ipad表示供iPad使用)
- .ext:文件扩展名(可以是png或其他格式)
尽管文件很复杂,但调用却很简单,只要写上 basename.ext 即可。
二、演示样例
1,效果图
(1)程序启动后先判断是不是第一次允许,是的话先显示新手引导页面。
(2)向左滑动即可翻页。
(3)当在最后一页继续滑动时,会显示真正的主页面(程序定义的初始化视图控制器)

2,文件结构

3,样例代码
(1)入口类:AppDelegate.swiftimport UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//增加标识,用于判断是否是第一次启动应用...
if (!(UserDefaults.standard.bool(forKey: "everLaunched"))) {
UserDefaults.standard.set(true, forKey:"everLaunched")
let guideViewController = GuideViewController()
self.window!.rootViewController=guideViewController
print("guideview launched!")
}
return true
}
func applicationWillResignActive(_ application: UIApplication) {
}
func applicationDidEnterBackground(_ application: UIApplication) {
}
func applicationWillEnterForeground(_ application: UIApplication) {
}
func applicationDidBecomeActive(_ application: UIApplication) {
}
func applicationWillTerminate(_ application: UIApplication) {
}
}
(2)向导页面:GuideViewController.swift
import UIKit
class GuideViewController:UIViewController,UIScrollViewDelegate
{
//页面数量
var numOfPages = 3
override func viewDidLoad()
{
let frame = self.view.bounds
//scrollView的初始化
let scrollView = UIScrollView()
scrollView.frame = self.view.bounds
scrollView.delegate = self
//为了能让内容横向滚动,设置横向内容宽度为3个页面的宽度总和
scrollView.contentSize = CGSize(width:frame.size.width * CGFloat(numOfPages),
height:frame.size.height)
print("\(frame.size.width*CGFloat(numOfPages)),\(frame.size.height)")
scrollView.isPagingEnabled = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.showsVerticalScrollIndicator = false
scrollView.scrollsToTop = false
for i in 0..<numOfPages{
let imgfile = "jianjie\(Int(i+1)).png"
print(imgfile)
let image = UIImage(named:"\(imgfile)")
let imgView = UIImageView(image: image)
imgView.frame = CGRect(x:frame.size.width*CGFloat(i), y:CGFloat(0),
width:frame.size.width, height:frame.size.height)
scrollView.addSubview(imgView)
}
scrollView.contentOffset = CGPoint.zero
self.view.addSubview(scrollView)
}
//scrollview滚动的时候就会调用
func scrollViewDidScroll(_ scrollView: UIScrollView)
{
print("scrolled:\(scrollView.contentOffset)")
let twidth = CGFloat(numOfPages-1) * self.view.bounds.size.width
//如果在最后一个页面继续滑动的话就会跳转到主页面
if(scrollView.contentOffset.x > twidth)
{
let mainStoryboard = UIStoryboard(name:"Main", bundle:nil)
let viewController = mainStoryboard.instantiateInitialViewController()
self.present(viewController!, animated: true, completion:nil)
}
}
}
全部评论(5)
我想在你这讲的基础上,改下,就是让用户在最后一张向导图上点击按钮后进入app,不想让程序直接在浏览到最后一张向导图直接跳到APP的第一个场景去。
站长回复:可以啊,你只要在最后一页的合适位置放置个按钮,把跳转代码添加到按钮点击事件上就好了。
航哥你好,我想请问一下,我在引导页上面添加了一个button,如何进行跳转到主页面呢?(我现在引导页self.window!.rootViewController放在AppDelegate上,还有一个tarbar也放在了AppDelegate上面,要怎么去分开这两个呢)
站长回复:样例代码是如果在最后一个引导页面继续滑动的话,便会跳到主页面。跳转相关代码就是GuideViewController类中的44,45,46这三行。如果想要改成按钮点击跳转,调用的方法也是一样的。
学到了好多知识点,永远支持航哥
站长回复:谢谢你的支持,能帮助到大家我也很高兴。欢迎常来看看。
请问程序更新时,NSUserDefaults.standardUserDefaults()的数据会清空吗?如果没清空 是不是要设置一个新的标识吗?能解答下我的疑问吗?大神!
站长回复:更新程序是不会清空NSUserDefaults.standardUserDefaults()的数据。
如果每次升级程序后的第一次启动也要引导页的话,是要增加新标示。可以用 关键字+版本号 作为key 。
能给个完全demo不,,这个网站真是不错,,,,,
站长回复:这个就是完整的代码啊,一个AppDelegate.swift,一个GuideViewController.swift,放到项目中就可以了。(引导页的图片我就不放到网站上了,这个自行添加需要的图片)
谢谢你喜欢我的网站,欢迎常来看看。