보기가 표시되기 전에 iPhone에서 UITableView의 맨 아래까지 스크롤하는 방법
는 나나 a a a가 있다UITableView
하다뷰에 밀어넣을 때 테이블이 아래로 스크롤되도록 하고 싶습니다.
저는 현재 다음과 같은 기능을 가지고 있습니다.
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[log count]-1 inSection:0];
[self.table scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
log는 각 셀의 내용을 구성하는 개체를 포함하는 가변 배열입니다.
위의 코드는 에서 정상적으로 동작합니다.viewDidAppear
그러나 뷰가 처음 나타날 때 테이블 상단이 표시되고 다음으로 아래로 점프하는 안타까운 부작용이 있습니다.table view
표시되기 전에 아래로 스크롤할 수 있습니다.
나는 스크롤을 시도했다.viewWillAppear
★★★★★★★★★★★★★★★★★」viewDidLoad
그러나 두 경우 모두 아직 데이터가 테이블에 로드되지 않았으며 둘 다 예외를 발생시킵니다.
제가 가지고 있는 것이 가능한 전부라고 하는 경우라도, 어떤 지도라도 감사하게 생각합니다.
나는 그 소명이
tableView.setContentOffset(CGPoint(x: 0, y: CGFloat.greatestFiniteMagnitude), animated: false)
네가 원하는 걸 할 거야
가장 쉬운 방법은 다음과 같습니다.
if (self.messages.count > 0)
{
[self.tableView
scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.messages.count-1
inSection:0]
atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
Swift 3 버전:
if messages.count > 0 {
userDefinedOptionsTableView.scrollToRow(at: IndexPath(item:messages.count-1, section: 0), at: .bottom, animated: true)
}
제이콥의 대답에 따르면, 암호는 다음과 같습니다.
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (self.messagesTableView.contentSize.height > self.messagesTableView.frame.size.height)
{
CGPoint offset = CGPointMake(0, self.messagesTableView.contentSize.height - self.messagesTableView.frame.size.height);
[self.messagesTableView setContentOffset:offset animated:YES];
}
}
내용의 정확한 끝까지 스크롤해야 하는 경우 다음과 같이 스크롤할 수 있습니다.
- (void)scrollToBottom
{
CGFloat yOffset = 0;
if (self.tableView.contentSize.height > self.tableView.bounds.size.height) {
yOffset = self.tableView.contentSize.height - self.tableView.bounds.size.height;
}
[self.tableView setContentOffset:CGPointMake(0, yOffset) animated:NO];
}
오토레이아웃을 사용 중인데 아무 답변도 안 들어왔어요.마지막으로 성공한 솔루션은 다음과 같습니다.
@property (nonatomic, assign) BOOL shouldScrollToLastRow;
- (void)viewDidLoad {
[super viewDidLoad];
_shouldScrollToLastRow = YES;
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// Scroll table view to the last row
if (_shouldScrollToLastRow)
{
_shouldScrollToLastRow = NO;
[self.tableView setContentOffset:CGPointMake(0, CGFLOAT_MAX)];
}
}
Swift 2.0 0 2음음0000000000000 。은 '이러다'를 '이러다'라고 .tableview
import UIKit
extension UITableView {
func setOffsetToBottom(animated: Bool) {
self.setContentOffset(CGPointMake(0, self.contentSize.height - self.frame.size.height), animated: true)
}
func scrollToLastRow(animated: Bool) {
if self.numberOfRowsInSection(0) > 0 {
self.scrollToRowAtIndexPath(NSIndexPath(forRow: self.numberOfRowsInSection(0) - 1, inSection: 0), atScrollPosition: .Bottom, animated: animated)
}
}
}
@JacobRelkin이 승인한 솔루션은 iOS 7.0에서 자동 레이아웃을 사용하는 경우 작동하지 않았습니다.
는 커커classclassclassclassclassclassclassclassclassclass라는 관습적인 .UIViewController
변수를 했습니다._tableView
의 of as as of 의 view
를 정했습니다._tableView
이치노.viewDidLoad
에에 in in에서도viewWillAppear:
다
제가 을 추가했습니다.UIViewController
.
- (void)tableViewScrollToBottomAnimated:(BOOL)animated {
NSInteger numberOfRows = [_tableView numberOfRowsInSection:0];
if (numberOfRows) {
[_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:numberOfRows-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:animated];
}
}
" "[self tableViewScrollToBottomAnimated:NO]
viewDidLoad
가 있다.은 또한 이 된다.tableView:heightForRowAtIndexPath:
3번으로 나누다
실제로 이를 신속하게 수행하는 "Swifter" 방법은 다음과 같습니다.
var lastIndex = NSIndexPath(forRow: self.messages.count - 1, inSection: 0)
self.messageTableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Bottom, animated: true)
나에게 딱 맞는 일.
세부 사항
- Xcode 8.3.2, swift 3.1
- Xcode 10.2 (10E125), Swift 5
코드
import UIKit
extension UITableView {
func scrollToBottom(animated: Bool) {
let y = contentSize.height - frame.size.height
if y < 0 { return }
setContentOffset(CGPoint(x: 0, y: y), animated: animated)
}
}
사용.
tableView.scrollToBottom(animated: true)
풀샘플
솔루션 코드 붙여넣기 잊지 마세요!
import UIKit
class ViewController: UIViewController {
private weak var tableView: UITableView?
private lazy var cellReuseIdentifier = "CellReuseIdentifier"
override func viewDidLoad() {
super.viewDidLoad()
let tableView = UITableView(frame: view.frame)
view.addSubview(tableView)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
self.tableView = tableView
tableView.dataSource = self
tableView.performBatchUpdates(nil) { [weak self] result in
if result { self?.tableView?.scrollToBottom(animated: true) }
}
}
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath )
cell.textLabel?.text = "\(indexPath)"
return cell
}
}
테이블이 프레임에 표시된 테이블 끝에 장착되기를 원했습니다.를 사용하고 있는 것을 알았습니다.
NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([self.tableView numberOfRowsInSection:0] - 1) inSection:0];
[[self tableView] scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
테이블 높이가 프레임 높이보다 작을 때 오류가 발생했기 때문에 작동하지 않았습니다.내 테이블에는 섹션이 하나뿐입니다.
이 솔루션은 다음 코드를 viewWillApper에 구현했습니다.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// on the initial cell load scroll to the last row (ie the latest Note)
if (initialLoad==TRUE) {
initialLoad=FALSE;
NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([self.tableView numberOfRowsInSection:0] - 1) inSection:0];
[[self tableView] scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
CGPoint offset = CGPointMake(0, (1000000.0));
[self.tableView setContentOffset:offset animated:NO];
}
}
boOL ivar initial Load는 viewDidLoad에서 TRUE로 설정됩니다.
Swift의 경우:
if tableView.contentSize.height > tableView.frame.size.height {
let offset = CGPoint(x: 0, y: tableView.contentSize.height - tableView.frame.size.height)
tableView.setContentOffset(offset, animated: false)
}
하면 됩니다.UITableViewScrollPositionBottom
★★★★★★ 。
Swift 3(Xcode 8.1)의 경우:
override func viewDidAppear(_ animated: Bool) {
let numberOfSections = self.tableView.numberOfSections
let numberOfRows = self.tableView.numberOfRows(inSection: numberOfSections-1)
let indexPath = IndexPath(row: numberOfRows-1 , section: numberOfSections-1)
self.tableView.scrollToRow(at: indexPath, at: UITableViewScrollPosition.middle, animated: true)
}
당연히 벌레죠. 내 하고 있을 이 있습니다.table.estimatedRowHeight = value
(예를 들어 100).이 값을 행 높이에서 얻을 수 있다고 생각하는 가장 높은 값(예: 500)으로 바꿉니다.그러면 다음 코드와 함께 문제가 해결됩니다.
//auto scroll down example
let delay = 0.1 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), {
self.table.scrollToRowAtIndexPath(NSIndexPath(forRow: self.Messages.count - 1, inSection: 0), atScrollPosition: UITableViewScrollPosition.Bottom, animated: false)
})
여러 번 만지작거린 끝에 나는 이렇게 되었다.
var viewHasAppeared = false
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if !viewHasAppeared { goToBottom() }
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
viewHasAppeared = true
}
private func goToBottom() {
guard data.count > 0 else { return }
let indexPath = NSIndexPath(forRow: data.count - 1, inSection: 0)
tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: false)
tableView.layoutIfNeeded()
}
열쇠가 포장되어 있지 않은 것으로 판명되었다.scrollToRowAtIndexPath
의 of의 dispatch_async
제안했듯이 콜을 만으로, 「」을 호출할 수 있습니다.layoutIfNeeded
.
현재 스레드에서 스크롤 메서드를 호출하면 보기가 표시되기 전에 스크롤 오프셋을 즉시 설정할 수 있습니다.메인 스레드에 디스패치 했을 때, 스크롤이 유효하게 되기 전에 뷰가 잠시 표시되고 있었습니다.
는 ('NB)viewHasAppeared
.goToBottom
viewDidLayoutSubviews
이 바뀔 .)예를 들어 방향이 바뀔 때마다 호출됩니다.)
func scrollToBottom() {
let sections = self.chatTableView.numberOfSections
if sections > 0 {
let rows = self.chatTableView.numberOfRows(inSection: sections - 1)
let last = IndexPath(row: rows - 1, section: sections - 1)
DispatchQueue.main.async {
self.chatTableView.scrollToRow(at: last, at: .bottom, animated: false)
}
}
}
추가해야 합니다.
DispatchQueue.main.async {
self.chatTableView.scrollToRow(at: last, at: .bottom, animated: false)
}
그렇지 않으면 아래로 스크롤되지 않습니다.
한 줄:
tableView.scrollToRow(at: IndexPath(row: data.count - 1, section: 0), at: .bottom, animated: true)
이 코드는 승인된 답변보다 IMHO가 더 명확합니다.
위의 솔루션을 사용하면 테이블 맨 아래로 스크롤됩니다(테이블의 내용이 먼저 로드된 경우에만).
//Scroll to bottom of table
CGSize tableSize = myTableView.contentSize;
[myTableView setContentOffset:CGPointMake(0, tableSize.height)];
Swift 3.0의 경우
self.tableViewFeeds.setContentOffset(CGPoint(x: 0, y: CGFLOAT_MAX), animated: true)
이 간단한 코드를 사용하여 테이블을 스크롤합니다.아래쪽 보기
NSInteger rows = [tableName numberOfRowsInSection:0];
if(rows > 0) {
[tableName scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:rows-1 inSection:0]
atScrollPosition:UITableViewScrollPositionBottom
animated:YES];
}
아래로 스크롤하기 전에 데이터를 비동기적으로 로드해야 하는 경우 가능한 해결 방법은 다음과 같습니다.
tableView.alpha = 0 // We want animation!
lastMessageShown = false // This is ivar
viewModel.fetch { [unowned self] result in
self.tableView.reloadData()
if !self.lastMessageShown {
dispatch_async(dispatch_get_main_queue()) { [unowned self] in
if self.rowCount > 0 {
self.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: self.rowCount, inSection: 0), atScrollPosition: .Bottom, animated: false)
}
UIView.animateWithDuration(0.1) {
self.tableView.alpha = 1
self.lastMessageShown = true // Do it once
}
}
}
}
3 스크롤을 아래로 빠르게 이동 시 기능
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(false)
//scroll down
if lists.count > 2 {
let numberOfSections = self.tableView.numberOfSections
let numberOfRows = self.tableView.numberOfRows(inSection: numberOfSections-1)
let indexPath = IndexPath(row: numberOfRows-1 , section: numberOfSections-1)
self.tableView.scrollToRow(at: indexPath, at: UITableViewScrollPosition.middle, animated: true)
}
}
제이콥에게 답변 감사합니다.모노터치 c# 버전에 관심 있는 사람이 있다면 정말 도움이 됩니다.
private void SetScrollPositionDown() {
if (tblShoppingListItem.ContentSize.Height > tblShoppingListItem.Frame.Size.Height) {
PointF offset = new PointF(0, tblShoppingListItem.ContentSize.Height - tblShoppingListItem.Frame.Size.Height);
tblShoppingListItem.SetContentOffset(offset,true );
}
}
iOS에서는 이 기능이 정상적으로 동작했습니다.
CGFloat height = self.inputTableView.contentSize.height;
if (height > CGRectGetHeight(self.inputTableView.frame)) {
height -= (CGRectGetHeight(self.inputTableView.frame) - CGRectGetHeight(self.navigationController.navigationBar.frame));
}
else {
height = 0;
}
[self.inputTableView setContentOffset:CGPointMake(0, height) animated:animated];
'아까부터'라고요.viewDidLayoutSubviews
[ self . table ]뷰정보 스크롤RectToVisible:CGRectMake(0, self.tableViewInfo.contentSize).high-self.tableViewInfo 를 지정합니다.높이, self.tableViewInfo.width, self.tableViewInfo.높이) 애니메이션:네];
승인된 답변은 테이블(수천 개의 행, 동적 로딩)에서 작동하지 않지만 아래 코드는 작동합니다.
- (void)scrollToBottom:(id)sender {
if ([self.sections count] > 0) {
NSInteger idx = [self.sections count] - 1;
CGRect sectionRect = [self.tableView rectForSection:idx];
sectionRect.size.height = self.tableView.frame.size.height;
[self.tableView scrollRectToVisible:sectionRect animated:NO];
}
}
스크롤은 필요 없습니다.다음 코드를 사용하면 됩니다.
[YOURTABLEVIEWNAME setContentOffset:CGPointMake(0, CGFLOAT_MAX)];
테이블 뷰용으로 프레임을 프로그래밍 방식으로 설정하는 경우 프레임을 올바르게 설정하고 있는지 확인합니다.
iOS 12에서는 승인된 답변이 깨진 것 같습니다.아래 내선번호로 작동하였습니다.
import UIKit
extension UITableView {
public func scrollToBottom(animated: Bool = true) {
guard let dataSource = dataSource else {
return
}
let sections = dataSource.numberOfSections?(in: self) ?? 1
let rows = dataSource.tableView(self, numberOfRowsInSection: sections-1)
let bottomIndex = IndexPath(item: rows - 1, section: sections - 1)
scrollToRow(at: bottomIndex,
at: .bottom,
animated: animated)
}
}
swift 3.0에서 테이블 뷰의 특정 셀로 이동하려면 셀 인덱스 값을 변경 "self"와 같이 변경하십시오.yourArr.count" 값.
self.yourTable.reloadData()
self.scrollToBottom()
func scrollToBottom(){
DispatchQueue.global(qos: .background).async {
let indexPath = IndexPath(row: self.yourArr.count-1, section: 0)
self.tblComment.scrollToRow(at: indexPath, at: .bottom, animated: true)
}
}
언급URL : https://stackoverflow.com/questions/2770158/how-to-scroll-to-the-bottom-of-a-uitableview-on-the-iphone-before-the-view-appea
'programing' 카테고리의 다른 글
applicationWillEnterForeground vs. applicationDidBecomeActive, applicationWillResignActive vs.applicationDidEnterBackground (0) | 2023.04.19 |
---|---|
채워진 행을 통해 반복 (0) | 2023.04.19 |
종속 속성에서 속성 변경 이벤트를 발생시키는 방법 (0) | 2023.04.14 |
중간 커밋 없이 두 커밋 간의 변화를 확인하는 방법은 무엇입니까? (0) | 2023.04.14 |
거북이SVN 아이콘이 Windows 7에 표시되지 않음 (0) | 2023.04.14 |