2018-11-08 09:21:27 weixin_43566445 阅读数 309

效果图

实现效果:

controller弹出时:半透明背景渐变展示.地址选择器从下方弹出.

地址选择器:以省份,城市,地区三级进行选择,数据来自本地plist文件.有12个热门城市供快速选择,选择错误可以回选.

选择地区时进行将数据回调到上一控制器,点击页面空白区域退出controller.

controller消失时:背景渐变消失,地址选择器向下退出.

#实现思路:
本质上来说这是一个复杂版的日期选择器,有关弹出动画完全可以拿过来就用.

所以主要复杂的点就是这个自定制的地址选择器.

具体实现是写一个view其中包含tableView.给view三种type.来决定它当前的状态.然后根据type的改变来修改他的样式和数据展示,以及cell被点击时执行方法.

实现方式:

1.找到数据源,声明model将数据转成对象.

2.实现地址选择器的样式,数据展示.

3.实现我们需要的转场视图动画.

4.将地址选择器加入一个ViewController,并修改其转场动画代理,使其使用自定制转场动画.

5.实现地址选择器的功能,以及交互优化.


1.找到数据源,声明model将数据转成对象.

数据来自网络,一个plist文件.将其转换成model进行保存.

struct EWCountryModel {
    var countryDictionary: Dictionary<String,EWProvincesModel> = [:]
    var provincesArray: [String] = []
    init(dic:Dictionary<String,Dictionary<String,Array<String>>>){
        for (key,value) in dic{
            let model = EWProvincesModel(dic: value)
            countryDictionary[key] = model
            provincesArray.append(key)
        }
    }
}
struct EWProvincesModel{
    var provincesDictionary: Dictionary<String,EWCityModel> = [:]
    var cityArray: [String] = []
    init(dic:Dictionary<String,Array<String>>){
        for (key,value) in dic{
            let model = EWCityModel(Arr: value)
            provincesDictionary[key] = model
            cityArray.append(key)
        }
    }
}
struct EWCityModel{
    var areaArray: Array<String> = []
    init(Arr:Array<String>){
        for str in Arr{
            areaArray.append(str)
        }
    }
}

  /// 从area.plist获取全部地区数据
    func initLocationData(){
        let dic = NSDictionary(contentsOfFile: Bundle.main.path(forResource: "area", ofType: "plist")!) as! Dictionary<String,Any>
        locationModel = EWCountryModel(dic: dic as! Dictionary<String, Dictionary<String, Array<String>>>)
        dataArray = locationModel?.provincesArray
    }

