【Swift3】卡片功能

添加卡片信息(卡片正反照片,名称,卡号和密码)
编辑修改卡片信息
卡片列表:可删除,移动

添加卡片信息

【Swift3】卡片功能_第1张图片
【Swift3】卡片功能_第2张图片
  • 点击头部两个按钮,从相册分别添加正反照片

iOS8之后,使用UIImagePickerController调取相册的时候会崩溃,需要设置权限

【Swift3】卡片功能_第3张图片

原因是我们需要在info.plist文件中添加权限

Privacy - Photo Library Usage Description
是否允许访问相册
Privacy - Camera Usage Description
是否允许访问相机

【Swift3】卡片功能_第4张图片
  • 下面是代码部分
    isFront控制时正面照片还是反面照片
   isFront = btn.tag == 0 ? true : false
        //弹框提示如何选择图片
        let alertController = UIAlertController(title: btn.tag == 0 ? "正面图片" : "背面图片", message: nil, preferredStyle: .actionSheet)
        let cancelAction = UIAlertAction(title: "取消", style: .cancel, handler:
        {
            (UIAlertAction) -> Void in
            print("你点击了取消")
        })
        let okAction = UIAlertAction(title: "从相册中选择照片", style: .default, handler:
        {
            (UIAlertAction) -> Void in
            print("点击从相册中选择")
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self
            imagePicker.allowsEditing = true
            imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
            self.present(imagePicker, animated: true, completion: nil)
        })
        
        let okAction1 = UIAlertAction(title: "拍照", style: .default, handler:
        {
            (UIAlertAction) -> Void in
            if UIImagePickerController.isSourceTypeAvailable(.camera)
            {
                print("拍照可用")
                let imagePicker = UIImagePickerController()
                imagePicker.delegate = self
                imagePicker.allowsEditing = true
                imagePicker.sourceType = UIImagePickerControllerSourceType.camera
                self.present(imagePicker, animated: true, completion: nil)
            }
            else
            {
                print("拍照不可用")
            }
            
        })
        alertController.addAction(cancelAction)
        alertController.addAction(okAction)
        alertController.addAction(okAction1)
        self.present(alertController, animated: true, completion: nil)
  • 要想实现相册选择,必须同时实现UIImagePickerControllerDelegate,UINavigationControllerDelegate两种协议

###在代理中实现,将相册中选中的图片添加至tableView的头部按钮上

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
    {
        //在相册中选择完照片后的回调
        picker.dismiss(animated: true, completion: nil)
        let imageStr : UIImage = info[UIImagePickerControllerEditedImage] as! UIImage
        //显示
        if isFront
        {
            frontBtn.setImage(imageStr, for: UIControlState.normal)
        }
        else
        {
            backBtn.setImage(imageStr, for: UIControlState.normal)
        }  
    }
  • 点击保存时,检查是否均已输入,若没有则弹框提示,若全部输入则跳出
###判断三个textField

//1.在tableView中记录textField
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        cell.inputTextField.tag = indexPath.row
        return cell;
    }

//2.viewDidLoad中注册消息监听
       NotificationCenter.default.addObserver(self, selector: #selector(notificationResponse(notification:)), name: NSNotification.Name.UITextFieldTextDidChange, object: nil)

//3.实现实时监听,将textField的值赋值给变量
    func notificationResponse(notification: NSNotification)
    {
        let textField : UITextField = notification.object as! UITextField
        if textField.tag == 0
        {
            memberName = textField.text!
        }
        else if textField.tag == 1
        {
            memberNum = textField.text!
        }
        else
        {
            memberPassWord = textField.text!
        }
    }

//4.点击保存按钮的时候,判断变量是否有值
        if (memberName.lengthOfBytes(using: String.Encoding.utf8) == 0 ||
            memberNum.lengthOfBytes(using: String.Encoding.utf8) == 0 ||
            memberPassWord.lengthOfBytes(using: String.Encoding.utf8) == 0)
        {
            ToastView.instance.showToast(content: "输入不全", duration: 1.5)
        }
        else
        {
            print("保存")
        }
###判断正反面照片
###照片存本地文件:在documentDirectory下新建"/Documents/Member"的路径,将照片保存在文件中,,均保存在Member文件夹下,并且没张图片以当前时间戳命名
###点击保存时,判断正反面照片是否有值,将当前时间戳.jpg赋值给正反面照片的变量,判断此变量即可


###Tools工具类
getDocumentsMemberFile方法返回在documentDirectory下新建"/Documents/Member"的路径
getTimeSP返回当前时间戳

    //MAARK: - 获取Documents下的路径
    /*
     *在iOS8之前,我们获取到沙盒中的document、cache、tmp之后,下一次模拟器或真机无论怎样重启,这具体的路径是固定的了
     在iOS8之后,苹果可能考虑到安全因素,应用每一次重启,沙盒路径都动态的发生了变化,但是并不代表你原来沙盒路径中的数据发生了变化;同时,也并不代表路径会越来越多
     1>苹果会把你上一个路径中的数据转移到你新的路径中。
     2>你上一个路径也会被苹果毫无保留的删除,只保留最新的路径
     */
    public func getDocumentsMemberFile() -> String
    {
        //Documents下创建或找到文件
        let rootPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true)[0] as String
        let filePath:String = rootPath + "/Documents/Member"
        return filePath
    }

    //MARK: - 获取当前时间戳
    public func getTimeSP() -> Int
    {
        let now = Date()
        let timeInterval:TimeInterval = now.timeIntervalSince1970
        let timeStamp = Int(timeInterval)
        return timeStamp
    }

