直播项目笔记(四)

2017-11-30  本文已影响0人  Closer3

心跳包 + 图文混排 + Core Graphics

Socket 服务器加入心跳包

Timer 和 Runloop

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)
上一篇 下一篇

猜你喜欢

热点阅读