# DNSPageView **Repository Path**: moonrhino/DNSPageView ## Basic Information - **Project Name**: DNSPageView - **Description**: 一个纯Swift的轻量级、灵活且易于使用的pageView - **Primary Language**: Swift - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-08-23 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # DNSPageView [![Version](https://img.shields.io/cocoapods/v/DNSPageView.svg?style=flat)](http://cocoapods.org/pods/DNSPageView) [![License](https://img.shields.io/cocoapods/l/DNSPageView.svg?style=flat)](http://cocoapods.org/pods/DNSPageView) [![Platform](https://img.shields.io/cocoapods/p/DNSPageView.svg?style=flat)](http://cocoapods.org/pods/DNSPageView) [English Introduction](https://github.com/Danie1s/DNSPageView/blob/master/README_EN.md) DNSPageView一个纯Swift的轻量级、灵活且易于使用的`PageView`框架,`titleView`和`contentView`可以布局在任意地方,可以纯代码初始化,也可以使用`xib`或者`storyboard`初始化,并且提供了常见样式属性进行设置。 如果你使用的开发语言是Objective-C,请使用[DNSPageView-ObjC](https://github.com/Danie1s/DNSPageView-ObjC) - [Features](#features) - [Requirements](#requirements) - [Installation](#installation) - [Example](#example) - [Usage](#usage) - [直接使用DNSPageView初始化](#直接使用dnspageview初始化) - [使用xib或者storyboard初始化](#使用xib或者storyboard初始化) - [使用DNSPageViewManager初始化,再分别对titleView和contentView进行布局](#使用dnspageviewmanager初始化,再分别对titleview和contentview进行布局) - [样式](#样式) - [事件监听](#事件监听) - [常见问题](#常见问题) - [License](#license) ## Features: - [x] 使用简单 - [x] 多种初始化方式 - [x] 灵活布局 - [x] 常见的样式 - [x] 双击`titleView`的回调 - [x] `contentView`滑动监听 ## Requirements - iOS 8.0+ - Xcode 10.2+ - Swift 5.0+ ## Installation ### CocoaPods [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command: ```bash $ gem install cocoapods ``` > CocoaPods 1.1+ is required to build DNSPageView. To integrate DNSPageView into your Xcode project using CocoaPods, specify it in your `Podfile`: ```ruby source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' use_frameworks! target '' do pod 'DNSPageView' end ``` Then, run the following command: ```bash $ pod install ``` ### Manually If you prefer not to use any of the aforementioned dependency managers, you can integrate DNSPageView into your project manually. ## Example To run the example project, clone the repo, and run `DNSPageView.xcodeproj` . ## Usage ### 直接使用DNSPageView初始化 ```swift // 创建DNSPageStyle,设置样式 let style = DNSPageStyle() style.isTitleViewScrollEnabled = true style.isTitleScaleEnabled = true // 设置标题内容 let titles = ["头条", "视频", "娱乐", "要问", "体育" , "科技" , "汽车" , "时尚" , "图片" , "游戏" , "房产"] // 创建每一页对应的controller let childViewControllers: [UIViewController] = titles.map { _ -> UIViewController in let controller = UIViewController() addChild(controller) return controller } let y = UIApplication.shared.statusBarFrame.height + (navigationController?.navigationBar.frame.height ?? 0) let size = UIScreen.main.bounds.size // 创建对应的DNSPageView,并设置它的frame // titleView和contentView会连在一起 let pageView = DNSPageView(frame: CGRect(x: 0, y: y, width: size.width, height: size.height), style: style, titles: titles, childViewControllers: childViewControllers) view.addSubview(pageView) ``` ### 使用xib或者storyboard初始化 在`xib`或者`storyboard`中拖出2个`UIView`,让它们分别继承`DNSPageTitleView`和`DNSPageContentView`,拖线到代码中 ```swift @IBOutlet weak var titleView: DNSPageTitleView! @IBOutlet weak var contentView: DNSPageContentView! ``` 对DNSPageTitleView和DNSPageContentView进行设置 ```swift // 创建DNSPageStyle,设置样式 let style = DNSPageStyle() style.titleViewBackgroundColor = UIColor.red style.isShowCoverView = true // 设置标题内容 let titles = ["头条", "视频", "娱乐", "要问", "体育"] // 设置默认的起始位置 let startIndex = 2 // 对titleView进行设置 titleView.titles = titles titleView.style = style titleView.currentIndex = startIndex // 最后要调用setupUI方法 titleView.setupUI() // 创建每一页对应的controller let childViewControllers: [UIViewController] = titles.map { _ -> UIViewController in let controller = UIViewController() addChild(controller) return controller } // 对contentView进行设置 contentView.childViewControllers = childViewControllers contentView.startIndex = startIndex contentView.style = style // 最后要调用setupUI方法 contentView.setupUI() // 让titleView和contentView进行联系起来 titleView.delegate = contentView contentView.delegate = titleView ``` ### 使用DNSPageViewManager初始化,再分别对titleView和contentView进行布局 创建DNSPageViewManager ```swift private lazy var pageViewManager: DNSPageViewManager = { // 创建DNSPageStyle,设置样式 let style = DNSPageStyle() style.isShowBottomLine = true style.isTitleViewScrollEnabled = true style.titleViewBackgroundColor = UIColor.clear // 设置标题内容 let titles = ["头条", "视频", "娱乐", "要问", "体育"] // 创建每一页对应的controller let childViewControllers: [UIViewController] = titles.map { _ -> UIViewController in let controller = UIViewController() addChild(controller) return controller } return DNSPageViewManager(style: style, titles: titles, childViewControllers: childViewControllers) }() ``` 布局titleView和contentView ```swift // 单独设置titleView的frame navigationItem.titleView = pageViewManager.titleView pageViewManager.titleView.frame = CGRect(x: 0, y: 0, width: 180, height: 44) // 单独设置contentView的大小和位置,可以使用autolayout或者frame let contentView = pageViewManager.contentView view.addSubview(pageViewManager.contentView) contentView.snp.makeConstraints { (maker) in maker.edges.equalToSuperview() } ``` ### 样式 `DNSPageStyle`中提供了常见样式的属性,可以按照不同的需求进行设置,包括可以设置初始显示的页面 ### 事件回调 DNSPageView提供了常见事件监听回调,它属于`DNSPageTitleViewDelegate`的中的可选属性 ```swift /// DNSPageView的事件回调,如果有需要,请让对应的childViewController遵守这个协议 @objc public protocol DNSPageEventHandleable: class { /// 重复点击pageTitleView后调用 @objc optional func titleViewDidSelectSameTitle() /// pageContentView的上一页消失的时候,上一页对应的controller调用 @objc optional func contentViewDidDisappear() /// pageContentView滚动停止的时候,当前页对应的controller调用 @objc optional func contentViewDidEndScroll() } ``` ### 常见问题 - `style.isTitleViewScrollEnabled` 如果`titles`的数量比较少,建议设置`style.isTitleViewScrollEnabled = false`,`titleView`会固定,`style.titleMargin`不起作用,每个`title`平分整个`titleView`的宽度,下划线的宽度等于`title`的宽度。 如果标签比较多,建议设置`style.isTitleViewScrollEnabled = true`,`titleView`会滑动,下划线的宽度随着`title`文字的宽度变化而变化 - 标签下划线的宽度跟随文字的宽度 设置`style.isTitleViewScrollEnabled = true`,可以参考`Demo`中的第四种样式。 - 由于`DNSPageView`是基于`UIScrollView`实现,那么就无法避免它的一些特性: - 当控制器被`UINavigationController`管理,且`navigationBar.isTranslucent = true`的时候,当前控制器的`view`是从`y = 0`开始布局的,所以为了防止部分内容被`navigationBar`遮挡,系统默认会给`UIScrollView`添加offset。如果想取消这个特性: - iOS 11 以前,在控制器中设置`automaticallyAdjustsScrollViewInsets = false ` - iOS 11 以后引入`SafeArea`概念,设置`UIScrollView`的属性`contentInsetAdjustmentBehavior = .never` - 其实这个效果还与`UIViewController`的其他属性有关系,但因为各种组合的情景过于复杂,所以不在此一一描述 - `DNSPageContentView`用`UICollectionView`实现,所以这个特性有机会造成`UICollectionView`的经典警告: > The behavior of the UICollectionViewFlowLayout is not defined because: > > the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values 从而引发一些Bug - 以上只是可能出现的Bug之一,由于`Demo`不能覆盖所有的场景,不同的布局需求可能会引起不同的Bug,开发者需要明确了解自己的布局需求,注意细节,了解iOS布局特性,并且作出对应的调整,不能完全参照`Demo`。 ## License DNSPageView is available under the MIT license. See the LICENSE file for more info.