1. 程式人生 > >istudy學生端專案的總結(二)

istudy學生端專案的總結(二)

當有navigationBar的時候不設定向下移動64個單位 textViewtableView都是scrollView,因此當有navigationBar的時候都會自動的往下移

因此可以用這兩句話 其中一種方法來解決

不設定自動往下移,本來預設是true

self.automaticallyAdjustsScrollViewInsets = false
還有一種是跟新tableView的subView 因為tableView的subView是scrollView
    override func viewWillLayoutSubviews() {
       super.viewWillLayoutSubviews()
        self.tableView?.contentInset = UIEdgeInsetsZero
        self.tableView?.scrollIndicatorInsets = UIEdgeInsetsZero
    }


設定隱藏自己的tabBar

 self.tabBarController?.tabBar.hidden = true

當向伺服器傳圖片時,一種是傳url,還有一種是傳base64的字串,需將圖片變成base64的字串
    //每張圖片轉化成base64的字串
    func imageToBae64(image:UIImage) -> String{
        let data = UIImageJPEGRepresentation(image, 0.5)
        let encodeString = data?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
        return encodeString!
    }

將系統裡面選擇的相簿轉化成為image
   //當選擇好相簿後
    func photoPicker(picker: AJPhotoPickerViewController!, didSelectAssets assets: [AnyObject]!) {
        for i in 0 ..< assets.count {
            let asset = assets[i]
            let tempImage = UIImage(CGImage: asset.defaultRepresentation().fullScreenImage().takeUnretainedValue())
            self.photos.addObject(tempImage)
        }
        picker.dismissViewControllerAnimated(true, completion: nil)
        
        self.collectionView?.reloadData()
    }

將圖片的base64字串組裝成html的格式
   //轉換成base64字串
        for i in 0 ..< self.photos.count{
            let widthAndHeight = " width = " + "\(50)" + " height = " + "\(50)"
            let base64String = imageToBae64(self.photos[i] as! UIImage)
            let imgHtml = "<img"  + widthAndHeight +  " src = " + "\"" +  "data:image/jpg;base64," + base64String +  "\"" + "/>"
            
            content += imgHtml

        }
類似QQ的分組表

只要在每個tablView的sectonView中新增一個按鈕 隨後用一個是非值進行儲存即可

 //實現sectionView的檢視
    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = UIView(frame: CGRectMake(0,0,SCREEN_WIDTH,30))
        view.backgroundColor = UIColor.whiteColor()
        
        //組的名稱 還有箭頭圖片 記錄人數
        let tempArray = self.items[section].valueForKey("ContacterList") as! NSArray
        
        let groupNameLabel = UILabel(frame: CGRectMake(40,0,SCREEN_WIDTH - 40,30))
        groupNameLabel.text = (self.items[section].valueForKey("Label") as? String)! + "(" + "\(tempArray.count)" + "人)"
       //箭頭的檢視
        
        let imageView = UIImageView(frame: CGRectMake(0, 0, 40, 30))
        if(self.selectArr[section] as! NSObject == 1){
        imageView.image = UIImage(named: "選擇信件")
        }else{
            imageView.image = UIImage(named: "未選擇信件")
        }
       
        let btn = UIButton(frame: CGRectMake(0,0,SCREEN_WIDTH,50))
        
        btn.tag = section
        btn.addTarget(self, action: #selector(ContactPersonViewController.btnOpenList(_:)), forControlEvents: .TouchUpInside)
        view.addSubview(btn)
          view.addSubview(imageView)
        view.addSubview(groupNameLabel)
        view.bringSubviewToFront(btn)
        view.autoresizingMask = .FlexibleWidth
        return view
    }

點選按鈕的事件
  func btnOpenList(sender:UIButton){
        if(self.selectArr[sender.tag] as! NSObject == 0){
            self.selectArr[sender.tag] = 1
        }else{
            self.selectArr[sender.tag] = 0
        }
        self.contactPersonTableView?.reloadData()
    }

