Center text vertically in a UITextView

2019-01-05 00:17发布

I want to center the text vertically inside a big UITextView that fills the whole screen - so that when there's little of text, say a couple of words, it is centered by height. It's not a question about centering the text (a property that can be found in IB) but about putting the text vertically right in the middle of UITextView if the text is short, so there are no blank areas in the UITextView. Can this be done? Thanks in advance!

17条回答
家丑人穷心不美
2楼-- · 2019-01-05 00:45

I have also this problem and I solved it with a UITableViewCell with UITextView. I created method in a custom UITableViewCell subclass, property statusTextView:

- (void)centerTextInTextView
{
    CGFloat topCorrect = ([self.statusTextView bounds].size.height - [self.statusTextView contentSize].height * [self.statusTextView zoomScale])/2.0;
    topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
    self.statusTextView.contentOffset = (CGPoint){ .x = 0, .y = -topCorrect };

And call this method in methods:

- (void)textViewDidBeginEditing:(UITextView *)textView
- (void)textViewDidEndEditing:(UITextView *)textView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

This solution worked for me with no issues, you can try it.

查看更多
Animai°情兽
3楼-- · 2019-01-05 00:46

Swift 3:

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        textField.frame = self.view.bounds

        var topCorrect : CGFloat = (self.view.frame.height / 2) - (textField.contentSize.height / 2)
        topCorrect = topCorrect < 0.0 ? 0.0 : topCorrect
        textField.contentInset = UIEdgeInsetsMake(topCorrect,0,0,0)

    }
查看更多
贼婆χ
4楼-- · 2019-01-05 00:47

Because UIKit is not KVO compliant, I decided to implement this as a subclass of UITextView which updates whenever the contentSize changes.

It's a slightly modified version of Carlos's answer which sets the contentInset instead of the contentOffset. In addition to being compatible with iOS 9, it also seems to be less buggy on iOS 8.4.

class VerticallyCenteredTextView: UITextView {
    override var contentSize: CGSize {
        didSet {
            var topCorrection = (bounds.size.height - contentSize.height * zoomScale) / 2.0
            topCorrection = max(0, topCorrection)
            contentInset = UIEdgeInsets(top: topCorrection, left: 0, bottom: 0, right: 0)
        }
    }
}
查看更多
欢心
5楼-- · 2019-01-05 00:48

UITextView+VerticalAlignment.h

//  UITextView+VerticalAlignment.h
//  (c) The Internet 2015
#import <UIKit/UIKit.h>

@interface UITextView (VerticalAlignment)

- (void)alignToVerticalCenter;
- (void)disableAlignment;

@end

UITextView+VerticalAlignment.m

#import "UITextView+VerticalAlignment.h"

@implementation UITextView (VerticalAlignment)

- (void)alignToVerticalCenter {
    [self addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:NULL];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    UITextView *tv = object;
    CGFloat topCorrect = ([tv bounds].size.height - [tv contentSize].height * [tv zoomScale])/2.0;
    topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
    tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
}

- (void)disableAlignment {
    [self removeObserver:self forKeyPath:@"contentSize"];
}
@end
查看更多
何必那么认真
6楼-- · 2019-01-05 00:51

Auto-layout solution:

  1. Create a UIView that acts as a container for the UITextView.
  2. Add the following constraints:
    • TextView: Align leading space to: Container
    • TextView: Align trailing space to: Container
    • TextView: Align center Y to: Container
    • TextView: Equal Height to: Container, Relation: ≤
查看更多
何必那么认真
7楼-- · 2019-01-05 00:55
func alignTextVerticalInTextView(textView :UITextView) {

    let size = textView.sizeThatFits(CGSizeMake(CGRectGetWidth(textView.bounds), CGFloat(MAXFLOAT)))

    var topoffset = (textView.bounds.size.height - size.height * textView.zoomScale) / 2.0
    topoffset = topoffset < 0.0 ? 0.0 : topoffset

    textView.contentOffset = CGPointMake(0, -topoffset)
}
查看更多
登录 后发表回答