Swift3超级炫酷的可以旋转的引导页

大多数app的引导页要求能左右滑动,能起到引导页的作用就可以了,显得十分单调无趣,今天在简书上发现一个很炫酷的引导页,滑动时可以旋转,当时就被这种效果吸引了,效果如下:

是不是感觉逼格满满,我看了一下代码是用Objective-C写的,因此我想用Swift3也实现一个这种引导页,由于没有好看的图片素材,实现效果稍有差别,如果各位有好的素材替换一下就好,最终的效果如下:

GitHub地址:https://github.com/developerZGJ/ZGGuideViewController
原文链接:http://www.jianshu.com/p/1b470fd15470

关键代码

import UIKit

class GuideViewController: UIViewController {
    
    //外部接口
    var imageNamesArray = [String]()
    var textImageArray = [String]()
    //k开头的一般是全局宏(当然Swift是没有宏一说的,懂就行),之前定义的是宏,但是考虑到便于搬砖不起冲突,拖进来当普通变量了
    fileprivate let kBaseTag = 10000
    fileprivate let kRotateRate: CGFloat = 1
    fileprivate let kScreenWidth = UIScreen.main.bounds.width
    fileprivate let kScreenHeight = UIScreen.main.bounds.height

    override func viewDidLoad() {
        super.viewDidLoad()

        buildInterface()
    }
    
    private func buildInterface(){
        view.backgroundColor = UIColor(red: 140.0/255, green: 1, blue: 1, alpha: 1)
        
        let mainScrollView = UIScrollView(frame: UIScreen.main.bounds)
        mainScrollView.isPagingEnabled = true
        mainScrollView.contentSize = CGSize(width: kScreenWidth * CGFloat(imageNamesArray.count), height: kScreenHeight)
        mainScrollView.showsHorizontalScrollIndicator = false
        mainScrollView.delegate = self
        view.addSubview(mainScrollView)
        
        //有需要可以添加修饰图片,带透明度会好看一点
//        let t_imageView = UIImageView(frame: CGRect(x: 0, y: 330, width: kScreenWidth, height: 170.fitScreenWidth))
//        t_imageView.image = UIImage(named: "yun")
//        view.addSubview(t_imageView)
        
        //添加引导图
        for i in 0..<imageNamesArray.count{
            let rotateView = UIView(frame: CGRect(x: kScreenWidth *  CGFloat(i), y: 0, width: kScreenWidth, height: kScreenHeight * 2))
            rotateView.tag = kBaseTag + i
            mainScrollView.addSubview(rotateView)
            rotateView.alpha = i == 0 ? 1 : 0
            
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: kScreenWidth, height: kScreenHeight))
            imageView.image = UIImage(named: imageNamesArray[i])
            rotateView.addSubview(imageView)
            
            let textImageView = UIImageView(frame: CGRect(x: kScreenWidth * CGFloat(i), y: 50.fitScreenHeight(), width: kScreenWidth, height: 150.fitScreenHeight()))
            textImageView.tag = kBaseTag * 2 + i
            textImageView.image = UIImage(named: textImageArray[i])
            mainScrollView.addSubview(textImageView)
            
            //最后一页添加按钮
            if i == imageNamesArray.count - 1 {
                let button = UIButton(frame: CGRect(x: 20.fitScreenWidth(), y: kScreenHeight - 80.fitScreenHeight(), width: kScreenWidth - 20.fitScreenWidth() * 2, height: 50.fitScreenHeight()))
                button.addTarget(self, action: #selector(self.buttonClicked(sender:)), for: .touchUpInside)
                button.setImage(UIImage(named: "icon_next"), for: .normal)
                rotateView.addSubview(button)
            }
        }
        
    }
    
    //Mark: - 按钮点击
    func buttonClicked(sender:UIButton){
        print("按钮点击")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

}

//Mark: - UIScrollViewDelegate
extension GuideViewController: UIScrollViewDelegate{
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        
        let xOffset = scrollView.contentOffset.x
        for i in 0..<imageNamesArray.count{
            let imageView = scrollView .viewWithTag(kBaseTag + i)
            //根据偏移量旋转
            let rotateAngle = -1 * 1 / kScreenWidth * xOffset * CGFloat.pi/2 * kRotateRate
            imageView?.layer.transform = CATransform3DMakeRotation(rotateAngle + CGFloat.pi/2 * CGFloat(i), 0, 0, 1)
            //根据偏移量位移(保证中心点始终都在屏幕下方中间)
            imageView?.center = CGPoint(x: 0.5 * kScreenWidth + xOffset, y: kScreenHeight)
        }
        
        //原来的代码固定了4张图进行计算,这里我也还没想到怎么改灵活,暂时也固定吧
        let view1 = scrollView.viewWithTag(kBaseTag)
        let view2 = scrollView.viewWithTag(kBaseTag + 1)
        let view3 = scrollView.viewWithTag(kBaseTag + 2)
        let view4 = scrollView.viewWithTag(kBaseTag + 3)
        let textIV1 = scrollView.viewWithTag(kBaseTag * 2)
        let textIV2 = scrollView.viewWithTag(kBaseTag * 2 + 1)
        let textIV3 = scrollView.viewWithTag(kBaseTag * 2 + 2)
        let textIV4 = scrollView.viewWithTag(kBaseTag * 2 + 3)
        
