解决IOS8.1中UIActionSheet与UIPickerView不兼容

本文介绍了一种在iOS应用中使用Swift语言模拟废弃的UIActionSheet的方法,通过自定义UIView并整合UIPickerView来实现类似的功能,适用于创建备忘录等场景。
/*
 * 解决IOS8.1中UIActionSheet与UIPickerView不兼容
 * 我的思路是用UIView模拟UIActionSheet的效果,向UIView中加入UIPickerView
 *
 * 背景:做一个备忘录的时候,设置提醒时间时,想要做成万年历的效果(底部弹出一个时间选择项,还可以选择农历日历),本想在
 *      UIActionSheet中,加入UIPickerView实现的。但UIActionSheet在IOS8.1后已经废弃了,且实现起来效果很糟糕。
 * 声明:刚好在网站看到这个问题的解决方案,但是用objective-c实现,我用swift实现了一遍,担心新人和我一样,不太容易理解使用
 *      增加了注释。原文出处:黑月神话, vjson.com
 */


import UIKit

//使用代理模式,以便于自定义点击“确认”或“取消”按钮后执行的操作
protocol SimulateActionSheetDelegate:UIPickerViewDelegate {

    func actionCancle()  //取消按钮
    func actionDone()   //确认按钮
}

class SimulateActionSheet: UIView,SimulateActionSheetDelegate {


    var headToolBar:UIView!   //头部工具条,用于放置操作按钮(取消按钮、确认按钮)
    var pickView:UIPickerView!    //pickView  用户显示内容
    var delegate:SimulateActionSheetDelegate!
    var headToolBarColor:UIColor!   //头部工具条背景颜色
    var textColorNormal:UIColor!    //按钮文本颜色
    var textClolorPressed:UIColor!  //按钮按下文本颜色
    var pickerBgColor:UIColor!      //pickView的背景颜色



    //初始化,设置样式
    init(frame: CGRect,headToolBarColor:UIColor,textColorNormal:UIColor,textClolorPressed:UIColor,pickerBgColor:UIColor) {

        super.init(frame: frame)

        self.headToolBarColor = headToolBarColor
        self.textColorNormal = textColorNormal
        self.textClolorPressed = textClolorPressed
        self.pickerBgColor = pickerBgColor

    }


    //required修饰符的使用规则

    /*required修饰符只能用于修饰类初始化方法。
     *当子类含有异于父类的初始化方法时(初始化方法参数类型和数量异于父类),子类必须要实现父类的required初始化方法,
      并且也要使用required修饰符而不是override。
     *当子类没有初始化方法时,可以不用实现父类的required初始化方法。
     */
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    //类方法,获得自定义样式的SimulateActionSheet类的实例
    class func getSimulateActionSheet(headToolBarColor:UIColor,textColorNormal:UIColor,textClolorPressed:UIColor,pickerBgColor:UIColor)->SimulateActionSheet {



        let sheet = SimulateActionSheet.init(frame: CGRectMake(0,0,UIScreen.mainScreen().bounds.size.width,UIScreen.mainScreen().bounds.size.height), headToolBarColor: headToolBarColor, textColorNormal: textColorNormal, textClolorPressed: textClolorPressed, pickerBgColor: pickerBgColor)

        sheet.backgroundColor = UIColor.clearColor()

        sheet.headToolBar = sheet.actionHeadToolBar() //初始化头部工具条
        sheet.pickView = sheet.actionPickerView()     //初始化UIPickView
        sheet.addSubview(sheet.headToolBar)          //把工具条,添加到自定义的SimulateActionSheet中
        sheet.addSubview(sheet.pickView)             //把UIPickView,添加到自定义的SimulateActionSheet中
        return sheet

    }