隨後跟新檢視的時候跟新每個section的row的行數
  func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //每一組究竟有幾個列表
        if(self.selectArr[section] as! NSObject == 1){
        self.contacterlistArray = self.items[section].valueForKey("ContacterList") as! NSArray
        return self.contacterlistArray.count
        }else{
            return 0
        }
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        //首先賦值每個組的聯絡人表
        self.contacterlistArray = self.items[indexPath.section].valueForKey("ContacterList") as! NSArray
        let cell = tableView.dequeueReusableCellWithIdentifier("ContactPersonTableViewCell")
        as! ContactPersonTableViewCell
        //先不賦值
        if(self.selectArr[indexPath.section] as! NSObject == 1){
        cell.teacherHeadImageView?.image = UIImage(named: "教師頭像")
        cell.teacherNameLabel?.text = self.contacterlistArray[indexPath.row].valueForKey("Name") as? String
        cell.selectedBtn?.addTarget(self, action: #selector(ContactPersonViewController.selectPerson(_:)), forControlEvents: .TouchUpInside)
        cell.id = self.contacterlistArray[indexPath.row].valueForKey("Id") as! NSInteger
        cell.isSelect = false
        //自定義btn的tag
           cell.selectedBtn?.setImage(UIImage(named: "未選擇信件" ), forState: .Normal)
        cell.selectedBtn!.customTag = "\(indexPath.section)" + "-" + "\(indexPath.row)"
            for i in 0 ..< self.selectedPersonIdArray.count{
                if(self.selectedPersonIdArray[i] as! NSInteger == cell.id){
                    cell.isSelect = true
                cell.selectedBtn?.setImage(UIImage(named: "選擇信件" ), forState: .Normal)
                }
            }

        cell.selectionStyle = .None
        }
        return cell
    }
因為每個indexPath的row都一樣 所以要自定義button 改變他的tag即可
import UIKit

class CustomContactSelectBtn: UIButton {

   //自定義tag
    var customTag = ""

}

當有doc,ppt等檔案型別的時候 一種選擇是開啟safari瀏覽器,但是使用者體驗不好,還有一種是用PreviewController

繼承協議

QLPreviewControllerDataSource

var fileUrl = NSURL()

用Url 進行預覽

隨後點選的時候進行預覽即可

   func previewController(controller: QLPreviewController, previewItemAtIndex index: Int) -> QLPreviewItem {
        return self.fileUrl
    }
字串的分割 後臺返回來的時間型別是yyyyMMddhhmmss型別的 因此需要進行分割 分割必須是NSString型別的

定義其實位置 和長度

     let yearRange = NSMakeRange(0, 4)
        let monthRange = NSMakeRange(4, 2)
        let dateRange = NSMakeRange(6, 2)
        let hourRange = NSMakeRange(8, 2)
        let minuateRange = NSMakeRange(10, 2)
        let secondRange = NSMakeRange(12, 2)

進行切割
 tempStartDate = items[indexPath.row].valueForKey("datestart") as! NSString
 date += "開始時間:" + tempStartDate.substringWithRange(yearRange) + "-" + tempStartDate.substringWithRange(monthRange) + "-" + tempStartDate.substringWithRange(dateRange) + " " + tempStartDate.substringWithRange(hourRange) + ":" + tempStartDate.substringWithRange(minuateRange) + ":" + tempStartDate.substringWithRange(secondRange) + "\n"

將截止時間得到的字串轉化為date型別 隨後與現在的時間進行比較,要注意日期的格式 第一個是晚於現在的日期 第二個是早於現在的日期
   //string轉化為date
        if(jsonDateString != ""){
        let formatter = NSDateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        let jsonDate = formatter.dateFromString(jsonDateString)
        let currentDate = NSDate()
        cell.endDate  = jsonDate!
        //進行比較
        let result:NSComparisonResult = currentDate.compare(jsonDate!)
        if result == .OrderedAscending{
               cell.answerQusBtn?.setTitle("答題", forState: .Normal)
           
            
        }else{
              cell.answerQusBtn?.setTitle("檢視", forState: .Normal)
            if(!self.isExercise){
             cell.Score?.text = "成績:" + score
            }
        }

tableView頂部加一個搜尋條 首先繼承協議
UISearchResultsUpdating,UISearchControllerDelegate
定義搜尋條
  var sc:UISearchController!

  sc = UISearchController(searchResultsController: nil)


 sc.searchResultsUpdater = self
        sc.dimsBackgroundDuringPresentation = false
        sc.hidesNavigationBarDuringPresentation = true
        sc.searchBar.placeholder = "請輸入試卷名稱"
        sc.searchBar.searchBarStyle = .Minimal
        sc.searchBar.sizeToFit()
        self.tableView?.tableHeaderView = sc.searchBar
        sc.delegate = self


當有搜尋條的時候sc為活躍狀態 否則為沉寂狀態 根據這個的不同 來改變tableView中顯示的值

 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if(sc?.active == false) {
        return self.items.count
        }else{
        return filterItems.count
        }
    }
