我在iOS8中有一个像这样的表格视图:
tableView = UITableView(frame: view.bounds, style: .Plain)
view.addSubview(tableView)
当用户在键盘中键入并发送一些文本时,应用程序会调用以下方法来滚动tableView。目标是在屏幕上查看新文本(如聊天)
let numberOfRows = tableView.numberOfRowsInSection(0)
if numberOfRows > 0 {
let indexPath = NSIndexPath(forRow: numberOfRows-1, inSection: 0)
tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
}
但表视图不会滚动到bootom。
有人有解决方案吗?
谢谢。
说明:
班级定义:
class ChatViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextViewDelegate
然后我有了表视图的定义:
var tableView: UITableView!
在viewDidLoad中:
tableView = UITableView(frame: view.bounds, style: .Plain)
tableView.dataSource = self
tableView.delegate = self
view.addSubview(tableView)
然后我调用了应该进行滚动的代码(我的答案中的第二个代码块)。 当我启动应用程序时,我希望tableview向下滚动,但它不起作用。
答案 0 :(得分:75)
以下解决方案对我有用。它是StackOverflow上的解决方案组合。经过短暂的延迟,我打电话给“scrollToRowAtIndexPath
”。
func tableViewScrollToBottom(animated: Bool) {
let delay = 0.1 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), {
let numberOfSections = self.tableView.numberOfSections()
let numberOfRows = self.tableView.numberOfRowsInSection(numberOfSections-1)
if numberOfRows > 0 {
let indexPath = NSIndexPath(forRow: numberOfRows-1, inSection: (numberOfSections-1))
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
}
})
}
呼叫:
tableViewScrollToBottom(true)
Swift 3
func tableViewScrollToBottom(animated: Bool) {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
let numberOfSections = self.tableView.numberOfSections
let numberOfRows = self.tableView.numberOfRows(inSection: numberOfSections-1)
if numberOfRows > 0 {
let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
self.tableView.scrollToRow(at: indexPath, at: .bottom, animated: animated)
}
}
}
答案 1 :(得分:9)
我的问题的解决方案是:
let numberOfSections = tableView.numberOfSections()
let numberOfRows = tableView.numberOfRowsInSection(numberOfSections-1)
if numberOfRows > 0 {
println(numberOfSections)
let indexPath = NSIndexPath(forRow: numberOfRows-1, inSection: (numberOfSections-1))
tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
}
答案 2 :(得分:7)
在调用scroll之前先尝试重新加载。很受欢迎,但适用于iOS8。
tableView.reloadData()
tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
答案 3 :(得分:6)
@ Fox5150的SWIFT 3版本答案,附带扩展名:
extension UITableView {
func tableViewScrollToBottom(animated: Bool) {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
let numberOfSections = self.numberOfSections
let numberOfRows = self.numberOfRows(inSection: numberOfSections-1)
if numberOfRows > 0 {
let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
self.scrollToRow(at: indexPath, at: UITableViewScrollPosition.bottom, animated: animated)
}
}
}
}
<强> USAGE:强>
self.tableView.tableViewScrollToBottom(animated: true)
答案 4 :(得分:2)
我有一个更大的索引的问题,甚至是15.只有5-6的索引才能使用。通过制作“animated:false”,scrollToRowAtIndexPath()完美地运作。
答案 5 :(得分:1)
更好的解决方案是颠倒tableView,以便您可以显示新消息
-insertRowsAtIndexPaths:withRowAnimation:
要做到这一点,你需要先通过以下方式翻转你的桌子:
_tableView.transform = CGAffineTransformMakeScale (1,-1);
然后不要忘记翻转你的细胞,通过子类化在-awakeFromNib中做到最好的地方:
- (void)awakeFromNib {
[super awakeFromNib];
self.contentView.transform = CGAffineTransformMakeScale (1,-1);
//if you have accessoryView
self.accessoryView.transform = CGAffineTransformMakeScale (1,-1);
}
答案 6 :(得分:1)
尝试以下方法:
if tableView.numberOfRows(inSection: 0) > 0 {
tableView.scrollToRow(at: IndexPath(row: ROW, section: SECTION), at: .top, animated: false)
}
答案 7 :(得分:0)
如果键盘仍然可见,则必须设置UITableView
的{{1}}属性以补偿屏幕底部的键盘高度。否则您的单元格可能隐藏在键盘后面,因为contentInset
并不知道其中一半内容被隐藏。
或使用自动处理的UITableView
。
答案 8 :(得分:0)
在加载tableview之后调用scrollToLastPosition()方法,如从viewWillAppear()调用或在表视图重新加载后将某些内容更改为tableview
func scrollToLastPosition() {
if !message.isEmpty {
let indexpath = NSIndexPath(forRow: message.count - 1 , inSection: 0)
self.tableView.scrollToRowAtIndexPath(indexpath, atScrollPosition: .Bottom, animated: true)
}
}
答案 9 :(得分:0)
Heres Swift 3版
let numberOfSections = self.tableView.numberOfSections
let numberOfRows = self.tableView.numberOfRows(inSection: numberOfSections-1)
if numberOfRows > 0 {
let indexPath = NSIndexPath.init(row: numberOfRows-1, section: numberOfSections-1)
self.tableView.scrollToRow(at: indexPath as IndexPath, at: UITableViewScrollPosition.bottom, animated: animated)
}
答案 10 :(得分:0)
// First figure out how many sections there are
let lastSectionIndex = self.tblTableView!.numberOfSections() - 1
// Then grab the number of rows in the last section
let lastRowIndex =
self.tblTableView!.numberOfRowsInSection(lastSectionIndex) - 1
// Now just construct the index path
let pathToLastRow = NSIndexPath(forRow: lastRowIndex, inSection: lastSectionIndex)
// Make the last row visible
self.tblTableView?.scrollToRowAtIndexPath(pathToLastRow, atScrollPosition: UITableViewScrollPosition.None, animated: true)
答案 11 :(得分:0)
很简单。只需在 viewDidLayoutSubViews()
中进行滚动操作即可override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.scrollToBottom(animated: false)
}
fileprivate func scrollToBottom(animated: Bool) {
if self.items.count > 0 {
let lastIndex = IndexPath(row: items.count - 1, section: 1)
self.tableView.scrollToRow(at: lastIndex, at: .bottom, animated: animated)
}
}
看似tableview可以在布局子视图后获得正确的位置。
答案 12 :(得分:0)
我知道这是一个较旧的线程,但是仍然有用。除了处理有时可能无法及时安排的超时外,还可以在主线程上使用同步块(通常不是我愿意做的事,但是我们讲的是毫秒):
def __str__(self):
return '{}-{}'.format(self.industry, self.get_risk_display())
这总是对我有用。
答案 13 :(得分:0)
我通过在`viewWillLayoutSubviews()中调用scrollToRow()
解决了该问题
答案 14 :(得分:0)
我在2020年末遇到同样的问题。
由于我真的不想要一些不可思议的调度超时,所以我玩了一些。帮助(并且在此之前未提及)的是UITableView的强制布局:
_viewTable.layoutIfNeeded()
_viewTable.scrollToRow(at:IndexPath(row:index, section:0), at:.middle, animated:false)
答案 15 :(得分:-1)
以上所有代码都可以,但在我的情况下,我想加载tableView
以及当时立即滚动到tableView
的底部控制器加载,对于上述情况,上述方法需要一些时间才能滚动到tableView
的底部。所以我遵循了这些代码。
覆盖tableView
重新加载为
extension UITableView
{
func reloadData(completion: @escaping ()->()) {
UIView.animate(withDuration: 0, animations: { self.reloadData() })
{ _ in completion() }
}
}
写入滚动到底部的方法如下:
func tableViewScrollToBottom
{
if self.tblChat.contentSize.height > self.tblChat.frame.size.height
{
let offset:CGPoint = CGPoint(x: 0,y :self.tblChat.contentSize.height-self.tblChat.frame.size.height)
self.tblChat.setContentOffset(offset, animated: false)
}
}
然后在从Web服务或任何核心数据实体加载数据时重新加载tableView
:
tblChat.reloadData()
{
self.tableViewScrollToBottom
}
现在我的工作顺利进行。