2.实现地址选择器的样式,数据展示.

    func buildTitleScrollView() {
        if titleSV != nil {
            titleSV.removeFromSuperview()
        }
        buttonArr = []
        titleSV = UIScrollView(frame: CGRect(x: 0, y: 72, width: ScreenInfo.Width, height: 44))
        self.underLine = UIView(frame: CGRect(x: 0, y: 40, width: 30, height: 2))
        self.underLine.backgroundColor = UIColor.x4FB0FF
        for i in 0..<3{
            let button = UIButton(frame: CGRect(x: 24 + CGFloat(i) * (ScreenInfo.Width - 47) / 3, y: 0, width: ScreenInfo.Width / 3, height: 44))
            button.tag = Int(i)
            if i == 1 {
                button.isSelected = true
                underLine.center.x = button.center.x
            }
            button.setTitle("请选择", for: .normal)
            button.setTitleColor(UIColor.x333333, for: .normal)
            button.setTitleColor(UIColor.x4FB0FF, for: .selected)
            button.titleLabel?.font = UIFont.systemFont(ofSize: 12)
            button.titleLabel?.adjustsFontSizeToFitWidth = true
            button.addTarget(self, action: #selector(onClickTitlebutton(sender:)), for: .touchUpInside)
            buttonArr.append(button)
            titleSV.addSubview(button)
        }
        titleSV.showsVerticalScrollIndicator = false
        titleSV.addSubview(self.underLine)
        titleSV.contentSize = CGSize(width: ScreenInfo.Width, height: 44)
        titleSV.isHidden = true
        self.addSubview(titleSV)
    }
    func drawTableView(){
        self.addSubview(tableView)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.separatorStyle = .none
        tableView.tableHeaderView = tableViewHeaderView
        tableView.showsVerticalScrollIndicator = false
        tableView.register(EWAddressPickViewTableViewCell.self, forCellReuseIdentifier: EWAddressPickViewTableViewCell.identifier)
        tableView.register(EWAddressPickViewFirstTableViewCell.self, forCellReuseIdentifier: EWAddressPickViewFirstTableViewCell.identifier)
    }

3.实现我们需要的转场视图动画.

       //EWAddressPickerViewController的推出和取消动画
class EWAddressPickerPresentAnimated: NSObject,UIViewControllerAnimatedTransitioning {

    var type: EWAddressPickerPresentAnimateType = .present

    init(type: EWAddressPickerPresentAnimateType) {
        self.type = type
    }
    /// 动画时间
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.3
    }
    /// 动画效果
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        switch type {
        case .present:
            let toVC : EWAddressViewController = transitionContext.viewController(forKey: .to) as! EWAddressViewController
            let toView = toVC.view

            let containerView = transitionContext.containerView
            containerView.addSubview(toView!)

            toVC.containV.transform = CGAffineTransform(translationX: 0, y: (toVC.containV.frame.height))

            UIView.animate(withDuration: 0.25, animations: {
                /// 背景变色
                toVC.backgroundView.alpha = 1.0
                /// addresspicker向上推出
                toVC.containV.transform =  CGAffineTransform(translationX: 0, y: -10)
            }) { (finished) in
                UIView.animate(withDuration: 0.2, animations: {
                    /// transform初始化
                    toVC.containV.transform = CGAffineTransform.identity
                }, completion: { (finished) in
                    transitionContext.completeTransition(true)
                })
            }
        case .dismiss:
            let toVC : EWAddressViewController = transitionContext.viewController(forKey: .from) as! EWAddressViewController

            UIView.animate(withDuration: 0.25, animations: {
                toVC.backgroundView.alpha = 0.0
                /// addresspicker向下推回
                toVC.containV.transform =  CGAffineTransform(translationX: 0, y: (toVC.containV.frame.height))
            }) { (finished) in
                transitionContext.completeTransition(true)
            }
        }
    }
}

4.将地址选择器加入一个ViewController,并修改其转场动画代理,使其使用自定制转场动画.

 lazy var containV: EWAddressPickView = {
        let view = EWAddressPickView(frame: CGRect(x: 0, y: ScreenInfo.Height-550, width: ScreenInfo.Width, height: 550))
        view.backOnClickCancel = {
            self.onClickCancel()
        }
        /// 成功选择后将数据回调,并推出视图
        view.backLocationString = { (address,province,city,area) in
            if self.backLocationStringController != nil{
                self.backLocationStringController!(address,province,city,area)
                self.onClickCancel()
            }
        }
        return view
    }()

//MARK: - 转场动画delegate
extension EWAddressViewController:UIViewControllerTransitioningDelegate{
    /// 推入动画
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        let animated = EWAddressPickerPresentAnimated(type: .present)
        return animated
    }
    /// 推出动画
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        let animated = EWAddressPickerPresentAnimated(type: .dismiss)
        return animated
    }
}

5.实现地址选择器的功能,以及交互优化.

