Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIScrollView以编程方式滚动到底部_Ios_Objective C_Swift_Uiscrollview - Fatal编程技术网

Ios UIScrollView以编程方式滚动到底部

Ios UIScrollView以编程方式滚动到底部,ios,objective-c,swift,uiscrollview,Ios,Objective C,Swift,Uiscrollview,如何使UIScrollView滚动到代码的底部?或者以更通用的方式,到子视图的任何点?您可以使用UIScrollView的setContentOffset:animated:功能滚动到内容视图的任何部分。假设您的scrollView是self.scrollView,下面是一些可以滚动到底部的代码: 目标C: CGPoint bottomOffset=CGPointMake(0,self.scrollView.contentSize.height-self.scrollView.bounds.si

如何使
UIScrollView
滚动到代码的底部?或者以更通用的方式,到子视图的任何点?

您可以使用UIScrollView的
setContentOffset:animated:
功能滚动到内容视图的任何部分。假设您的scrollView是
self.scrollView
,下面是一些可以滚动到底部的代码:

目标C:

CGPoint bottomOffset=CGPointMake(0,self.scrollView.contentSize.height-self.scrollView.bounds.size.height+self.scrollView.contentInset.bottom);
[self.scrollView setContentOffset:bottomOffset动画:是];
斯威夫特:

let bottomOffset=CGPoint(x:0,y:scrollView.contentSize.height-scrollView.bounds.height+scrollView.contentInset.bottom)
scrollView.setContentOffset(底部偏移,动画:true)

希望有帮助

在使用UITableview(UIScrollView的子类)的情况下,我还发现了另一种有用的方法:


在添加了
footerView
之后,当我尝试在
self.tableView
(iOS 4.1)
上的
UITableViewController
中使用它时,它对我不起作用。它滚动出边框,显示黑色屏幕

替代解决方案:

 CGFloat height = self.tableView.contentSize.height; 

 [self.tableView setTableFooterView: myFooterView];
 [self.tableView reloadData];

 CGFloat delta = self.tableView.contentSize.height - height;
 CGPoint offset = [self.tableView contentOffset];
 offset.y += delta;

 [self.tableView setContentOffset: offset animated: YES];

valdyr,希望这能帮助你:

CGPoint bottomOffset = CGPointMake(0, [textView contentSize].height - textView.frame.size.height);

if (bottomOffset.y > 0)
 [textView setContentOffset: bottomOffset animated: YES];

将内容偏移设置为内容大小的高度是错误的:它会将内容的底部滚动到滚动视图的顶部,因此看不见

正确的解决方案是将内容的底部滚动到滚动视图的底部,如下所示(
sv
是UIScrollView):

使用(可选)
footerView
contentInset
,解决方案是:

CGPoint bottomOffset = CGPointMake(0, _tableView.contentSize.height - tableView.frame.size.height + _tableView.contentInset.bottom);
if (bottomOffset.y > 0) [_tableView setContentOffset: bottomOffset animated: YES];
滚动到顶部

- CGPoint topOffset = CGPointMake(0, 0);
- [scrollView setContentOffset:topOffset animated:YES];
滚动到底部

- CGPoint bottomOffset = CGPointMake(0, scrollView.contentSize.height - self.scrollView.bounds.size.height);
 - [scrollView setContentOffset:bottomOffset animated:YES];

分类来营救

将其添加到某个共享实用程序标题:

@interface UIScrollView (ScrollToBottom)
- (void)scrollToBottomAnimated:(BOOL)animated;
@end
然后到该实用程序实现:

@implementation UIScrollView(ScrollToBottom)
- (void)scrollToBottomAnimated:(BOOL)animated
{
     CGPoint bottomOffset = CGPointMake(0, self.contentSize.height - self.bounds.size.height);
     [self setContentOffset:bottomOffset animated:animated];
}
@end
然后在您喜欢的任何地方实施它,例如:

[[myWebView scrollView] scrollToBottomAnimated:YES];

确保内容底部可见的一个好方法是使用以下公式:

contentOffsetY = MIN(0, contentHeight - boundsHeight)
这样可以确保内容的底边始终位于视图的底边或其上方。之所以需要
MIN(0,…)
,是因为
UITableView
(很可能是
UIScrollView
)确保了当用户试图通过可视抓取
contentOffsetY=0来滚动时
contentOffsetY>=0
。对于用户来说,这看起来很奇怪

实现这一点的代码是:

UIScrollView scrollView = ...;
CGSize contentSize = scrollView.contentSize;
CGSize boundsSize = scrollView.bounds.size;
if (contentSize.height > boundsSize.height)
{
    CGPoint contentOffset = scrollView.contentOffset;
    contentOffset.y = contentSize.height - boundsSize.height;
    [scrollView setContentOffset:contentOffset animated:YES];
}

只是对现有答案的改进

CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];

