iOS引导页

引导页是App中的基本功能,指导用户理解某些操作或版本变化等等。

引导页可能出现在任何时候,页面内容会根据可交互度增加而增加,而且,引导页一般为一次性展示,页面存在过多的引导页逻辑,会影响到项目功能的架构设计。

这里分享一种基于swift dynomic replacement的解决方案:

一、方法替换:

extension HomeContainerViewController {  

    @_dynamicReplacement(for: viewWillAppear(_:))  

    func guidance_viewWillAppear(_ animated: Bool) {    

        viewWillAppear(animated)    

        if AppStatus.guideForHome.isValid { return }    

        // display

    }

}

在本案例中,引导页触发点是viewWillAppear,通过替换方法截取触发时机,通过判断条件,展示引导页。

@_dynamicReplacement是swift 5.0之后提供的方法,使用条件:a、自定义类;b、带有dynamic标识符。不支持对原生类方法的替换,比如UIView、UIViewController等;

触发时机一般是某个类的某个方法,比如按钮点击、手势触发、App或实例生命周期方法等;

状态存储,建议针对引导项作单独存储,便于版本升级管理(清理),可以使用UserDefault-suitname方式,创建本地存储,状态值采用懒加载:

lazy var isValid = UserDefaults(suiteName: "guide")?.bool(forKey: "guideForHome") ?? false

二、引导页展示

present(GuideForHomeViewController(self), animated: true, completion: nil)

modalPresentationStyle = .overFullScreen

modalTransitionStyle = .crossDissolve

view.backgroundColor = .clear

采用present方式,配合转场特性,可以非常平滑的展示出引导页。设置背景色透明或半透明,可以更方便引导页与业务页面结合。

三、内容绘制

let timeFrame = timeView.superview?.convert(timeView.frame, to: view)

guideImageView.frame = timeFrame    

guideImageView.image = UIGraphicsImageRenderer(size: timeFrame.size)      

                                            .image(actions: { (renderer) in timeView.layer.render(in: renderer.cgContext) })

UIGraphicsImageRenderer是目前iOS图片处理的几个API中最快的一个。将原始view提取成image到 guideImageView中,实现高亮效果。如果需要流程事件响应,可以分多个step,分别展示不同步骤的引导。

四、事件更新

AppStatus.guideForHome.save(true)

dismiss(animated: true, completion: nil)

在引导结束后,更新状态,退出引导页。

最终效果图:


你可能感兴趣的:(iOS引导页)