主要复杂的部分,只能展示其中一部分代码,具体实现还是要在demo中看.

 private var tableViewType: EWLocationPickViewTableViewType = .provinces{
        didSet{
            switch tableViewType {
            case .provinces:
                /// 选择省份时,有上面的热门城市view.没有滚动选择type的titleScrollView.没有已选择label.
                self.tableView.tableHeaderView = tableViewHeaderView
                self.tableView.frame = CGRect(x: 0, y: 42, width: ScreenInfo.Width, height: 458)
                self.titleSV.isHidden = true
                self.leftLabel.isHidden = true
                /// 将所有选中数据清空
                self.provincesModel = nil
                self.selectedProvince = ""
                self.selectedCity = ""
                self.selectedArea = ""
                self.cityModel = nil
                // 将titleSV中所有button的title重置
                // 并将第一个button设置为选中状态,已保证选择城市后button下的横线有滚动效果.
                for button in buttonArr {
                    button.setTitle("请选择", for: .normal)
                    button.isSelected = false
                    if button.tag == 0{
                        button.isSelected = true
                    }
                }
                self.underLine.center = CGPoint(x: self.buttonArr[1].center.x, y: self.underLine.center.y)
                self.dataArray = locationModel?.provincesArray
                self.tableView.reloadData()
            case .city:
                /// 选择城市时没有热门城市view,并将titleSV显示出来
                self.tableView.tableHeaderView = UIView()
                self.tableView.frame = CGRect(x: 0, y: 136, width: ScreenInfo.Width, height: 367)
                self.titleSV.isHidden = false
                self.leftLabel.isHidden = false
                /// 将省份选择保留,将城市与地区数据清空
                self.selectedCity = ""
                self.selectedArea = ""
                self.cityModel = nil
                /// 通过修改titleSV中button的选中状态来修改它的颜色
                for button in buttonArr {
                    button.isSelected = false
                    if button.tag != 0{
                        button.setTitle("请选择", for: .normal)
                    }
                    if button.tag == 1{
                        button.isSelected = true
                    }
                }

                /// 滚动titleSV中button下滚动的Line
                UIView.animate(withDuration: 0.3, animations: {() -> Void in
                    self.underLine.center = CGPoint(x: self.buttonArr[1].center.x, y: self.underLine.center.y)
                })

                self.dataArray = provincesModel?.cityArray
                self.tableView.reloadData()
            case .area:
                /// 选择地区时没有上方热门城市View,有titleSV
                self.tableView.tableHeaderView = UIView()
                self.tableView.frame = CGRect(x: 0, y: 136, width: ScreenInfo.Width, height: 367)
                self.titleSV.isHidden = false
                self.leftLabel.isHidden = false
                /// 通过修改titleSV中button的选中状态来修改它的颜色
                for button in buttonArr {
                    button.isSelected = false
                    if button.tag == 2{
                        button.isSelected = true
                    }
                }
                /// 滚动titleSV中button下滚动的Line
                UIView.animate(withDuration: 0.3, animations: {() -> Void in
                    self.underLine.center = CGPoint(x: self.buttonArr[2].center.x, y: self.underLine.center.y)
                })
                self.dataArray = cityModel?.areaArray
                self.tableView.reloadData()
            }
        }
    }

使用方法:

将EWAddressPicker文件夹拖入项目,调用时:

let addressPicker = EWAddressViewController()
/*** 可使用这种init方法自定制选中颜色,不填写selectColor默认颜色为UIColor(red: 79/255, green: 176/255, blue: 255/255, alpha: 1),蓝色
let addressPicker = EWAddressViewController(selectColor: UIColor.yellow)
*/
// 返回选择数据,地址,省,市,区
addressPicker.backLocationStringController = { (address,province,city,area) in
    self.label.text = address
}
self.present(addressPicker, animated: true, completion: nil)

demo地址:AddressPicker

OC版本:OC.地址选择器.

有问题欢迎探讨.

2017-01-28 20:37:08 ch_quan 阅读数 2988

AreaPickerView_swift

areapicker in china, easy to use. 中国的地区选择器.简单易用.

之前的地址选择器都是网上找的,但是网上的第三方,功能很多,看起来还要配置不少东西.用起来麻烦. 然后,我就自己写了一个.只有地址选择功能,连数据源都自己搞好…方便很多.后来想想不知道,有没有人也像我一样只是想到一个简单的地区选择器而已.然后,我就上传上github上面了….. 希望有人能看到吧…
直接继承自UIpickerView.

AreaPaickerView

AreaPickerView

只需要实现三个代理方法

internal func cancel(areaToolbar: AreaToolbar, textField: UITextField, locate: Location, item: UIBarButtonItem) {
//还原原来的值……
}

internal func sure(areaToolbar: AreaToolbar, textField: UITextField, locate: Location, item: UIBarButtonItem) {
//设置新值
}

internal func statusChanged(areaPickerView: AreaPickerView, pickerView: UIPickerView, textField: UITextField, locate: Location) {
//立即显示新值
}

2018-11-07 09:14:37 weixin_43566445 阅读数 234

效果图

实现效果:

controller弹出时:半透明背景渐变展示.时间选择器从下方弹出.选择器日期滚动到当前日期.

点击确认进行将数据回调到上一控制器,点击页面空白区域退出controller.

controller消失时:背景渐变消失,时间选择器向下退出.

实现方式:

1.首先写一个ViewController,将DatePicker加入.

2.实现DatePicker的展示效果与功能.

3.修改viewController的背景色,使其半透明.

4.实现我们需要的转场视图动画.

5.修改ViewController的transitioningDelegate,使其使用我们重写的转场视图动画.