它还负责底部插图(如果您在键盘可见时使用底部插图调整滚动视图)

如果您不需要动画,则可以:

[self.scrollView setContentOffset:CGPointMake(0, CGFLOAT_MAX) animated:NO];
CGFloat yOffset=scrollView.contentOffset.y;
CGFloat height=scrollView.frame.size.height;
CGFloat contentHeight=scrollView.contentSize.height;
CGFloat距离=(contentHeight-height)-yOffset;
如果(距离<0)
{
返回;
}
CGPoint offset=scrollView.contentOffset;
偏移量y+=距离;
[滚动视图设置内容偏移:偏移动画:是];
最简单的解决方案:

[scrollview scrollRectToVisible:CGRectMake(scrollview.contentSize.width - 1,scrollview.contentSize.height - 1, 1, 1) animated:YES];

虽然
Matt
解决方案对我来说似乎是正确的,但如果已经设置了集合视图,则还需要考虑集合视图插图

调整后的代码将是:

CGSize csz = sv.contentSize;
CGSize bsz = sv.bounds.size;
NSInteger bottomInset = sv.contentInset.bottom;
if (sv.contentOffset.y + bsz.height + bottomInset > csz.height) {
    [sv setContentOffset:CGPointMake(sv.contentOffset.x, 
                                     csz.height - bsz.height + bottomInset) 
                animated:YES];
}

接受答案的Swift版本,便于复制粘贴:

let bottomOffset=CGPoint(x:0,y:scrollView.contentSize.height-scrollView.bounds.size.height)
scrollView.setContentOffset(底部偏移,动画:true)

我发现
contentSize
并不能真正反映文本的实际大小,因此在尝试滚动到底部时,会有一点偏离。确定实际内容大小的最佳方法实际上是使用
NSLayoutManager
usedRectForTextContainer:
方法:

UITextView *textView;
CGSize textSize = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size;
要确定
UITextView
中实际显示多少文本,可以通过从帧高度减去文本容器插入来计算

UITextView *textView;
UIEdgeInsets textInsets = textView.textContainerInset;
CGFloat textViewHeight = textView.frame.size.height - textInsets.top - textInsets.bottom;
然后就可以很容易地滚动:

// if you want scroll animation, use contentOffset
UITextView *textView;
textView.contentOffset = CGPointMake(textView.contentOffset.x, textSize - textViewHeight);

// if you don't want scroll animation
CGRect scrollBounds = textView.bounds;
scrollBounds.origin = CGPointMake(textView.contentOffset.x, textSize - textViewHeight);
textView.bounds = scrollBounds;
一些数字用于参考空
UITextView
的不同大小代表的内容

textView.frame.size = (width=246, height=50)
textSize = (width=10, height=16.701999999999998)
textView.contentSize = (width=246, height=33)
textView.textContainerInset = (top=8, left=0, bottom=8, right=0)
迅速:

   if self.mainScroll.contentSize.height > self.mainScroll.bounds.size.height {
        let bottomOffset = CGPointMake(0, self.mainScroll.contentSize.height - self.mainScroll.bounds.size.height);
        self.mainScroll.setContentOffset(bottomOffset, animated: true)
    }

