istudy学生端项目的总结(二)

当有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

        }

差不多现在是这样,愿项目赶紧上线吧

时间: 2024-11-12 12:03:21

istudy学生端项目的总结(二)的相关文章

【铜】第174-9篇 一对一视频录制(九)一对多学生端删除白板及nginx下配CI

关键词:webm文件在手机端播放, 一对多学生端删除白板, nginx下配CI 一.一对一视频录制 1.1.webm文件在手机端播放 1)在PC上 a.)用谷歌浏览器播放 http://123.57.206.36:8014/uploads/177013288141499069939723.webm 2)手机端播放 二.一对多 2.1 网址 1)备份上 老师端:https://123.57.206.36:9101/demos/index.html?roomid=888&teaNameMobile=

家乡の战队实训项目博客二

家乡の战队:黄金点项目博客二 1.团队风采 组长:唐宇      16012020 队员:王松鹤  16012016 刘计     16012024 庞啸天 16012011 2.码云地址 https://gitee.com/wcnma/home_troops/tree/master 3. 团队分工 唐宇:团队组长,灵魂核心,领导组员完成java任务,是组员的导向标 评分:9 王松鹤:团队技术担当,高端技术人才,完成主要的java项目 评分:10 刘计:掌握了java的基础知识,擅长与客户交谈,

Vue2+VueRouter2+webpack 构建项目实战(二):目录以及文件结构

通过上一篇博文<Vue2+VueRouter2+webpack 构建项目实战(一):准备工作>,我们已经新建好了一个基于vue+webpack的项目.本篇文章详细介绍下项目的结构. 项目目录以及文件结构 如图所示: 如上图所示,自动构建的vue项目的结构就是这样. 目录/文件 说明 build 这个是我们最终发布的时候会把代码发布在这里,在开发阶段,我们基本不用管. config 配置目录,默认配置没有问题,所以我们也不用管 node_modules 项目开发依赖的一些模块 src 开发目录(

总结一下做移动端项目遇到的坑

新上线了一个vue的移动端项目,其中用到了时间控件,但是input[type='date']没有placeholder属性,网上查到的方法是<input type='text' onfocus='this.type="date"'>,这种方法在ios上是没问题的,但是在安卓上则需要点击两次才可以调起系统的时间控件.因此决定自己写个组件,解决安卓上的兼容性问题.代码如下: <template> <div class="date_container&

iOS开发——项目实战Swift篇&amp;swift 2.0项目开发总结二(开发常用)

swift 2.0项目开发总结二(开发常用) 一:相册中选择相片到App指定位置 随 着相机像素的提高,实际用户选择的图片都是很大的,有的高达5.6M,如果直接使用用户选着的图片,非常消耗内存,并且也用不到这么高像素的图片,可以当 用户选着好图片后,在UIImagePickerController对应的代理方法中,先将图片进行重新绘制为需要的大小,在设置给iconView 1 /// MARK: 摄像机和相册的操作和代理方法 2 extension MeViewController: UIIma

Vue移动端项目总结

使用Vue项目写了一个移动端项目,然后又把项目硬生生的抽离了组件,一直忙着写RN项目没有时间总结心得,今天上午终于下定决心,写点总结. 1.position:absolute: 定位的时候不同手机的浏览器版本不一样,存在兼容性问题,所以要修改为fixed,然后使用left: calc(50% - 1rem )进行定位: 2.event.touches[0].pageY:移动端事件touchstart,touchmove,touchend,在vue中的手指滑动的对象是要传入$event才可以使用e

【原创】岗位作业书-产品/项目经理(二)

产品/项目经理岗位作业书 --------------------- 岗位作业书配合是<开发工作流程>的重要附件,详细说明了每个岗位在开发过程中每个阶段的工作 一.每日例行工作: 1.早上开始上班后立即召开朝礼 2.写朝礼纪要并发给相关人 3.在日志中制定今日工作计划并挂到主线 4.上禅道检查任务完成进度是否与计划相符 5.上禅道检查Bug修复情况是否正常 6.处理各种临时任务,加入到禅道的任务列表,如:甲方提出的紧急任务等 7.如有必要,与技术经理.测试经理沟通 8.发现开发进度有严重延误的

移动端 项目总结

前言:刚完成一个简单的移动端项目,单从布局上来说,跟pc端的方法大致相同. 移动端的页面排版更简单一些,基本以单行为基础,逐行排版.唯一要注意的尺寸问题,由于移动设备的尺寸大小各不相同,所以要考虑一个适应主流移动设备宽度的页面排版.一般最常用的就是行居中效果,这样排版一般不会因为屏幕宽度太小而出现挤压的问题. 这里还要提到一个移动设备的缩放问题.做出来的页面可能无法完全适合移动设备的屏幕宽度,因此需要在html文档中声明设备宽度: 1 <meta name="viewport"

网站日志分析项目案例(二)数据清洗(MiniMapreduce)

网站日志分析项目案例(二)数据清洗 一.数据情况分析 1.1 数据情况回顾 该论坛数据有两部分: (1)历史数据约56GB,统计到2012-05-29.这也说明,在2012-05-29之前,日志文件都在一个文件里边,采用了追加写入的方式. (2)自2013-05-30起,每天生成一个数据文件,约150MB左右.这也说明,从2013-05-30之后,日志文件不再是在一个文件里边. 图1展示了该日志数据的记录格式,其中每行记录有5部分组成:访问者IP.访问时间.访问资源.访问状态(HTTP状态码).