我有一个类似于聊天应用程序的UI,我需要以气泡的形式显示消息(UILabels)。我使用了UITableView,其中包含一个包含标签的自定义单元格。
示例:假设我最初有3条消息。
Hi
How are you?
What can I do for you?
我希望3个细胞一个接一个地出现,有一些延迟,以便获得类似体验的聊天。 我已经尝试了dispatch_after并且在块中我有
[tableView insertRowsAtIndexPath: withAnimation:]
但是这会一共插入3行,没有任何延迟。 有人可以帮忙吗?
答案 0 :(得分:1)
您的要求类似于聊天应用程序,它会在消息中显示消息。
现有演示,您可以轻松下载和配置。从头开始创建后无需花时间。
https://github.com/tkirby/BubbleThingie
https://mobiforge.com/design-development/sms-bubble-ui-iphone-apps
答案 1 :(得分:0)
这应该可以,但你必须添加更新和主队列。
[tableView beginUpdates]
[tableView insertRowsAtIndexPath: withAnimation:]
[tableView endUpdates]
要对主线程执行操作
dispatch_async(dispatch_get_main_queue(), {() -> Void in
})
答案 2 :(得分:0)
您也可以一次插入所有这些行,并将alpha = 0设置为带文本的UILabels。 然后你可以使用几个连续的[UIView animateWithDuration]来将alpha设置为1 - 并且会出现标签。
答案 3 :(得分:0)
import Foundation
import UIKit
import QuartzCore
import AVFoundation
class ChatPracticeVC: UIViewController ,UITableViewDelegate, UITableViewDataSource {
//MARK: Properties
var tableView: UITableView!
var items = [Messages]()
var names = ["item1", "item2", "item3, "item4"] // ... you can add as many names as you want
var directions = ["right", "left", "right", "right"]
let barHeight: CGFloat = 50
var timer: DispatchSourceTimer!
var continueButt:UIButton!
var showContinueButt = true
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView(frame:CGRect.zero)
tableView.dataSource = self
tableView.delegate = self
self.view.addSubview(tableView)
self.tableView.separatorStyle = .none
self.customization()
}
override func viewWillAppear(_ animated: Bool) {
tableView.register(UINib(nibName: "ReceiverCell", bundle: nil), forCellReuseIdentifier: "receiverCell")
tableView.register(UINib(nibName: "SenderCell", bundle: nil), forCellReuseIdentifier: "senderCell")
}
override func viewWillLayoutSubviews() {
let height: CGFloat = 66
tableView.frame = CGRect(x: 0, y: (self.navigationController?.navigationBar.frame.height)!, width: view.bounds.size.width, height: view.bounds.size.height - height - 1.0)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
self.insertItem(index: 0)
DispatchQueue.main.asyncAfter(deadline: .now() + 4) { // change 2 to desired number of seconds
self.insertTimer(i: 1)
}
}
func insertItem(index:Int){
self.items.append(Messages(message: (self.names[index]), position: (self.directions[index])))
CATransaction.begin()
self.tableView.beginUpdates()
let lines = self.names[index].components(separatedBy: .newlines)
let indexPath:IndexPath = IndexPath(row:(self.items.count - 1), section:0)
CATransaction.setCompletionBlock {
//you can insert animation code here on loading of cell
}
CATransaction.commit()
self.tableView.insertRows(at: [indexPath], with: .bottom)
self.tableView.endUpdates()
self.tableView.scrollToRow(at: indexPath, at: .bottom, animated: false)
}
func delay(_ delay:Double, closure:@escaping ()->()) {
DispatchQueue.main.asyncAfter(
deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
}
func insertTimer(i :Int){
var index = i
timer = DispatchSource.makeTimerSource(queue: .main)
timer.schedule(deadline: .now(), repeating: .seconds(4))
timer.setEventHandler { [weak self] in
self?.insertItem(index: index)
index = index.advanced(by: 1)
if index == self?.names.endIndex {
if(self?.names.count == 13){
self?.continueButt.setTitle("Finish", for: .normal)
}
self?.timer.cancel()
self?.showAndHideBottomBar()
}
}
timer.resume()
}
//MARK: Methods
func customization() {
self.tableView.estimatedRowHeight = self.barHeight
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.contentInset.bottom = self.barHeight
self.tableView.scrollIndicatorInsets.bottom = self.barHeight
continueButt = UIButton(type: .custom)
self.view.addSubview(continueButt)
continueButt = UIButton(frame: CGRect(x:0, y:0, width:self.view.bounds.width, height:50))
continueButt.backgroundColor = UIColor(red: 0, green: 185/255, blue: 210/255, alpha: 1)
continueButt.setTitle("CONTINUE", for: .normal)
continueButt.frame.origin = CGPoint(x:0, y:self.view.frame.size.height - continueButt.frame.size.height)
continueButt.addTarget(self, action: #selector(self.continueButtClicked), for: .touchUpInside)
self.view.addSubview(continueButt)
continueButt.layer.zPosition = .greatestFiniteMagnitude
showAndHideBottomBar()
}
//Hides current viewcontroller
@objc func dismissSelf() {
if let navController = self.navigationController {
navController.popToRootViewController(animated: true)
}
}
@objc func continueButtClicked(_ sender: UIButton) {
view.endEditing(true)
showAndHideBottomBar()
if(sender.titleLabel?.text == "Finish"){
self.navigationController?.pushViewController(FinishVC(), animated: true)
}
if(names.count == 4){
let i = names.count
names.append("item5")
names.append("item6")
names.append("item7")
names.append("item8")
directions.append("left")
directions.append("right")
directions.append("left")
directions.append("right")
self.insertTimer(i: i )
}
else if(names.count == 8){
let i = names.count
names.append("item9")
names.append("item10")
directions.append("right")
directions.append("left")
self.insertTimer(i: i )
}
else if(names.count == 10){
let i = names.count
names.append("item11")
names.append("item12")
names.append("item13")
directions.append("right")
directions.append("right")
directions.append("left")
self.insertTimer(i: i )
}
}
//MARK: Delegates
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let temp:UITableViewCell = UITableViewCell()
switch self.items[indexPath.row].position {
case "right":
let cell = tableView.dequeueReusableCell(withIdentifier: "receiverCell", for: indexPath) as! ReceiverCell
cell.clearCellData()
cell.profilePic.image = UIImage(named:"user.png")
cell.message.text = self.items[indexPath.row].message
return cell
case "left":
let cell = tableView.dequeueReusableCell(withIdentifier: "senderCell", for: indexPath) as! SenderCell
cell.clearCellData()
cell.profilePic.image = UIImage(named:"user.png")
cell.message.text = self.items[indexPath.row].message
return cell
default:
return temp
}
}
func showAndHideBottomBar() {
if showContinueButt == false {
self.continueButt.alpha = 0.0
self.continueButt.isHidden = false
self.showContinueButt = true
UIView.animate(withDuration: 0.6, delay: 0, options: .curveEaseInOut, animations: {
self.continueButt.alpha = 1.0
}) { (isCompleted) in
}
} else{
UIView.animate(withDuration: 0.6, delay: 0, options: .curveEaseInOut, animations: {
self.continueButt.alpha = 0.0
}) { (isCompleted) in
self.continueButt.isHidden = true
self.showContinueButt = false
}
}
}
}
在这里,我使用计时器在数组中插入项目,然后将其插入表视图(检查方法insertItem和insertTimer),从而产生加载延迟效果 此示例应模仿您的聊天要求