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

XCODE/Swift Autolayout ScrollView with dynamic label, textview etc. How set scrollview height based on textview

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

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

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

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)

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

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

self.textViewHeightConstraint.constant = sizeThatFits.height;

滚动视图在自动布局方面有点复杂,这使得使用它们更加困难。

故事板中的 textView 可能有宽度和高度限制(否则 scrollView 的 contentSize 警告将不明确)。

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

首先,您需要在 viewController:

中根据 UITextView 高度限制创建一个插座
@interface ViewController ()

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

@end

然后,在 viewDidLoad 中,您将自己添加为 textView

contentSize 属性 的观察者
- (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

如果您使用 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")
    }
}