    //初始化头部工具条
    func actionHeadToolBar() ->UIView {

        let headTools = UIView(frame: CGRectMake(0, 0, 320, 44))
        headTools.backgroundColor = self.headToolBarColor

        //设置取消按样式
        let cancelButton = UIButton(frame: CGRectMake(0,0,0,0))
        cancelButton.setTitle("取消", forState: .Normal)
        cancelButton.setTitleColor(self.textClolorPressed, forState: .Highlighted)
        cancelButton.setTitleColor(self.textColorNormal, forState: .Normal)
        cancelButton.addTarget(self, action: "actionCancle", forControlEvents: .TouchUpInside)
        cancelButton.sizeToFit()

        headTools.addSubview(cancelButton)

        //将自适应向布局约束的转化关掉(根据情况有时需要有时不需要)
        cancelButton.translatesAutoresizingMaskIntoConstraints = false



        let cancleConstraintLeft = NSLayoutConstraint(item: cancelButton, attribute: NSLayoutAttribute.Leading, relatedBy: .Equal, toItem: headTools, attribute: NSLayoutAttribute.Leading, multiplier: 1.0, constant: 10.0)

        let cancleConstrainY = NSLayoutConstraint(item: cancelButton, attribute: NSLayoutAttribute.CenterY, relatedBy: .Equal, toItem: headTools, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0)

        headTools.addConstraint(cancleConstraintLeft)
        headTools.addConstraint(cancleConstrainY)


        //确认按钮
        let okButton = UIButton(frame: CGRectMake(0,0,0,0))
        okButton.setTitle("确认", forState: .Normal)
        okButton.setTitleColor(self.textClolorPressed, forState: .Highlighted)
        okButton.setTitleColor(self.textColorNormal, forState: .Normal)
        okButton.addTarget(self, action: "actionDone", forControlEvents: .TouchUpInside)
        okButton.sizeToFit()

        headTools.addSubview(okButton)

        okButton.translatesAutoresizingMaskIntoConstraints = false



        let okConstraintRight = NSLayoutConstraint(item: okButton, attribute: NSLayoutAttribute.Trailing, relatedBy: .Equal, toItem: headTools, attribute: NSLayoutAttribute.Trailing, multiplier: 1.0, constant: -10.0)

        let okConstrainY = NSLayoutConstraint(item: okButton, attribute: NSLayoutAttribute.CenterY, relatedBy: .Equal, toItem: headTools, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0)

        headTools.addConstraint(okConstraintRight)
        headTools.addConstraint(okConstrainY)


        return headTools

    }


    //初始化PickerView
    func actionPickerView() ->UIPickerView {

        let picker = UIPickerView(frame:CGRectMake(0, 44, 0, 0))
        picker.showsSelectionIndicator = true
        picker.backgroundColor = self.pickerBgColor
        return picker

    }



    //设置整个项目显示的位置
    func setInitPostion(Control:UIViewController) {

        UIApplication.sharedApplication().keyWindow?.addSubview(self)
        self.superview?.bringSubviewToFront(self)
        self.pickView.frame = CGRectMake(self.pickView.frame.origin.x, UIScreen.mainScreen().bounds.size.height, self.pickView.frame.size.width, self.pickView.frame.size.height)
        self.headToolBar.frame = CGRectMake(self.headToolBar.frame.origin.x, UIScreen.mainScreen().bounds.size.height, self.headToolBar.frame.size.width, self.headToolBar.frame.size.height)

    }


    /*UIPickerViewDataSource在项目实际使用中,自己根据项目情况自己实现*/




    //设置当前列默认显示第几行数据
    func selectRow(row: Int, Component: Int, animate: Bool) {

        self.pickView.selectRow(row, inComponent: Component, animated: animate)

    }


    func selectedRowInComponent(component: Int) ->Int {

        return self.pickView.selectedRowInComponent(component)
    }





    func actionCancle(){

        self.delegate.actionCancle()

    }

    func actionDone(){

        self.delegate.actionDone()

    }

    func setDelegate(delegate:SimulateActionSheetDelegate) {

        self.delegate = delegate
        self.pickView.delegate = delegate
    }