###在相册选择照片的回调代理中,将已保存在本地文件的图片的最后名字(时间戳)赋值给变量
    //MARK: - UIImagePickerControllerDelegate
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
    {
        //在相册中选择完照片后的回调
        picker.dismiss(animated: true, completion: nil)
        let imageStr : UIImage = info[UIImagePickerControllerEditedImage] as! UIImage
        //将图片存入文件
        let filePath = Tools().getDocumentsMemberFile()
        let exist = FileManager.default.fileExists(atPath: filePath)
        if !exist
        {
            try! FileManager.default.createDirectory(atPath: filePath,
                                                     withIntermediateDirectories: true, attributes: nil)
        }
        //将图片保存在文件中
        let imagePath = "\(filePath)/\(Tools().getTimeSP()).jpg"
        let imageData = UIImageJPEGRepresentation(imageStr, 1.0)
        FileManager.default.createFile(atPath: imagePath, contents: imageData, attributes: nil)
        //保存相对路径
        let imageNSURL:NSURL = NSURL.init(fileURLWithPath: imagePath)
        let imageLastPath = imageNSURL.lastPathComponent!
        //显示
        if isFront
        {
            frontBtn.setImage(imageStr, for: UIControlState.normal)
            frontPhoto = imageLastPath
        }
        else
        {
            backBtn.setImage(imageStr, for: UIControlState.normal)
            backPhoto = imageLastPath
        } 
    }

###在点击保存按钮时,判断正反照片的变量是否有值即可
    

  • 若本次卡片信息全部输入,则保存本地

参考:
http://www.jianshu.com/writer#/notebooks/11959695/notes/12740387/preview

###先将本次信息保存字典
  var dic = [String:Any]()
            dic["frontPhoto"] = frontPhoto
            dic["backPhoto"] = backPhoto
            dic["memberName"] = memberName
            dic["memberNum"] = memberNum
            dic["memberPassWord"] = memberPassWord