1.首先写一个ViewController,将DatePicker加入.

        let cancel = UIButton(frame: CGRect(x: 0, y: 10, width: 70, height: 20))
        let sure = UIButton(frame: CGRect(x: ScreenInfo.Width - 80, y: 10, width: 70, height: 20))
        cancel.setTitle("取消", for: .normal)
        sure.setTitle("确认", for: .normal)
        cancel.setTitleColor(UIColor.colorWithRGBA(r: 255, g: 51, b: 102, a: 1), for: .normal)
        sure.setTitleColor(UIColor.colorWithRGBA(r: 255, g: 51, b: 102, a: 1), for: .normal)
        cancel.addTarget(self, action: #selector(self.onClickCancel), for: .touchUpInside)
        sure.addTarget(self, action: #selector(self.onClickSure), for: .touchUpInside)
        picker = UIPickerView(frame: CGRect(x: 0, y: 24, width: ScreenInfo.Width, height: 216))
        picker.delegate = self
        picker.dataSource = self
        picker.backgroundColor = UIColor.clear
        picker.clipsToBounds = true//如果子视图的范围超出了父视图的边界,那么超出的部分就会被裁剪掉。
        //创建日期选择器
        self.containV.addSubview(cancel)
        self.containV.addSubview(sure)
        self.containV.addSubview(picker)
        self.view.addSubview(self.containV)

2.实现DatePicker的展示效果与功能.

  //MARK: - PickerViewDelegate
extension EWDatePickerViewController:UIPickerViewDelegate,UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 3
    }
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if component == 0 {
            return 10
        }else if component == 1 {
            return 12
        }else {
            let year: Int = pickerView.selectedRow(inComponent: 0) + currentDateCom.year!
            let month: Int = pickerView.selectedRow(inComponent: 1) + 1
            let days: Int = howManyDays(inThisYear: year, withMonth: month)
            return days
        }
    }
    private func howManyDays(inThisYear year: Int, withMonth month: Int) -> Int {
        if (month == 1) || (month == 3) || (month == 5) || (month == 7) || (month == 8) || (month == 10) || (month == 12) {
            return 31
        }
        if (month == 4) || (month == 6) || (month == 9) || (month == 11) {
            return 30
        }
        if (year % 4 == 1) || (year % 4 == 2) || (year % 4 == 3) {
            return 28
        }
        if year % 400 == 0 {
            return 29
        }
        if year % 100 == 0 {
            return 28
        }
        return 29
    }
    func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
        return ScreenInfo.Width / 3
    }
    func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 40
    }
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if component == 0 {
            return "\((currentDateCom.year!) + row)\("年")"
        }else if component == 1 {
            return "\(row + 1)\("月")"
        }else {
            return "\(row + 1)\("日")"
        }
    }
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if component == 1 {
            pickerView.reloadComponent(2)
        }
    }
}

3.修改viewController的背景色,使其半透明.

        var backgroundView:UIView = {
            let view = UIView()
            view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
            return view
        }()
        self.view.backgroundColor = UIColor.clear
        self.view.insertSubview(self.backgroundView, at: 0)
        self.modalPresentationStyle = .custom//viewcontroller弹出后之前控制器页面不隐藏 .custom代表自定义

4.实现我们需要的转场视图动画.

   //EWDatePickerViewController的推出和取消动画
class EWDatePickerPresentAnimated: NSObject,UIViewControllerAnimatedTransitioning {

    var type: EWDatePickerPresentAnimateType = .present

    init(type: EWDatePickerPresentAnimateType) {
        self.type = type
    }
    /// 动画时间
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.3
    }
    /// 动画效果
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        switch type {
        case .present:
            let toVC : EWDatePickerViewController = transitionContext.viewController(forKey: .to) as! EWDatePickerViewController
            let toView = toVC.view

            let containerView = transitionContext.containerView
            containerView.addSubview(toView!)

            toVC.containV.transform = CGAffineTransform(translationX: 0, y: (toVC.containV.frame.height))

            UIView.animate(withDuration: 0.25, animations: {
                /// 背景变色
                toVC.backgroundView.alpha = 1.0
                /// datepicker向上推出
                toVC.containV.transform =  CGAffineTransform(translationX: 0, y: -10)
            }) { (finished) in
                UIView.animate(withDuration: 0.2, animations: {
                    /// transform初始化
                    toVC.containV.transform = CGAffineTransform.identity
                }, completion: { (finished) in
                    transitionContext.completeTransition(true)
                })
            }
        case .dismiss:
            let toVC : EWDatePickerViewController = transitionContext.viewController(forKey: .from) as! EWDatePickerViewController

            UIView.animate(withDuration: 0.25, animations: {
                toVC.backgroundView.alpha = 0.0
                /// datepicker向下推回
                toVC.containV.transform =  CGAffineTransform(translationX: 0, y: (toVC.containV.frame.height))
            }) { (finished) in
                transitionContext.completeTransition(true)
            }
        }
    }
}