    //项目出现
    func show(controller:UIViewController) {

        self.setInitPostion(controller)
        let toolBarYposition = UIScreen.mainScreen().bounds.size.height - (self.pickView.frame.size.height
            + self.headToolBar.frame.size.height)

        UIView.animateWithDuration(0.25, animations: { () -> Void in

            self.backgroundColor = UIColor.darkGrayColor().colorWithAlphaComponent(0.5)
            controller.view.tintAdjustmentMode = .Dimmed
            controller.navigationController?.navigationBar.tintAdjustmentMode = .Dimmed
            self.headToolBar.frame = CGRectMake(self.headToolBar.frame.origin.x, toolBarYposition, self.headToolBar.frame.size.width, self.headToolBar.frame.size.height)
            self.pickView.frame = CGRectMake(self.pickView.frame.origin.x, toolBarYposition + self.headToolBar.frame.size.height , self.pickView.frame.size.width, self.pickView.frame.size.height)

            }, completion: nil)


    }

    //项目消失
    func dismiss(controller:UIViewController) {

        UIView.animateWithDuration(0.25, animations: { () -> Void in

            self.backgroundColor = UIColor.clearColor()
            controller.view.tintAdjustmentMode = .Normal
            controller.navigationController?.navigationBar.tintAdjustmentMode = .Normal



            }) { (finished:Bool) -> Void in
                self.removeFromSuperview()
        }

    }


}

测试:

//
//  ViewController.swift
//  SimulateActionSheet
//
//  Created by mac on 16/5/5.
//  Copyright © 2016年 fish. All rights reserved.
//

import UIKit

class ViewController: UIViewController,SimulateActionSheetDelegate,UIPickerViewDataSource {

    var sheet:SimulateActionSheet!
    var provinces = [String]()
    var citys = Dictionary<String,[String]>()
    var iComponent = 1   //默认只有一列

    var iprovince = 0  //当前选中的省

    override func viewDidLoad() {
        super.viewDidLoad()

        provinces.append("广东省")
        provinces.append("江西省")
        provinces.append("湖南省")
        provinces.append("浙江省")
        provinces.append("福建省")


        citys = ["广东省":["深圳市","广州市","东莞市","清远市"],"湖南省":["长沙市","邵阳市","娄底市","武冈市"],"江西省":["南昌市","九江市","赣州市","上饶市"],"浙江省":["杭州市","宁波市"],"福建省":["福州市","宁波市","泉州市"]]



        // Do any additional setup after loading the view, typically from a nib.
    }


    @IBAction func clickTestButton(sender: UIButton) {


        //测试一列按钮的tag设置为100  测试二列按钮的tag设置为200
        if sender.tag == 100 {

            iComponent = 1
        }
        else {
            iComponent = 2
        }

        self.sheet = SimulateActionSheet.getSimulateActionSheet(UIColor(red: 240/255, green: 240/255, blue: 240/255, alpha: 0.9), textColorNormal: UIColor(red: 0, green: 146/255, blue: 255/255, alpha: 1), textClolorPressed: UIColor(red: 209/255, green: 213/255, blue: 219/255, alpha: 0.9), pickerBgColor: UIColor(red: 209/255, green: 213/255, blue: 219/255, alpha: 0.9))





        self.sheet.setDelegate(self)


        self.sheet.selectRow(provinces.count/2, Component: 0, animate: true)
        if iComponent == 2 {

            iprovince = provinces.count/2
            self.sheet.pickView.reloadComponent(1)
        }


        self.sheet.show(self)

    }



    func actionCancle() {

        sheet.dismiss(self)
    }

    func actionDone() {

        sheet.dismiss(self)

    }

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {

        return iComponent
    }


    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {


        if iComponent == 1 {

            return self.provinces.count
        }
        else {

            if component == 0 {

                return self.provinces.count

            }
            else {

                return (self.citys["\(provinces[iprovince])"]?.count)!
            }
        }

    }

    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

        if iComponent == 1 {

            return self.provinces[row]
        }
        else {

            if component == 0 {

                return self.provinces[row]

            }
            else {

                return (self.citys["\(provinces[iprovince])"]?[row])!
            }
        }
    }


    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {



        if component == 0 {

            iprovince = row

            self.sheet.pickView.reloadComponent(1)

        }


    }



//    @IBOutlet weak var clickTestButton: UIButton!

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


}

效果:
这里写图片描述

这里写图片描述

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值