###声明可变数组memberList,如果本地有memberList的内容,则将它取出来赋值给一个不可变数组,再将不可变数组内容for循环添加至memberList
            let memberList : NSMutableArray = []
            if UserDefaults.standard.value(forKey: "memberList") != nil
            {
                let array = UserDefaults.standard.value(forKey: "memberList") as! NSArray
                memberList.removeAllObjects()
                let num = array.count
                for i in 0.. 0
            {
                let index = memberList.index(of: itemDic)
                memberList.remove(itemDic)
                memberList.insert(dic, at: index)
            }
            else
            {
                memberList.add(dic)
            }

###再将memberList赋值给不可变数组,方便存入UserDefaults保存
            let array = memberList
            UserDefaults.standard.set(array, forKey: "memberList")
            
            //返回上一页
            navigationController?.popViewController(animated: true)


重新编辑卡片信息

是编辑还是新增,是靠itemDic来控制的

    //下面是进来编辑的
    var itemDic = [String:String]()

如果进页面时itemDic已经被赋值,证明是编辑

###tableView的代理cellForRowAt中,如果itemDic有内容,则显示itemDic内容
        if itemDic.count > 0
        {
            if indexPath.row == 0
            {
                cell.inputTextField.text = itemDic["memberName"]
                memberName = itemDic["memberName"]!
            }
            else if indexPath.row == 1
            {
                cell.inputTextField.text = itemDic["memberNum"]
                memberNum = itemDic["memberNum"]!
            }
            else
            {
                cell.inputTextField.text = itemDic["memberPassWord"]
                memberPassWord = itemDic["memberPassWord"]!
            }
        }

###tableView的头部显示代理viewForHeaderInSection中,如果itemDic有内容,则显示itemDic内容,此时需要拼接上"rootPath + "/Documents/Member""的路径
        if itemDic.count > 0
        {
            let frontImagePath = "\(Tools().getDocumentsMemberFile())/\((itemDic["frontPhoto"])!)"
            frontBtn.setImage(UIImage(named:frontImagePath), for: UIControlState.normal)
            let backImagePath = "\(Tools().getDocumentsMemberFile())/\((itemDic["backPhoto"])!)"
            backBtn.setImage(UIImage(named:backImagePath), for: UIControlState.normal)
            frontPhoto = itemDic["frontPhoto"]!
            backPhoto = itemDic["backPhoto"]!
        }

###保存的时候,如果itemDic有内容,则
            if itemDic.count > 0
            {
                let index = memberList.index(of: itemDic)
                memberList.remove(itemDic)
                memberList.insert(dic, at: index)
            }

卡片列表

  • tableView的行数由dataMutableArray的长度决定,但如果dataMutableArray长度为0,则显示背景图
###背景图
    //MARK: - 懒加载
    private lazy var tvBackgroundView: UIView =
    {
        let view = UIView()
        view.backgroundColor = UIColor.white
        let btn = UIButton()
        btn.frame = CGRect(x: ScreenWidth / 2 - 100, y: ScreenHeight / 2 - 25, width: 200, height: 50)
        btn.setTitle("点击添加第一张银行卡", for: UIControlState.normal)
        btn.setTitleColor(UIColor.darkGray, for: UIControlState.normal)
        btn.layer.borderColor = UIColor.hexStringToColor(hexString: ColorOfWaveBlueColor).cgColor
        btn.layer.borderWidth = 2
        btn.layer.cornerRadius = 8
        btn.layer.masksToBounds = true
        btn.addTarget(self, action:#selector(addMemberCardButtonAction), for: UIControlEvents.touchUpInside)
        view.addSubview(btn)
        return view
    }()

###每次进入页面的时候均判断数组长度
    override func viewWillAppear(_ animated: Bool)
    {
        super.viewWillAppear(true)
        print("保存本地的是\(String(describing: UserDefaults.standard.value(forKey: "memberList")))")
        //初始化,没有nil判空会崩溃
        if UserDefaults.standard.value(forKey: "memberList") != nil
        {
            let array = UserDefaults.standard.value(forKey: "memberList") as! NSArray
            dataMutableArray.removeAllObjects()
            let num = array.count
            for i in 0.. UITableViewCell
    {
        
        let identifier = "identtifier";
        
        let cell = memberCardCommonCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: identifier)
        cell.accessoryType=UITableViewCellAccessoryType.disclosureIndicator
        
        let item = dataMutableArray[indexPath.row] as! NSDictionary
        //因为字典里存的是绝对路径,需要再拼上相对路径
        let imagePath = "\(Tools().getDocumentsMemberFile())/\((item["frontPhoto"] as? String)!)"
        cell.frontImageView.image = UIImage(named:imagePath)
        cell.nameLabel.text = item["memberName"] as? String
        cell.numLabel.text = item["memberNum"] as? String
        
        return cell
        
    }
    


  • 编辑
###点击编辑按钮进入编辑状态
    func editMemberCardButtonAction()
    {
        if tableView.isEditing
        {
            tableView.isEditing = false
        }
        else
        {
            tableView.isEditing = true
        }
    }

###左滑删除
    //左滑删除
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
    {
        //删除
        if editingStyle == UITableViewCellEditingStyle.delete
        {
            dataMutableArray.removeObject(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade)
            
            let array = dataMutableArray
            UserDefaults.standard.set(array, forKey: "memberList")
            
            if dataMutableArray.count == 0
            {
                tableView.backgroundView = tvBackgroundView
            }
            
        }
    }

###列表项的移动
    //编辑状态下的移动
    override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
    {
        
        if sourceIndexPath != destinationIndexPath
        {
            let moveItem = dataMutableArray[sourceIndexPath.row]
            dataMutableArray.removeObject(at: sourceIndexPath.row)
            dataMutableArray.insert(moveItem, at: destinationIndexPath.row)
  
            let array = dataMutableArray
            UserDefaults.standard.set(array, forKey: "memberList")
        }
    }

###点击cell进入编辑页
    //点击
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
        
        tableView.deselectRow(at: indexPath, animated: true)
        let vc = AddCardViewController()
        vc.itemDic = (dataMutableArray[indexPath.row] as! NSDictionary) as! [String : String]
        self.navigationController?.pushViewController(vc, animated: true)
        
    }

    
【Swift3】卡片功能_第5张图片

Demo地址
https://github.com/CarolineQian/FQAddCardDemo

你可能感兴趣的:(【Swift3】卡片功能)