使用UIScrollView的
setContentOffset:animated:
功能在Swift中滚动到底部

let bottomOffset : CGPoint = CGPointMake(0, scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)

如果
contentSize
低于
bounds
,该怎么办

对于Swift,它是:

scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)

快速实施:

extension UIScrollView {
   func scrollToBottom(animated: Bool) {
     if self.contentSize.height < self.bounds.size.height { return }
     let bottomOffset = CGPoint(x: 0, y: self.contentSize.height - self.bounds.size.height)
     self.setContentOffset(bottomOffset, animated: animated)
  }
}

Swift 2.2解决方案,考虑了
contentInset

let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
这应该是一个扩展

extension UIScrollView {

  func scrollToBottom() {
    let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
    setContentOffset(bottomOffset, animated: true)
  }
}

请注意,在滚动到表视图的最后一项之前,您可能需要检查
bottomOffset.y>0
解决方案:

Swift 3:

if self.items.count > 0 {
        self.tableView.scrollToRow(at:  IndexPath.init(row: self.items.count - 1, section: 0), at: UITableViewScrollPosition.bottom, animated: true)
}

Xamarin.iOS已接受答案的版本

var bottomOffset = new CGPoint (0,
     scrollView.ContentSize.Height - scrollView.Frame.Size.Height
     + scrollView.ContentInset.Bottom);

scrollView.SetContentOffset (bottomOffset, false);

Xamarin.iOS接受答案的
UICollectionView
版本,便于复制和粘贴

var bottomOffset = new CGPoint (0, CollectionView.ContentSize.Height - CollectionView.Frame.Size.Height + CollectionView.ContentInset.Bottom);          
CollectionView.SetContentOffset (bottomOffset, false);

用于水平滚动视图

如果您喜欢我的水平滚动视图,并希望滚动到其末尾(在我的情况下,滚动到最右边),则需要更改已接受答案的某些部分:

目标-C

CGPoint rightOffset = CGPointMake(self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, 0 );
[self.scrollView setContentOffset:rightOffset animated:YES];
Swift

let rightOffset:CGPoint=CGPoint(x:self.scrollView.contentSize.width-self.scrollView.bounds.size.width+self.scrollView.contentInset.right,y:0)
self.scrollView.setContentOffset(rightOffset,动画:true)

这里的所有答案似乎都没有考虑到安全区域。 自iOS 11以来,iPhoneX引入了一个安全区域。这可能会影响滚动视图的
contentInset

对于iOS 11及更高版本,请在包含内容插入的情况下正确滚动到底部。您应该使用
adjustedContentInset
而不是
contentInset
。检查此代码:

  • 斯威夫特:
let bottomOffset=CGPoint(x:0,y:scrollView.contentSize.height-scrollView.bounds.height+scrollView.adjustedContentInset.botto
if self.items.count > 0 {
        self.tableView.scrollToRow(at:  IndexPath.init(row: self.items.count - 1, section: 0), at: UITableViewScrollPosition.bottom, animated: true)
}
var bottomOffset = new CGPoint (0,
     scrollView.ContentSize.Height - scrollView.Frame.Size.Height
     + scrollView.ContentInset.Bottom);

scrollView.SetContentOffset (bottomOffset, false);
var bottomOffset = new CGPoint (0, CollectionView.ContentSize.Height - CollectionView.Frame.Size.Height + CollectionView.ContentInset.Bottom);          
CollectionView.SetContentOffset (bottomOffset, false);
CGPoint rightOffset = CGPointMake(self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, 0 );
[self.scrollView setContentOffset:rightOffset animated:YES];
scrollView.layoutIfNeeded()
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
if(bottomOffset.y > 0) {
    scrollView.setContentOffset(bottomOffset, animated: true)
}
extension UIScrollView {
    func scrollToBottom(animated:Bool) {
        let offset = self.contentSize.height - self.visibleSize.height
        if offset > self.contentOffset.y {
            self.setContentOffset(CGPoint(x: 0, y: offset), animated: animated)
        }
    }
}