在 viewDidLoad 中设置 NSAttributedString 会导致 Scrollview 在文本中间而不是顶部开始

Posted

技术标签:

【中文标题】在 viewDidLoad 中设置 NSAttributedString 会导致 Scrollview 在文本中间而不是顶部开始【英文标题】:Setting NSAttributedString in viewDidLoad causes Scrollview to start in the middle of text rather than top 【发布时间】:2014-09-26 22:09:23 【问题描述】:

我在设置视图控制器的 AttributedString(连接到 UITextView)时遇到了一个有趣的问题。

在 ViewDidLoad 中,我有以下内容覆盖了我拥有的占位符文本;

 - (void)viewDidLoad

    [super viewDidLoad];
    self.contentView.attributedText = self.attributedString

这会导致滚动视图从显示的文本的中间开始,而不是顶部。

我尝试通过将 [self.contentView setContentOffset:CGPointMake(0,0) animated:NO] 也放入 viewDidLoad 来向上移动滚动视图,但这不起作用。有趣的是,我在设置了AttributeText之后,打印出了当前y位置的CGFloat,它打印出了0。

奇怪的是,我添加了相同的代码来打印 viewDidAppear 中当前 y 位置的 CGFloat,它是 384(屏幕中间)。然后我添加了 [self.contentView setContentOffset:CGPointMake(0,0) animated:NO] 果然它向上滚动了。

有人知道为什么会这样吗?以及如何让它在 viewDidLoad 中滚动到顶部?

谢谢

【问题讨论】:

【参考方案1】:

猜测:在viewDidLoad,控制器的视图还没有调整大小。它将被加载,然后调整到屏幕的边界。 UITextView 正在智能地尝试在调整大小时保持相同的粗略文本区域显示。如果它显示中间,那么我猜你的故事板或 NIB 比你正在显示的设备大,但这不是猜测的基础。

这可能有点绝望,但也许抛弃viewDidLoad 并选择:

- (void)viewWillAppear

    if(![self.contentView.attributedText isEqual:self.attributedString])
        [self updateContentViewString];


- (void)setAttributedString:(NSAttributedString *)string

    _attributedString = [string copy]; // or no copy, as you prefer
    [self updateContentViewString];


- (void)updateContentViewString

    self.contentView.attributedText = self.attributedString;
    self.contentView.contentOffset = CGPointMake(0.0, 0.0);

如果你想假设一旦视图控制器可见,文本就不会更新,或者让它变得更简单。

【讨论】:

感谢您的努力,但这似乎不起作用。文本仍然出现在中间/底部附近。我现在开始认为这更像是一个自动布局问题...... 我说的太粗了:我们是在谈论滚动视图似乎滚动到中心的一大块文本,还是水平居中而不是顶部对齐的一小块文本? 我应该说,我的错!这是一大块文本,滚动视图似乎已滚动到其中心。 布局发生在viewWillAppear: 之后(顺便说一句,这需要一个参数)。试试viewDidLayoutSubviewsviewDidAppear: 把 self.contentView.contentOffset = CGPointMake(0.0, 0.0);在 viewDidLayoutSubviews 方法中使它起作用了!谢谢【参考方案2】:

如果您希望在加载 ViewController 时滚动到 contentView 的顶部:

override func viewDidLayoutSubviews() 
        super.viewDidLayoutSubviews()

        // Can add an if statement HERE to limit when you wish to scroll to top
        contentView.setContentOffset(.zero, animated: false)

【讨论】:

以上是关于在 viewDidLoad 中设置 NSAttributedString 会导致 Scrollview 在文本中间而不是顶部开始的主要内容,如果未能解决你的问题,请参考以下文章

在 Xcode 4.3 中设置属性值不固定/viewDidLoad 被多次调用

在 iOS 7 上,在 viewDidLoad 中设置图层变换会破坏自动布局

为什么不要在viewDidLoad方法中设置开始监听键盘通知

在标签栏控制器中设置视图控制器

如何在情节提要中设置 UINavigationController 的委托

swift:在导航栏中设置后退按钮图像