swift-05.01

禮物連擊動(dòng)畫

基礎(chǔ)知識

digitalLable:1.畫文字 ?2.lable動(dòng)畫回調(diào)

channelView:0.幾種狀態(tài) 1.當(dāng)執(zhí)行完(lable動(dòng)畫回調(diào))--檢測是否有緩存數(shù)量-有就遞歸執(zhí)行-count==0 ? 2.單模型緩存--數(shù)量? 3.動(dòng)畫 ?chanel回調(diào) 4.提供對外函數(shù)--增加正在執(zhí)行動(dòng)畫的數(shù)量---number

containnerView:0.當(dāng)執(zhí)行chanel回調(diào)-檢測多模型緩存--數(shù)量和類型--如果有就賦值數(shù)量和第一個(gè)模型--執(zhí)行動(dòng)畫 ?1.提供對外插入模型方法:1.1檢測是否和正在執(zhí)行的相同--如果有增加chinel緩存數(shù)量--沒有執(zhí)行1.2 ? 1.2檢測是否有空通道有就直接賦值執(zhí)行動(dòng)畫---沒有執(zhí)行1.3 ?1.3前兩部沒有加入到 模型緩存中

try處理

return try! userInfo.build()

userInfo.build()返回值中有throw? 需要進(jìn)行 try!處理

0.層級 關(guān)系 view? containView? channelView digitalview HYGiftModel

view: 只傳入model就可以

containView: 1.判斷是否有閑置通道 ?2.是否禮物模型相同 3.單通道的緩存數(shù)量

channelView: 對單個(gè)禮物的狀態(tài) ?和 緩存數(shù)量的執(zhí)行 和 給模型賦值后執(zhí)行動(dòng)畫

HYGiftModel: 判斷禮物是否相同(重寫isEqual 根據(jù)giftname 和發(fā)送者name )

1.HYDigitLabel ?

1.0畫出數(shù)字text ? 1.1設(shè)置開始動(dòng)畫方法----結(jié)束并且有回調(diào)

func startScaleAnimating(_ complection : (() -> Void)? = nil) {

UIView.animateKeyframes(withDuration: 1, delay: 0, options: [], animations: {

UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.4, animations: {

self.transform = CGAffineTransform(scaleX: 3.0, y: 3.0)

})

UIView.addKeyframe(withRelativeStartTime: 0.4, relativeDuration: 0.8, animations: {

self.transform = CGAffineTransform(scaleX: 0.7, y: 0.7)

})

UIView.addKeyframe(withRelativeStartTime: 0.8, relativeDuration: 1, animations: {

self.transform = CGAffineTransform.identity

})

}) { (_) in

complection?()

}

}

2.HYGiftChannelView ?通道view

class HYGiftChannelView: UIView {

// MARK: 控件屬性

@IBOutlet weak var bgView: UIView!

@IBOutlet weak var iconImageView: UIImageView!

@IBOutlet weak var senderLabel: UILabel!

@IBOutlet weak var giftDescLabel: UILabel!

@IBOutlet weak var giftImageView: UIImageView!

@IBOutlet weak var digitLabel: HYDigitLabel!

// MARK: 定義屬性

var finishedCallback : ((HYGiftChannelView) -> Void)?

var state : ChannerlViewState = .idle

var cacheNumber : Int = 0

fileprivate var currentNumber : Int = 0

var giftModel : HYGiftModel?? {

didSet {

// 1.校驗(yàn)?zāi)P褪欠裼兄?/p>

guard let giftModel = giftModel else {

return

}

// 2.將giftModel中屬性設(shè)置到控件中

iconImageView.image = UIImage(named: giftModel.senderIcon)

senderLabel.text = giftModel.senderName

giftDescLabel.text = "送出禮物【\(giftModel.giftName)"

giftImageView.image = UIImage(named: giftModel.giftIcon)

// 3.將channelView展示出來

performShowAnimating()

}

}

}

enum ChannerlViewState {

case idle ?閑置

case animating ?正在執(zhí)行

case endWating 等待結(jié)束

case ending 結(jié)束

}

2.1

fileprivate func performShowAnimating() {

狀態(tài)改變

state = .animating

UIView.animate(withDuration: 0.25, animations: {

self.frame.origin.x = 0

self.alpha = 1.0

}) { (_) in

橫條停到位置后----開始執(zhí)行數(shù)字彈跳動(dòng)畫

self.performDigitAnimating()

}}

數(shù)字彈跳動(dòng)畫