5.修改ViewController的transitioningDelegate,使其使用我们重写的转场视图动画.

//MARK: - 转场动画delegate
extension EWDatePickerViewController:UIViewControllerTransitioningDelegate{
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        let animated = EWDatePickerPresentAnimated(type: .present)
        return animated
    }
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        let animated = EWDatePickerPresentAnimated(type: .dismiss)
        return animated
    }
}

demo地址:DatePicker.求star.

有问题欢迎探讨.

2016-07-12 15:22:50 CodingFire 阅读数 1826

先来看看效果
这里写图片描述
滚动选择器博主以前有写过Object-C版本的,地址:http://blog.csdn.net/codingfire/article/details/51684247
这里是用Swift写的,其实核心代码都差不多,也就不再做详细说明了,先看下主要代码:


import UIKit

class LHHScrollView: UIView,UIScrollViewDelegate {


    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect) {
        // Drawing code
    }
    */

    var mainScrollView = UIScrollView()
    var titleScrollView = UIScrollView()

    var underLine = UIView()
    var _titleArray = NSArray()
    var selectIndex:Int = 0
    var cacheVC = CacheVC()



    /**
     初始化方法

     - parameter frame:      定义大小范围
     - parameter titleArray: 盛放标题

     - returns: nil
     */
    init(frame:CGRect , titleArray:NSArray) {
        super.init(frame: frame)
        _titleArray = NSArray(array: titleArray)
        self.backgroundColor = UIColor.lightGrayColor()
        self.creatMainScrollView(UIColor.whiteColor())
        self.creatSelectBtn(_titleArray)
        self.creatTitleScrollView()
    }
    /**
     创建滚动界面

     - parameter bgColor: 设置滚动条背景颜色
     */
    func creatMainScrollView(bgColor:UIColor) {

        mainScrollView.bounces = false
        mainScrollView.frame = CGRectMake(0, 0, WIDTH, HEIGHT-64)
        mainScrollView.showsHorizontalScrollIndicator = false
        mainScrollView.showsVerticalScrollIndicator = false
        mainScrollView.userInteractionEnabled = true
        mainScrollView.delegate = self
        mainScrollView.contentSize = CGSizeMake(CGFloat(_titleArray.count) * WIDTH, HEIGHT - 64)
        mainScrollView.scrollEnabled = true
        mainScrollView.pagingEnabled = true
        mainScrollView.backgroundColor = bgColor
        self.addSubview(mainScrollView)

    }
    /**
     创建滚动条
     */
    func creatTitleScrollView() {
        titleScrollView.bounces = false
        titleScrollView.frame = CGRectMake(0, 0, WIDTH, 42)
        titleScrollView.showsHorizontalScrollIndicator = false
        titleScrollView.showsVerticalScrollIndicator = false
        titleScrollView.userInteractionEnabled = true
        titleScrollView.scrollEnabled = true
        titleScrollView.backgroundColor = UIColor.lightGrayColor()
        self.addSubview(titleScrollView)

    }
    /**
     创建按钮和滑块

     - parameter titleArray: 标题
     */
    func creatSelectBtn(titleArray:NSArray) {
        var width:CGFloat
        width = 5
        for index in 0..<titleArray.count {

            let btn = UIButton(type: .Custom)
            btn.frame = CGRectMake(width, 5, self.legthOfTitle(titleArray[index] as! String)+30, 30)
            btn.setTitle(titleArray[index] as? String, forState: .Normal)
            btn.backgroundColor = UIColor.orangeColor()
            btn.layer.cornerRadius = 5
            btn.titleLabel?.font = UIFont.systemFontOfSize(13)
            btn.setTitleColor(UIColor.blackColor(), forState: .Normal)
            btn.tag = index + 50
            btn.addTarget(self, action: #selector(self.btnAction(_:)), forControlEvents: .TouchUpInside)
            titleScrollView.addSubview(btn)

            let lineView = UIView(frame: CGRectMake(width, 39, self.legthOfTitle(titleArray[index] as! String)+30, 3))
            lineView.tag = 100 + index
            lineView.backgroundColor = UIColor.redColor()
            lineView.hidden = true
            titleScrollView.addSubview(lineView)

            if index == 50 {
                btn.setTitleColor(UIColor.redColor(), forState: .Selected)
            }
            if lineView.tag == 100 {
                lineView.hidden = false
            }

            width = width + self.legthOfTitle(titleArray[index] as! String) + 30 + 10
        }
        selectIndex = 0
        titleScrollView.contentSize = CGSizeMake(width, 40)
        let viewVC = ViewController1()
        viewVC.contentID =  "\(selectIndex)"
        viewVC.view.frame = CGRectMake(0, 42, WIDTH, HEIGHT - 64 - 42)
        mainScrollView.addSubview(viewVC.view)
        cacheVC.addCurrentVC(selectIndex)

    }
    /**
     计算标题长度

     - parameter title: 标题

     - returns: 标题长度
     */
    func legthOfTitle(title:String) -> CGFloat {
        let attribute = [NSFontAttributeName: UIFont.systemFontOfSize(13)]
//        let text: NSString = NSString(CString: title.cStringUsingEncoding(NSUTF8StringEncoding)!,encoding: NSUTF8StringEncoding)!
        let option = NSStringDrawingOptions.UsesFontLeading
        let size = title.boundingRectWithSize(CGSizeMake(1000, 30), options:option, attributes: attribute, context: nil)
        return size.width
    }
    /**
     点击按钮响应事件

     - parameter btn: tag从50开始
     */
    func btnAction(btn:UIButton) {
        selectIndex = btn.tag - 50
        print(btn.tag)
        /// 按钮和滑块变为未选状态
        for var view in titleScrollView.subviews {
            if view.isKindOfClass(UIButton) {
                let button = view as! UIButton
                button.setTitleColor(UIColor.blackColor(), forState: .Normal)
            }
            else
            {
                let lineView = view 
                lineView.hidden = true
            }

        }
        btn.setTitleColor(UIColor.redColor(), forState: .Normal)
        let lineView = titleScrollView.viewWithTag(selectIndex + 100)
        lineView?.hidden = false
        /**
         *  对当前控制器做处理
         *
         *  @param selectIndex 当前控制器标号
         *
         *  @return nil
         */
        if !cacheVC.vcArray.containsObject(selectIndex) {
            let viewVC = ViewController1()
            viewVC.contentID =  "\(selectIndex)"
            viewVC.view.frame = CGRectMake(CGFloat(selectIndex) * WIDTH, 42, WIDTH, HEIGHT - 64 - 42)
            mainScrollView.addSubview(viewVC.view)
            cacheVC.addCurrentVC(selectIndex)
        }
        /**
         *  设置偏移量
         *
         *  @param self.selectIndex 当前位置
         *
         *  @return nil
         */
        self.mainScrollView.contentOffset = CGPointMake(CGFloat(self.selectIndex) * WIDTH, 0)
        /// 获取当前按钮左右按钮
        let btnRight = titleScrollView.viewWithTag(btn.tag + 1)
        let btnLeft = titleScrollView.viewWithTag(btn.tag - 1)
        /**
         *  通过位置判断偏移量
         */
        if (btn.frame.origin.x + btn.frame.size.width) > WIDTH - 10{
            if btn.tag - 50 != _titleArray.count - 1 {
                UIView.animateWithDuration(0.3, animations: {
                    self.titleScrollView.contentOffset = CGPointMake(btnRight!.frame.origin.x + btnRight!.frame.size.width - WIDTH + 10, 0);
                })
            }


        }
        else
        {
            if selectIndex == 0 {
                UIView.animateWithDuration(0.3, animations: {
                    self.titleScrollView.contentOffset = CGPointMake(0, 0)
                })
            }
            else
            {
                UIView.animateWithDuration(0.3, animations: {
                    self.titleScrollView.contentOffset = CGPointMake(btnLeft!.frame.origin.x, 0)
                })
            }
        }

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    /**
     scrollView代理方法

     - parameter scrollView: 滑动界面相应事件
     */
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        selectIndex = Int(mainScrollView.contentOffset.x / WIDTH)
        /// 按钮和滑块变为未选状态
        for var view in titleScrollView.subviews {
            if view.isKindOfClass(UIButton) {
                let button = view as! UIButton
                button.setTitleColor(UIColor.blackColor(), forState: .Normal)
            }
            else
            {
                let lineView = view
                lineView.hidden = true
            }

        }
        let btn = titleScrollView.viewWithTag(selectIndex + 50) as! UIButton

        btn.setTitleColor(UIColor.redColor(), forState: .Normal)
        let lineView = titleScrollView.viewWithTag(selectIndex + 100)
        lineView?.hidden = false
        /**
         *  对当前控制器做处理
         *
         *  @param selectIndex 当前控制器标号
         *
         *  @return nil
         */
        if !cacheVC.vcArray.containsObject(selectIndex) {
            let viewVC = ViewController1()
            viewVC.contentID =  "\(selectIndex)"
            viewVC.view.frame = CGRectMake(CGFloat(selectIndex) * WIDTH, 42, WIDTH, HEIGHT - 64 - 42)
            mainScrollView.addSubview(viewVC.view)
            cacheVC.addCurrentVC(selectIndex)
        }
        /**
         *  设置偏移量
         *
         *  @param self.selectIndex 当前位置
         *
         *  @return nil
         */

        self.mainScrollView.contentOffset = CGPointMake(CGFloat(selectIndex) * WIDTH, 0)
        /// 获取当前按钮左右按钮
        let btnRight = titleScrollView.viewWithTag(selectIndex + 50 + 1)
        let btnLeft = titleScrollView.viewWithTag(selectIndex + 50 - 1)

        /**
         *  通过位置判断偏移量
         */
        if (btn.frame.origin.x + btn.frame.size.width) > WIDTH - 10{
            if btn.tag - 50  != _titleArray.count - 1 {
                UIView.animateWithDuration(0.3, animations: {
                    self.titleScrollView.contentOffset = CGPointMake(btnRight!.frame.origin.x + btnRight!.frame.size.width - WIDTH + 10, 0);
                })
            }


        }
        else
        {
            if selectIndex == 0 {
                UIView.animateWithDuration(0.3, animations: {
                    self.titleScrollView.contentOffset = CGPointMake(0, 0)
                })
            }
            else
            {
                UIView.animateWithDuration(0.3, animations: {
                    self.titleScrollView.contentOffset = CGPointMake(btnLeft!.frame.origin.x, 0)
                })
            }
        }

    }
}

