Swift学习记录 Project 5

从100 Days of Swift中学习,实践

最近中途因为一些事情停更了一会,并且自后的一些项目都会比较大, 不能再通过Day record来记录, 修改为project来记录。

PROJECT 14 - JUMPBAR

I learned how to:

  • Sort an Array in alphabetical order
  • Create an Indexed Table View

具体思路:
1.将数据源根据首字母排序,获取首字母Array,然后通过将对应字母的数据组成一个新的数组,按顺序加入新的数组中
2.UI上创建tableview 和对应索引栏,比较简单


PROJECT 20 - SAVE DATE, LOCATION & PHOTO

2015-09-15-saving-date-location-photo-text.gif

I learned how to:

  • Create an Accessory Input View
  • Use Core Location to retrieve Location
  • Work with NSDate
  • 使用imagepickerViewController
  • 自适应cell高度
  1. 辅助栏跟随键盘上升和下降显示和隐藏的,有拍照和选择照片,定位等功能。
    View需要监听键盘升起和降下两个通知, 并且判断是否有输入联想框(会影响View位置)
    然后提供出来两个按钮的点击响应和一个LocationLabel,一个imageView
KeyBoardStatusView: UIView

首先监听键盘

//监听键盘上升
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(_:)), name:NSNotification.Name.UIKeyboardWillShow, object: nil)
//监听键盘下降
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillHide(_:)), name:NSNotification.Name.UIKeyboardWillHide, object: nil)

根据监听获取键盘移动距离,动画时间

@objc fileprivate func keyBoardWillShow(_ notification:NSNotification){
        
        let kbInfo = notification.userInfo
        
        //获取键盘的size
        
        let kbRect = (kbInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        
        //键盘的y偏移量
        
        let changeY = kbRect.origin.y - UIScreen.main.bounds.height
        
        //键盘弹出的时间
        
        let duration = kbInfo?[UIKeyboardAnimationDurationUserInfoKey] as!Double
        
        UIView.animate(withDuration: duration) {
            self.isHidden = false
            self.transform = CGAffineTransform(translationX: 0, y:changeY)
            self.alpha = 1;
        }
        
    }
    @objc fileprivate func keyBoardWillHide(_ notification:NSNotification){
        let kbInfo = notification.userInfo
        
        //获取键盘的size
        
        let kbRect = (kbInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        
        //键盘的y偏移量
        
        let changeY = kbRect.origin.y - UIScreen.main.bounds.height
        
        //键盘弹出的时间
        
        let duration = kbInfo?[UIKeyboardAnimationDurationUserInfoKey] as!Double
        
        UIView.animate(withDuration: duration, animations: {
            self.transform = CGAffineTransform(translationX: 0, y:changeY)
            self.alpha = 0
        }) { (isEnd) in
            if isEnd {
                self.isHidden = true
            }
        }
        
    }

提供按钮点击响应,以闭包的形式进行回调

   typealias BtnClickClouse = (_ index:NSInteger)->Void
    
    private var btnClickBlock:BtnClickClouse?
    
    convenience init(_ view:UIView,_ block:@escaping BtnClickClouse) {
        self.init(frame: CGRect.init(x: 0, y: view.bounds.height-40, width: UIScreen.main.bounds.width, height: 40))
        setup()
        self.btnClickBlock = block     
    }

//点击方法
    @objc private func cameraBtnClick(){  
        
        self.btnClickBlock!(0)
    }
    @objc private func locationBtnClick(){
        
        self.btnClickBlock!(1)
    }

ViewController中初始化KeyBoardStatusView

lazy var keystatusView: KeyBoardStatusView = {
        let statusview = KeyBoardStatusView.init(self.view, { (index) in
            if (index == 0 ){
                self.addPhoto()
            }
            else if (index == 1) {
                self.addLocate()
            }
        })
        return statusview
    }()
  1. CLLocation的使用以及经纬度反编码
import CoreLocation
private var location = CLLocationManager.init()

 lazy var geoCoder: CLGeocoder = {
        return CLGeocoder()
    }()

//添加定位信息
    private func addLocate(){
        location.delegate = self
        //定位方式
        location.desiredAccuracy = kCLLocationAccuracyBest
        //授权请求
        location.requestWhenInUseAuthorization()
        
        if (CLLocationManager.locationServicesEnabled()){
            //允许使用定位服务的话,开始定位服务更新
            location.startUpdatingLocation()
        }
        else
        {
            CLLocationManager.authorizationStatus()
        }
    }

extension ViewController:CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        
        self.EntryTextView.text = "\(String(describing: locations.first?.coordinate.latitude))"+"\n\(String(describing: locations.first?.coordinate.longitude))"
        
        geoCoder.reverseGeocodeLocation(CLLocation.init(latitude: (locations.first?.coordinate.latitude)!, longitude: (locations.first?.coordinate.longitude)!)) { (pls: [CLPlacemark]?, error: Error?)  in
            if error == nil {
                print("反地理编码成功")
                guard let plsResult = pls else {return}
                let firstPL = plsResult.first
                self.keystatusView.locationLabel.text = firstPL?.name
            }else {
                print("错误")
            }
        }
        manager.stopUpdatingLocation()
    }
    
}

