美文网首页
直播项目笔记(四)

直播项目笔记(四)

作者: Closer3 | 来源:发表于2017-11-30 20:04 被阅读0次

    心跳包 + 图文混排 + Core Graphics

    Socket 服务器加入心跳包

    Timer 和 Runloop

    • Timer只负责计时,Timer所绑定的动作,是由Runloop来执行的,Runloop运行的时候需要指定运行模式,一个timer同一时间只可以注册到一个runloop中,但是可以添加到这个runloop的多个运行模式中

    • 两个创建Timer的区别

    test1 //计时器会在当前循环最后进行 先输出haha才开始计数
    
    override func viewDidLoad() {
        super.viewDidLoad()
           
        // 创建 timer
        timer = Timer(timeInterval: 1, target: self, selector: #selector(test), userInfo: nil, repeats: true)
        /*
        创建一个 timer 加入到当前 runloop 默认模式
        timer = Timer(timeInterval: 1, target: self, selector: #selector(test), userInfo: nil, repeats: true)
        */
           
        // 将 timer 加入到 Runloop 中
        RunLoop.current.add(timer, forMode: .commonModes)
        print("haha")
    }
            
    @objc func test() {
        count += 1
        print("\(count)")
    }
    
    test2 //计时器手动开始执行 fire() 先开始第一次计数再输出haha
    override func viewDidLoad() {
      super.viewDidLoad()
      
      timer = Timer(fireAt: Date(), interval: 1, target: self, selector: #selector(test), userInfo: nil, repeats: true)
      // 将 timer 加入到 Runloop 中
      RunLoop.current.add(timer, forMode: .commonModes)
      timer.fire()
      print("哈哈")
    }
       
    @objc func test() {
      count += 1
      print("\(count)")
    }
    

    添加聊天内容

    正则表达式

    在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码

    • 常用元字符
    \ba\w*\b匹配以字母a开头的单词——先是某个单词开始处(\b),然后是字母a,然后是任意数量的字母或数字(\w*),最后是单词结束处(\b)。
    \d+匹配1个或更多连续的数字。这里的+是和*类似的元字符,不同的是*匹配重复任意次(可能是0次),而+则匹配重复1次或更多次。
    \b\w{6}\b 匹配刚好6个字符的单词。
    
    代码 说明
    . 匹配除换行符以外的任意字符
    \w 匹配字母或数字或下划线或汉字
    \s 匹配任意的空白符
    \d 匹配数字
    ^ 匹配字符串的开始
    $ 匹配字符串的结束
    一个网站如果要求你填写的QQ号必须为5位到12位数字时,可以使用:^\d{5,12}$
    
    • 字符转义

    如果你想查找元字符本身的话,比如你查找.,或者*,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\来取消这些字符的特殊意义。因此,你应该使用\.和\*。当然,要查找\本身,你也得用\
    在swift中 转义字符是 \\

    • 重复
    代码/语法 说明
    * 重复零次或更多次
    + 重复一次或更多次
    重复零次或一次
    {n} 重复n次
    {n,} 重复n次或更多次
    {n,m} 重复n到m次
    • 字符类 [ ]

    [aeiou]匹配任何一个英文元音字母
    [.?!]匹配标点符号(.或?或!)

    • 分歧条件 |

    \d{5}-\d{4}|\d{5}这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:使用分枝条件时,要注意各个条件的顺序。如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了

    富文本(NSAttributedString)

    image
    • 给字符串特定字符换颜色
    let str = "小明:哈哈哈哈"
    label1.text = str
            
    let attr = NSMutableAttributedString(string: str)
    // NSAttributedStringKey里还有更多可修改的属性
    attr.addAttributes([NSAttributedStringKey.foregroundColor: UIColor.orange], range: NSRange(location: 0, length: 2))
    label2.attributedText = attr
    
    • 图文混排
    let str = "小明:[鄙视]你怎么这样[呲牙]"
    label1.text = str
       
    let attr = NSMutableAttributedString(string: str)
    // 正则表达式 匹配表情
    let pattern = "\\[.*?\\]"
    let regex = try! NSRegularExpression(pattern: pattern, options: [])
    let results = regex.matches(in: str, options: [], range: NSRange(location: 0, length: str.count))
    // 获取表情的结果 从后往前匹配 避免打乱前面字符串的range
    for i in (0..<results.count).reversed() {
      let result = results[i]
      let emoticonName = (str as NSString).substring(with: result.range)
      let image = UIImage(named: emoticonName)
      let attachment = NSTextAttachment()
      attachment.image = image
      let font = UIFont.systemFont(ofSize: 15)
      attachment.bounds = CGRect(x: 0, y: -3, width: font.lineHeight, height: font.lineHeight)
      let imageAttrStr = NSAttributedString(attachment: attachment)
      attr.replaceCharacters(in: result.range, with: imageAttrStr)
    }
    label2.attributedText = attr
    

    礼物动画展示

    Core Graphics

    1. 什么是Core Graphics

    Core Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎。它提供了低级别、轻量级、高保真度的2D渲染。该框架可以用于基于路径的绘图、变换、颜色管理、脱屏渲染,模板、渐变、遮蔽、图像数据管理、图像的创建、遮罩以及PDF文档的创建、显示和分析

    2. 绘图的一般步骤

    (1)获取绘图上下文
    (2)创建并设置路径
    (3)将路径添加到上下文
    (4)设置上下文状态(如笔触颜色、宽度、填充色等等)
    (5)绘制路径

    3. 绘制图形
    override func draw(_ rect: CGRect) {
       super.draw(rect)
       let context = UIGraphicsGetCurrentContext() // 获取上下文 创建画布
       let path = CGMutablePath() // 创建路径
       path.move(to: CGPoint(x: 20, y: 50)) // 移动到指定位置(设置路径起点)
       path.addLine(to: CGPoint(x: 20, y: 100)) // 绘制直线(从起始位置开始)
       context?.addPath(path) // 把路径添加到上下文(画布)中
       // Core Graphics中还提供了很多预先设置好的路径
       // CGContext.add()
       
       // 设置图形上下文状态属性
       context?.setStrokeColor(UIColor.blue.cgColor) // 设置笔触颜色
       
       // 阴影 虚线 填充色 顶点 连接点 ...
       
       // 填充类型中可以选择只绘制边框、只填充、同时绘制边框和填充内部区域、奇偶规则填充等
       context?.setTextDrawingMode(.stroke) // 填充类型
       // 绘制路径
       context?.strokePath()
       // OC的ARC机制并不会对它进行内存管理,但是Swift对它自动进行了,所以在Swift中不需要写这个代码  CGPathRelease(path)
    }
    

    Keyframe动画

    Keyframe动画可以让我们有效的拆分由若干段动画连接而成的复杂动画,可以较为精准的定义每段动画的起始点及持续时间,并且在代码组织方面也非常清晰

    UIView.animateWithDuration(1, animations: {  
        view.center.x += 200.0  
    }, completion: { _ in  
        UIView.animateWithDuration(1, animations: {  
            view.center.y += 100.0  
        }, completion: { _ in  
            UIView.animateWithDuration(1, animations: {  
                view.center.x -= 200.0  
            }, completion: { _ in  
                UIView.animateWithDuration(1, animations: {  
                    view.center.y -= 100.0  
                }, completion: nil)  
            })  
        })  
    })
    
    // or
    
    UIView.animateKeyframesWithDuration(2, delay: 0, options: [], animations: {  
        // relativeDuration 是总动画时长的百分比
        UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0.25, animations: {  
                view.center.x += 200.0  
            })  
            UIView.addKeyframeWithRelativeStartTime(0.25, relativeDuration: 0.25, animations: {  
                view.center.y += 100.0  
            })  
            UIView.addKeyframeWithRelativeStartTime(0.5, relativeDuration: 0.25, animations: {  
                view.center.x -= 200.0  
            })  
            UIView.addKeyframeWithRelativeStartTime(0.75, relativeDuration: 0.25, animations: {  
                view.center.y -= 100.0  
            })  
    }, completion: nil)
    
    • 礼物连击动画
    UIView.animateKeyframes(withDuration: 0.25, delay: 0, options: [], animations: {
        UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5, animations: {
            self.transform = CGAffineTransform(scaleX: 3.0, y: 3.0)
        })
          
        UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5, animations: {
            self.transform = CGAffineTransform(scaleX: 0.7, y: 0.7)
        })
    }, completion: { isFinished in
        UIView.animate(withDuration: 0.25, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 10, options: [], animations: {
            self.transform = CGAffineTransform.identity
        }, completion: { (isFinished) in
            complection()
        })
    })
    

    取消延迟执行函数

    // 取消一个对象在当前Run Loop中的所有未执行的
    NSObject.cancelPreviousPerformRequests(withTarget: self)
    
    self.perform(#selector(self.test), with: self, afterDelay: 3.0)
    // 调用取消执行函数后 test方法不会执行
    NSObject.cancelPreviousPerformRequests(withTarget: self)
    

    相关文章

      网友评论

          本文标题:直播项目笔记(四)

          本文链接:https://www.haomeiwen.com/subject/bvdbbxtx.html