代码中都给出了注释,还有不懂的请留言,下载地址:https://github.com/codeliu6572/Swift_Scroll_Select

2017-09-30 16:23:35 EyreFree 阅读数 962

EFColorPicker 是一个纯 Swift 的轻量级 iOS 颜色选择器,受 MSColorPicker 启发。

English Introduction

链接

https://github.com/EyreFree/EFColorPicker

概述

iOS 颜色选择器组件,它能够让用户选择自定义颜色,关键特性如下:

  • 支持 iPhone 和 iPad
  • 自适应的用户界面
  • 支持 RGB 和 HSB 两种颜色模式
  • 比较完善的文档和注释
  • 支持 iOS 8.0 (iPhone & iPad) 及更高版本

预览

iPhone iPad

示例

  1. 利用 git clone 命令下载本仓库;
  2. 利用 cd 命令切换到 Example 目录下,执行 pod install 命令;
  3. 随后打开 EFColorPicker.xcworkspace 编译即可。

或执行以下命令:

git clone git@github.com:EyreFree/EFColorPicker.git; cd EFColorPicker/Example; pod install; open EFColorPicker.xcworkspace

环境

  • iOS 8.0+
  • Xcode 9.0+
  • Swift 4.0+

安装

EFColorPicker 可以通过 CocoaPods 进行获取。只需要在你的 Podfile 中添加如下代码就能实现引入:

pod "EFColorPicker"

备注

EFColorPicker 的第一个版本从 MSColorPicker 转换而来,在此对 MSColorPicker 的作者 sgl0v 表示感谢!

作者

EyreFree, eyrefree@eyrefree.org

协议

EFQRCode 基于 MIT 协议进行分发和使用,更多信息参见协议文件。

OC.地址选择器

阅读数 115

没有更多推荐了,返回首页