        //调节透明度
        let xOffsetMore = xOffset * 1.5 > kScreenWidth ? kScreenWidth : xOffset * 1.5
        if xOffset < kScreenWidth {
            view1?.alpha = (kScreenWidth - xOffsetMore) / kScreenWidth
            textIV1?.alpha = (kScreenWidth - xOffsetMore) / kScreenWidth
        }
        if xOffset <= kScreenWidth  {
            view2?.alpha = xOffsetMore / kScreenWidth
            textIV2?.alpha = xOffset / kScreenWidth
        }
        if xOffset > kScreenWidth && xOffset <= kScreenWidth * 2 {
            view2?.alpha = (kScreenWidth * 2 - xOffset) / kScreenWidth
            view3?.alpha = (xOffset - kScreenWidth) / kScreenWidth
            textIV2?.alpha = (kScreenWidth * 2 - xOffset) / kScreenWidth
            textIV3?.alpha = (xOffset - kScreenWidth) / kScreenWidth
        }
        if xOffset > kScreenWidth * 2 {
            view3?.alpha = (kScreenWidth * 3 - xOffset) / kScreenWidth
            view4?.alpha = (xOffset - kScreenWidth * 2) / kScreenWidth
            textIV3?.alpha = (kScreenWidth * 3 - xOffset) / kScreenWidth
            textIV4?.alpha = (xOffset - kScreenWidth * 2) / kScreenWidth
        }
        
        //调节背景色
        //调节背景色
        if (xOffset < kScreenWidth && xOffset > 0) {
            view.backgroundColor = UIColor(red: (140 - 40.0 / kScreenWidth * xOffset) / 255.0, green: (255 - 25.0 / kScreenWidth * xOffset) / 255.0, blue: (255 - 100.0 / kScreenWidth * xOffset) / 255.0, alpha: 1)
            
        }else if (xOffset >= kScreenWidth && xOffset < kScreenWidth * 2){
            view.backgroundColor = UIColor(red: (100 + 30.0 / kScreenWidth * (xOffset - kScreenWidth))/255.0, green: (230-40.0 / kScreenWidth * (xOffset - kScreenWidth)) / 255.0, blue: (155-5.0 / 320 * (xOffset - kScreenWidth)) / 255.0, alpha: 1)
            
        }else if (xOffset >= kScreenWidth * 2 && xOffset < kScreenWidth * 3){
            view.backgroundColor = UIColor(red: (130 - 50.0 / kScreenWidth * (xOffset - kScreenWidth * 2)) / 255.0, green: (190 - 40.0 / kScreenWidth * (xOffset - kScreenWidth * 2))/255.0, blue: (150 + 50.0 / kScreenWidth * (xOffset - kScreenWidth * 2)) / 255.0, alpha: 1)
            
        }else if (xOffset >= kScreenWidth * 3 && xOffset < kScreenWidth * 4){
            view.backgroundColor = UIColor(red: (80 - 10.0 / kScreenWidth * (xOffset - kScreenWidth * 3)) / 255.0, green: (150 - 25.0 / kScreenWidth*(xOffset - kScreenWidth * 3)) / 255.0, blue: (200 - 90.0 / kScreenWidth * (xOffset - kScreenWidth * 3)) / 255.0, alpha: 1)
        }
        
    }
    
}

//Mark: - 屏幕适配
extension Int {
    
    func fitScreenHeight() -> CGFloat {
        let screenHeight = UIScreen.main.bounds.height - 64;
        let height : CGFloat = 667.0 - 64;
        let scale = screenHeight / height ;
        return scale * CGFloat(self);
    }
    
    func fitScreenWidth() -> CGFloat {
        let screenWidth = UIScreen.main.bounds.width;
        let width : CGFloat = 375;
        let scale = screenWidth / width ;
        return scale * CGFloat(self);
    }
    
}

extension CGFloat {
    
    func fitScreenHeight() -> CGFloat {
        let screenHeight = UIScreen.main.bounds.height - 64;
        let height : CGFloat = 667.0 - 64;
        let scale = screenHeight / height ;
        return scale * CGFloat(self);
    }
    
    func fitScreenWidth() -> CGFloat {
        let screenWidth = UIScreen.main.bounds.height;
        let width : CGFloat = 375;
        let scale = screenWidth / width ;
        return scale * CGFloat(self);
    }
    
}

使用

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        window = UIWindow(frame: UIScreen.main.bounds)
        let rootVC = GuideViewController()
        rootVC.imageNamesArray = ["guide_40_1","guide_40_2","guide_40_3","guide_40_4"]
        rootVC.textImageArray = ["1","2","3","4"]
        window?.rootViewController = rootVC
        
        return true
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容