fileprivate func performDigitAnimating() {

// 1.將digitLabel的alpha值設(shè)置為1

digitLabel.alpha = 1

// 2.設(shè)置digitLabel上面顯示的數(shù)字

currentNumber += 1

digitLabel.text = " x\(currentNumber)"

// 3.執(zhí)行動(dòng)畫

digitLabel.startScaleAnimating {

if self.cacheNumber > 0 {

self.cacheNumber -= 1

self.performDigitAnimating()

相當(dāng)于遞歸執(zhí)行 直到self.cacheNumber = 0

} else {

如果沒有self.cacheNumber 狀態(tài)就改變

self.state = .endWating

等待執(zhí)行結(jié)束動(dòng)畫

self.perform(#selector(self.performEndAnimating), with: nil, afterDelay: 3.0)

}

}

@objc fileprivate func performEndAnimating() {

狀態(tài)改變--正在結(jié)束 ?往右走的過程

self.state = .ending

UIView.animate(withDuration: 1, animations: {

self.frame.origin.x = UIScreen.main.bounds.width

}) { (_) in

self.alpha = 0.0

self.state = .idle

self.digitLabel.alpha = 0

self.currentNumber = 0

self.cacheNumber = 0

self.frame.origin.x = -self.frame.width

self.giftModel = nil

結(jié)束完成通知控制器,看是否還有任務(wù)需要執(zhí)行

self.finishedCallback?(self)

}

}

// MARK:- 對外提供的函數(shù)---對單一通道的處理

extension HYGiftChannelView {

func addOnceToCache() {

若果正在等待結(jié)束----讓其取消等待--立即執(zhí)行-改變狀態(tài)

if state == .endWating {

NSObject.cancelPreviousPerformRequests(withTarget: self)

self.state = .animating

performDigitAnimating()

} else {

其他情況就讓其緩存+1

cacheNumber += 1

}

}

}

對containView處理

extension HYGiftContainerView {

fileprivate func setupUI() {

// 1.根據(jù)當(dāng)前的渠道數(shù),創(chuàng)建HYGiftChannelView

let w : CGFloat = frame.width

let h : CGFloat = 40

let x : CGFloat = -w

for i in 0..<2 {

let y : CGFloat = (h + 10) * CGFloat(i)

let channelView = HYGiftChannelView.loadChannelView()

channelView.frame = CGRect(x: x, y: y, width: w, height: h)

channelView.alpha = 0.0

addSubview(channelView)

channelViews.append(channelView)

channelView.finishedCallback = {[unowned self] (channelView) in

// 1.檢查緩存中是否有內(nèi)容

guard self.cacheGiftModels.count != 0 else {

return

}

// 2.取出模型

let firstGiftModel = self.cacheGiftModels.first!

self.cacheGiftModels.removeFirst()

// 3.取出和giftModel相同模型的個(gè)數(shù)

var cacheNumber = 0

for i in (0..<self.cacheGiftModels.count).reversed() {

if self.cacheGiftModels[i].isEqual(firstGiftModel) {

cacheNumber += 1

self.cacheGiftModels.remove(at: i)

}

}

// 4.讓閑置的channelView執(zhí)行緩存中禮物模型的動(dòng)畫

channelView.cacheNumber = cacheNumber

channelView.giftModel = firstGiftModel

}

}

}

}

對外提供的函數(shù)--如何調(diào)用

extension HYGiftContainerView {

func insertGiftModel(_ giftModel : HYGiftModel) {

// 1.判斷是否有正在執(zhí)行動(dòng)畫的渠道的模型和新插入的模型一致

if let channelView = checkModelInChannerView(giftModel) {

channelView.addOnceToCache()

return

}

// 2.有沒有閑置的channelView可以用于展示的禮物

if let channelView = checkIdleChannelView() {

channelView.giftModel = giftModel

return

}

// 3.將模型添加到緩存中

cacheGiftModels.append(giftModel)

}

fileprivate func checkModelInChannerView(_ newGiftModel : HYGiftModel) -> HYGiftChannelView? {

// return channelViews.filter({ newGiftModel.isEqual($0.giftModel) }).first

for channelView in channelViews {

if newGiftModel.isEqual(channelView.giftModel) && channelView.state != .ending {

return channelView

}

}

return nil

}

fileprivate func checkIdleChannelView() -> HYGiftChannelView? {

// return channelViews.filter({ $0.state == .idle }).first

for channelView in channelViews {

if channelView.state == .idle {

return channelView

}

}

return nil

}

}

模型的處理

class HYGiftModel : NSObject {

var senderName : String = ""

var senderIcon : String = ""

var giftIcon : String = ""

var giftName : String = ""

init(senderName : String, senderIcon : String, giftIcon : String, giftName : String) {

self.senderName = senderName

self.senderIcon = senderIcon

self.giftIcon = giftIcon

self.giftName = giftName

}

override func isEqual(_ object: Any?) -> Bool {

// 1.判斷傳入的內(nèi)容是否有值

guard let object = object as? HYGiftModel else {

return false

}

// 2.判斷贈(zèng)送者和贈(zèng)送的禮物名稱是否相同

return object.senderName == senderName && object.giftName == giftName

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容