XCODE/Swift Autolayout ScrollView with dynamic label, textview etc. 如何根据 textview 设置滚动视图高度

Posted

技术标签:

【中文标题】XCODE/Swift Autolayout ScrollView with dynamic label, textview etc. 如何根据 textview 设置滚动视图高度【英文标题】:XCODE/Swift Autolayout ScrollView with dynamic label, textview etc. How set scrollview height based on textview 【发布时间】:2015-04-14 07:36:53 【问题描述】:

我正在使用:Swift、自动布局并在情节提要中创建所有视图。我确实以编程方式修改内容。 我有以下设计;黑框是图片,图片下方是日期和主题,下方是标题,在底部我有一个从网络资源加载的文本视图。我在 textview 上禁用了滚动,因为我只希望滚动视图滚动。 那么解决这个问题的最佳方法是什么,这样我就可以滚动到文本视图的底部,向我展示所有的文本?

我的想法是在将内容加载到其中后以某种方式检索 textview 的 contentheight (ViewDidLoad)。然后将此添加到从 textview 的原始高度中减去的滚动视图的高度。但必须说,对于我认为是标准功能的东西来说似乎很难。 对此有何想法?

到目前为止,我的代码看起来确实像这样,但它似乎不起作用:

override func viewDidAppear(animated: Bool)
 
    println("Height: \(self.textView.frame.height)") // prints 222.0
    let contentSize = self.textView.sizeThatFits(self.textView.bounds.size)
    var frame = textView.frame
    frame.size.height = contentSize.height
    textView.frame = frame
    println("Height: \(self.textView.frame.height)") // prints 283.5
 
override func viewDidLoad() 

    super.viewDidLoad()
    self.textView.layoutIfNeeded()
    println("Height: \(self.textView.frame.height)")  //prints 222.0

    //self.textView.delegate = self

代码示例2:

let sizeThatFits = CGSizeMake(self.textView.frame.size.width, CGFloat(MAXFLOAT))
    //CGSize sizeThatFits = [self.textView sizeThatFits:CGSizeMake(self.textView.frame.size.width, MAXFLOAT)]
    self.textViewHeight = sizeThatFits.height

错误信息:NSNumber 不是 NSLayoutConstraint 的子类型。

下面的语法似乎没问题。 代码示例 3:

self.textView.addObserver(self, forkeypath: "contentSize", options: NSKeyValueObservingOptions, context: nil)

【问题讨论】:

您是如何创建视图的?故事板或代码?你在使用自动布局吗? 故事板,使用代码修改内容并使用自动布局。 Tnx。 【参考方案1】:

当涉及到自动布局时,滚动视图有点复杂,这使得使用它们变得更加困难。

您可能在情节提要中为您的 textView 设置了宽度和高度限制(否则您将在 scrollView 中收到不明确的 contentSize 警告)。

我为您的问题找到了解决方案,刚刚试了一下,效果很好。

首先,您需要在 viewController 中从 UITextView 高度约束创建一个插座:

@interface ViewController ()

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewHeightConstraint;

@end

然后,在 viewDidLoad 中,您将自己添加为 textViewcontentSize 属性的观察者

- (void)viewDidLoad 
    [super viewDidLoad];
    // All you other stuff ...

    [self.textView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionInitial context:nil];

然后在observeValueForKeyPath 中,更新textView 的高度约束,如下所示:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
    [self.textViewHeightConstraint setConstant:self.textView.contentSize.height];

然后不要忘记删除观察者,以免崩溃

- (void)dealloc 
    [self.textView removeObserver:self forKeyPath:@"contentSize"];

为此,您必须确保具有从 textViewscrollView 的顶部和底部偏移约束。

如果您需要更多帮助,请告诉我。


更新 - 斯威夫特

如果你使用 swift,你的实现应该是这样的

class YourViewController: UIViewController 

    @IBOutlet weak var textView: UITextView!
    @IBOutlet weak var textViewHeightConstraint: NSLayoutConstraint!

    override
    func viewDidLoad ()
        textView.addObserver(self, forKeyPath: "contentSize", options:NSKeyValueObservingOptions.New, context: nil)
    

    override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) 
        textViewHeightConstraint.constant = textView.contentSize.height
    

    deinit 
        self.textView.removeObserver(self, forKeyPath: "contentSize")
    

【讨论】:

谢谢,看来我在正确的轨道上。我用代码示例 3 更新了问题。我猜想 obj-c 有问题。 那么,你让它工作了吗?还是你还有问题? 不。还是麻烦:代码示例3,放在viewController的viewDidLoad方法中。我应该把“observeValueForKeyPath”放在哪里?那么删除观察者功能呢,我应该把它放在哪里? 我已经用 swift 中的一些示例代码更新了我的答案。 Catalina T. 非常感谢 :-) 它有效。只是为了掌握它——我实际上可以使用这个函数来寻找其他高度限制的变化,对吧?【参考方案2】:

您可以将文本视图的高度约束作为 IBOutlet 添加到您的文件中。加载后,简单更新一下:

CGSize sizeThatFits = [self.textView sizeThatFits:CGSizeMake(self.textview.frame.size.width, MAXFLOAT)];

self.textViewHeightConstraint.constant = sizeThatFits.height;

【讨论】:

以上是关于XCODE/Swift Autolayout ScrollView with dynamic label, textview etc. 如何根据 textview 设置滚动视图高度的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Xcode 6.1.1 Swift 代码转换为 Xcode 6.4 Swift 代码?

目标 C 项目中的 Xcode 8.3 Swift 版本错误 (SWIFT_VERSION)

拖放到 Xcode 后无法读取 JSON 文件 - Xcode/Swift

Xcode 8 / Swift 3 - 类型“CGColorRenderingIntent”没有成员“RenderingIntentDefault”

Xcode 7.0 Swift 更新问题

viewDidLoad 函数未在 Xcode 6.2 swift 应用程序中调用,但在 OS X 上的 Xcode 6.4 swift 应用程序中调用