Ios 如何使用contentOffset在UIScrollView中居中放置内容
这应该是一个很容易的问题,但我有困难得到想要的结果。我有宽度为320的水平滚动UIScrollView。其内容的宽度为5000。我正试图以以下内容为中心:Ios 如何使用contentOffset在UIScrollView中居中放置内容,ios,objective-c,uiscrollview,Ios,Objective C,Uiscrollview,这应该是一个很容易的问题,但我有困难得到想要的结果。我有宽度为320的水平滚动UIScrollView。其内容的宽度为5000。我正试图以以下内容为中心: // 'self' is the UIScrollView CGFloat newContentOffsetX = (self.width/2) + (self.contentSize.width/2); self.contentOffset = CGPointMake(newContentOffsetX, 0); 我不明白为什么这不是以内
// 'self' is the UIScrollView
CGFloat newContentOffsetX = (self.width/2) + (self.contentSize.width/2);
self.contentOffset = CGPointMake(newContentOffsetX, 0);
我不明白为什么这不是以内容为中心。你能看出计算有什么问题吗?我想你需要:
CGFloat newContentOffsetX = (self.contentSize.width/2) - (self.bounds.size.width/2);
图表:
|------------------------self.contentSize.width------------------------|
|-----self.width-----|
|-------- offset --------|
^ center
使用以下代码:
CGFloat newContentOffsetX = (scrollView.contentSize.width - scrollView.frame.size.width) / 2;
scrollView.contentOffset = CGPointMake(newContentOffsetX, 0);
Swift 4 滚动至滚动视图的内容中心
let centerOffsetX = (scrollView.contentSize.width - scrollView.frame.size.width) / 2
let centerOffsetY = (scrollView.contentSize.height - scrollView.frame.size.height) / 2
let centerPoint = CGPoint(x: centerOffsetX, y: centerOffsetY)
scrollView.setContentOffset(centerPoint, animated: true)
不是最好的解决方案,但可能对您有效
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self centerScrollViewAnimated:NO];
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
[self centerScrollViewAnimated:YES];
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
*targetContentOffset = [self suggestedCenteredContentOffset];
}
- (CGPoint)suggestedCenteredContentOffset {
CGSize imageSize = self.pickedImage.size;
CGSize containerSize = self.zoomingScrollView.bounds.size;
CGPoint result = self.zoomingScrollView.contentOffset;
if ( self.zoomingScrollView.zoomScale * imageSize.width < containerSize.width )
result.x = MIN((self.zoomingScrollView.zoomScale * imageSize.width - containerSize.width)/2, 0);
if ( self.zoomingScrollView.zoomScale * imageSize.height < containerSize.height )
result.y = MIN((self.zoomingScrollView.zoomScale * imageSize.height - containerSize.height)/2, 0);
return result;
}
- (void)centerScrollViewAnimated:(BOOL)animated {
[self.zoomingScrollView setContentOffset:[self suggestedCenteredContentOffset] animated:animated];
}
-(void)ViewDidLayoutSubView{
[超级视图布局子视图];
[self-centerScrollViewAnimated:否];
}
-(无效)ScrollViewDiEndZooming:(UIScrollView*)带视图的scrollView:(UIView*)按比例查看:(CGFloat)比例{
[self-centerScrollViewAnimated:是];
}
-(void)ScrollViewWillendDraging:(UIScrollView*)带速度的scrollView:(CGPoint)速度目标内容偏移量:(inout CGPoint*)目标内容偏移量{
*targetContentOffset=[self-suggestedCenteredContentOffset];
}
-(CGPoint)建议的中心内容偏移量{
CGSize imageSize=self.pickedImage.size;
CGSize containerSize=self.zoomingScrollView.bounds.size;
CGPoint结果=self.zoomingScrollView.contentOffset;
if(self.zoomingScrollView.zoomScale*imageSize.width
我创建了一个简单的UIScrollView扩展,它具有IBInspectable属性,可以水平和/或垂直地将内容居中。只有当scrollview内容大小小于scrollview大小时,它才起作用
以下是Swift 5.2代码:
import UIKit
@IBDesignable class CenteredScrollView: UIScrollView {
@IBInspectable var verticallyCentered: Bool = false
@IBInspectable var horizontallyCentered: Bool = false
override var contentSize: CGSize {
didSet {
if contentSize.height <= bounds.height && verticallyCentered {
centerVertically()
}
if contentSize.width <= bounds.width && horizontallyCentered {
centerHorizontally()
}
}
}
private func centerVertically() {
let yContentOffset = (contentSize.height / 2) - (bounds.size.height / 2)
contentOffset = CGPoint(x: contentOffset.x, y: yContentOffset)
}
private func centerHorizontally() {
let xContentOffset = (contentSize.width / 2) - (bounds.size.width / 2)
contentOffset = CGPoint(x: xContentOffset, y: contentOffset.y)
}
}
导入UIKit
@IBDesignable类中心滚动视图:UIScrollView{
@IBInspectable var verticallyCentered:Bool=false
@IBInspectable var HorizontallyCenter:Bool=false
覆盖变量contentSize:CGSize{
迪塞特{
如果contentSize.heightSwift 5+
@IBDesignable class CenteredScrollView: UIScrollView {
@IBInspectable var isVerticallyCentered: Bool = false
@IBInspectable var isHorizontallyCentered: Bool = false
public func center(vertically: Bool, horizontally:Bool, animated: Bool) {
guard vertically || horizontally else {
return
}
var offset = contentOffset
if vertically && contentSize.height <= bounds.height {
offset.y = (contentSize.height / 2) - (bounds.size.height / 2)
}
if horizontally && contentSize.width <= bounds.width {
offset.x = (contentSize.width / 2) - (bounds.size.width / 2)
}
setContentOffset(offset, animated: animated)
}
override func layoutSubviews() {
super.layoutSubviews()
center(vertically: isVerticallyCentered, horizontally: isHorizontallyCentered, animated: false)
}
}
@IBDesignable class CenteredScrollView:UIScrollView{
@IBInspectable var垂直居中:Bool=false
@IBInspectable var isHorizontallyCentered:Bool=false
公共函数中心(垂直:布尔,水平:布尔,动画:布尔){
垂直防护| |水平防护{
返回
}
var offset=contentOffset
如果垂直(&contentSize.height),请对“self.width”表示抱歉混乱。这是我用UIView分类添加的快捷方式。为什么要使用self.bounds而不是self.frame?我怀疑self.width
不是真正的问题,而是你想从contentSize.width
中减去它-但我习惯性地使用了self.bounds
。self.bounds.size
和self.frame.size
应该相同;我倾向于使用self.bounds
除非我需要使用self.frame.origin
获得的相对于superview的原点。