需要设置Privacy - Location When In Use Usage Description 请求获取定位权限的描述

  1. 设置照片,拍照, 以及actionsheet
private func addPhoto() {
        
        let alertActionSheet = UIAlertController.init(title: nil, message: nil, preferredStyle:   UIAlertControllerStyle.actionSheet)
        let actionCamera = UIAlertAction.init(title: "拍照", style: UIAlertActionStyle.default) { _ in
            if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera){
                UIImagePickerController.availableMediaTypes(for: UIImagePickerControllerSourceType.camera)
                let pick = UIImagePickerController()
                pick.delegate = self
                self.present(pick, animated: true, completion: nil)
                
            }
            else{
                print("不支持")
            }
            
        }
        let actoionPhoto = UIAlertAction.init(title: "相册", style: UIAlertActionStyle.default) { (_) in
            if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary)
            {
                UIImagePickerController.availableMediaTypes(for: UIImagePickerControllerSourceType.photoLibrary)
                let pick = UIImagePickerController()
                pick.delegate = self
                self.present(pick, animated: true, completion: nil)
                
            }
            else{
                print("不支持")
            }
        }
        let actionCancel = UIAlertAction.init(title: "取消", style: UIAlertActionStyle.cancel, handler: nil)
        alertActionSheet.addAction(actionCamera)
        alertActionSheet.addAction(actoionPhoto)
        alertActionSheet.addAction(actionCancel)
        self.present(alertActionSheet, animated: true, completion: nil)
        
    }

  1. NSDate
lazy var formatter: DateFormatter = {
        let formatter1 = DateFormatter.init()
        formatter1.locale = Locale.current
        formatter1.dateFormat = "MM/dd/YYY"
        return formatter1
    }()

  let date = Date.init()
  TimeLabel.text = formatter.string(from: date)
  1. cell自适应高度
    从设计图分析,每个控件之间间隔为10,并且允许什么都不输入,那么此时只有一个TimeLabel(15的高度),cell基础高度为15+10+10。
    此时,需要分情况讨论 image和text以及location的高度关系
    1.当只有image或者text和location总高度不如imageView时, imageView 与 TimeLabel同在一个origin.y,那么此时cell高度为50+10+10
    2.text和location的总高度大于image的高度时,使用text和location的总高度。

在model中将高度计算完成
model.swift

struct Model{
    var time:String!
    var image:String!
    var location:String = ""
    var text:String = ""
    private var _height:CGFloat = 35
    var height: CGFloat {
        get {
            return _height
        }
        set {
            _height = newValue
        }
    }
    
    public mutating func calculteHeight(_ font:CGFloat, _ width:CGFloat) {
        var locationH:CGFloat = 0
        var textH:CGFloat = 0
        let imageH:CGFloat = 50+20 - 35
        if location.count > 0 {
            locationH = 25
        }
        
        if text.count > 0 {
            let textFont = UIFont.systemFont(ofSize: 14)
            let textString = text
            let textMaxSize = CGSize(width: width, height: CGFloat(MAXFLOAT))
            let size = textSize(text: textString, font: textFont, maxSize: textMaxSize)
            textH = size.height + 10
        }
        
        if image.count > 0 && imageH > locationH + textH{
            height = height + imageH
        }
        else {
            height = height + locationH + textH
            
        }
        _height = height
    }
    private func textSize(text : String , font : UIFont , maxSize : CGSize) -> CGSize{
        return text.boundingRect(with: maxSize, options: [.usesLineFragmentOrigin], attributes: [NSAttributedStringKey.font : font], context: nil).size
    }
}

ViewController.swift

public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        var model:Model = sourceArray[indexPath.row]
        //重新计算
        model.calculteHeight(14.0, Screen_Width-80-80)
        return model.height
    }

在实际项目中实践,在书写记录中巩固。
最近用swift重写现在的一些项目, 涉及很多库 记录一下

target '****_Swift' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!
    pod 'MJRefresh'              
    pod 'Moya'
    pod 'Moya/RxSwift'
    pod 'RxSwift',    '~> 4.0'
    pod 'RxCocoa',    '~> 4.0'
    pod 'CTMediator'                  //用于解耦
    pod 'SDWebImage'
    pod 'MBProgressHUD'
    pod 'DZNEmptyDataSet'        //优秀的空白展示页
    pod 'SwiftyJSON'
#    pod 'PermissionScope'
#    pod 'EZSwiftExtensions', '~> 1.11'
    pod 'SwiftyUserDefaults'
    pod 'SnapKit'
    pod 'Hero'
    pod 'GDPerformanceView-Swift', '~> 1.3.2'
  # Pods for ****_Swift

  target '****_SwiftTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target '****_SwiftUITests' do
    inherit! :search_paths
    # Pods for testing
  end

end

你可能感兴趣的:(Swift学习记录 Project 5)