當搜尋條中有文字輸入時,跟新檢視 實際就是建立一個數組 隨後進行謂詞匹配來新增新的陣列的值,隨後檢視中來展現新的匹配後的東西
  func updateSearchResultsForSearchController(searchController: UISearchController) {
        self.filterItems.removeAllObjects()
        let scopePredicate = NSPredicate(format: "SELF contains[c] %@", searchController.searchBar.text!)
        for i in 0 ..< self.items.count{
            if(scopePredicate.evaluateWithObject(self.items[i].valueForKey("title")) == true){
                self.filterItems.addObject(self.items[i])
            }
        }
        
        self.tableView?.reloadData()
    }
    func willPresentSearchController(searchController: UISearchController) {
        self.tableView?.mj_header.hidden = true
    }
    func willDismissSearchController(searchController: UISearchController) {
        self.tableView?.mj_header.hidden = false
    }
當點選背景的時候 來使搜尋條拿掉
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.sc.active = false
        self.sc.searchBar.text = ""
        sc.dismissViewControllerAnimated(true, completion: nil)
       }
當這個頁面完全拿出時,呼叫解構函式時,搜尋條移除
  override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.sc.active = false
        self.sc.searchBar.text = ""
        sc.dismissViewControllerAnimated(true, completion: nil)
       }

回退回上一個viewController 在navigation的棧裡面 進行遍歷
f(sender.tag == 1) {
            let vc = UIStoryboard(name: "OneCourse", bundle: nil).instantiateViewControllerWithIdentifier("MyHomeWorkVC") as! MyHomeWorkViewController
            
            for temp in (self.navigationController?.viewControllers)!{
                if(temp .isKindOfClass(vc.classForCoder)){
                    self.navigationController?.popToViewController(temp, animated: true)
                }
            }
但是若是改變vc的值,是不會有任何作用的 這種遍歷情況下的回退 注意

點選webView隨後進行圖片的放大

獲取到圖片的url

 func webViewShowBig(sender:UITapGestureRecognizer){
        var pt = CGPoint()
     var urlToSave = ""
        if(sender.view?.tag == 1){
         pt = sender.locationInView(self.answerWebView)
            let imgUrl = String(format: "document.elementFromPoint(%f, %f).src",pt.x, pt.y);
             urlToSave = self.answerWebView.stringByEvaluatingJavaScriptFromString(imgUrl)!
        }else{

圖片放大的手勢識別,手勢也要有delegate隨後進行識別,是點選在要放大的那個webView上
   //圖片放大時候的動作
    func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
        
        return true
        
    }
    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        if(gestureRecognizer == self.tap){
            return true
        }else{
            return false
        }
    }



隨後將url轉化成data,在轉化成url 傳到放大的視圖裡
     let image = UIImage(data: data!)
        let previewPhotoVC = UIStoryboard(name: "Problem", bundle: nil).instantiateViewControllerWithIdentifier("previewPhotoVC") as! previewPhotoViewController
        previewPhotoVC.toShowBigImageArray = [image!]
        previewPhotoVC.contentOffsetX = 0
        self.navigationController?.pushViewController(previewPhotoVC, animated: true)
        }

webView載入好自動適應高度 不讓他滾動 繼承協議
UIWebViewDelegate
 self.qusDes.delegate = self

