istudy學生端專案的總結(二)
阿新 • • 發佈:2019-01-03
當有navigationBar的時候不設定向下移動64個單位 textView和tableView都是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 隨後上傳即可