隨後在webViewdidStart裡面初始化webView的長寬,因為若載入新的html文件,的話,他會保留上次載入的長寬,因此要初始化
讓webView自動適應寬度
  func webViewDidStartLoad(webView: UIWebView) {
        webView.frame = CGRectMake(0, 0, SCREEN_WIDTH, 1)
    }
    var resetBtnAndQusHeight:CGFloat = 0.0
    func webViewDidFinishLoad(webView: UIWebView) {
        let height = NSInteger(webView.stringByEvaluatingJavaScriptFromString("document.body.offsetHeight")!)
        
        var NewFrame = webView.frame
        NewFrame.size.height = CGFloat(height!) + 5
        webView.frame = NewFrame
        let scrollView = webView.subviews[0] as! UIScrollView
        scrollView.showsVerticalScrollIndicator = false
        let width = NSInteger(webView.stringByEvaluatingJavaScriptFromString("document.body.scrollWidth")!)
    scrollView.contentSize = CGSizeMake(CGFloat(width!), 0)
當有一個view時,要加陰影的偏移效果時
//頂部加條線
        //設定陰影效果
        self.topView?.layer.shadowOffset = CGSizeMake(2.0, 1.0)
        self.topView?.layer.shadowColor = UIColor.blueColor().CGColor
        self.topView?.layer.shadowOpacity = 0.5
注意collectionView是要有資源的 沒有資源,非同步從後臺獲取的話,就會崩潰

這裡題目 例如選擇題,填空題等都是用tableView來實現的 header載入題目描述,隨後每個cell載入選項或者空格 選項時有可能會有圖片,因此要自適應圖片的高度 因此只要在cell的方法中代理webView的delegate 隨後等Html載入好以後傳送通知到viewController,隨後每個cell的高度用一個數組儲存,初始化,當通知拿來的時候 要進行判斷 自己的陣列中的值和發來的這個通知是否一樣 若不一樣 進行改變即可 重新整理tableView 注意在這裡實現cell的方法中,不是重用cell,而是每次初始化一個Cell,這也是一個bug吧,隨後在cell中也是用程式碼的方式新增控制元件,而不是用拖拽的方式

<pre name="code" class="plain">    NSNotificationCenter.defaultCenter().postNotificationName("ChoiceWebViewHeight", object: self, userInfo: nil)


    //註冊通知
        NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(ChoiceQusViewController.reloadCellHeight(_:)), name: "ChoiceWebViewHeight", object: nil)

隨後改變cell的高度即可
    func reloadCellHeight(sender:NSNotification){
        let cell = sender.object as! ChoiceTableViewCell
        if(self.cellHeight[cell.Custag] as! CGFloat != cell.cellHeight){
            self.cellHeight.replaceObjectAtIndex(cell.Custag, withObject: cell.cellHeight)
            self.tableView?.reloadData()
        }
        
        
}

設定btn的下劃線 用富文字的方式
  let str1 = NSMutableAttributedString(string: (self.forgetPasswordBtn?.titleLabel?.text)!)
        let range1 = NSRange(location: 0, length: str1.length)
        let number = NSNumber(integer: NSUnderlineStyle.StyleSingle.rawValue)
        str1.addAttribute(NSUnderlineStyleAttributeName, value: number, range: range1)
       str1.addAttribute(NSForegroundColorAttributeName, value: UIColor.blueColor(), range: range1)
        self.forgetPasswordBtn?.setAttributedTitle(str1, forState: .Normal)
隨後設定鍵盤的時候,最好是設定約束中的layout的值,最好不要設定frame的值 有時會失效

設定label或texTView的字型的顏色時,首先有值,在設定顏色

self.displayMarkingTextView?.text = totalString
                self.displayMarkingTextView?.textColor = UIColor.redColor()

將點選事件傳到下一個view中去 可以首先自定義一個view
class mainTableView: UITableView {
    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect) {
        // Drawing code
    }
    */
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.nextResponder()?.touchesBegan(touches, withEvent: event)
    }
}
隨後用到的tableView 用這個自定義的即可
  @IBOutlet weak var courseDesTableView:mainTableView?
隨後的點選事件
  override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
                self.sc.active = false
            self.sc.searchBar.text = ""
            self.tabBarController?.tabBar.hidden = false
            
        }
差不多現在是這樣,願專案趕緊上線吧

Alamofire來進行上傳檔案 

Alamofire.upload(.POST, string, multipartFormData: { (formData) in
        formData.appendBodyPart(data: self.selectedImageData, name: "name", fileName: "head.jpg", mimeType: "image/jpeg")
        }) { (encodingResult) in
            switch encodingResult {
            case .Success(let upload, _, _):
   //         print((upload.request?.allHTTPHeaderFields))
                upload.responseJSON(completionHandler: { (response) in
                    switch response.result{
                    case .Success(let Value):
                        let json = JSON(Value)
                      userDefault.setValue(json["info"]["uploadedurl"].string, forKey: "avtarurl")
                        self.save()
                    case .Failure(_):
                        print(2)
                        ProgressHUD.showError("儲存失敗")
                    }
                })
            case .Failure(_):
                ProgressHUD.showError("儲存失敗")
                print(3)
            }
        }

selectedImageData是自己的圖片的二進位制檔案 將圖片進行命名隨後上傳 定義型別為jpg 隨後上傳即可