iOS 7 UITextView vertical alignment

别来无恙 提交于 2019-11-26 09:36:01

问题


How is that possible that my editable UITextView (placed inside a straightforward UIViewController inside a UISplitView that acts as delegate for the UITextView) is not showing text from the beginning but after something like 6-7 lines?

\"Screenshot\"

I didn\'t set any particular autolayout or something similar, trying to delete text doesn\'t help (so no hidden chars or something).

I\'m using iOS 7 on iPad, in storyboard looks good... The problem is the same on iOS simulator and real devices. I\'m getting mad :P

Here\'s some code. This is the ViewController viewDidLoad()

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.itemTextField.delegate = self;
    self.itemTextField.text = NSLocalizedString(@\"NEWITEMPLACEHOLDER\", nil);
    self.itemTextField.textColor = [UIColor lightGrayColor]; //optional
}

And here are the overridden functions for the UITextView I\'m using some code I\'ve found on StackOverflow to simulate a placeholder for the view (the same stuff on iPhone version of the storyboard works fine)...

// UITextView placeholder
- (void)textViewDidBeginEditing:(UITextView *)textView
{
    if ([textView.text isEqualToString:NSLocalizedString(@\"NEWITEMPLACEHOLDER\", nil)]) {
        textView.text = @\"\";
        textView.textColor = [UIColor blackColor]; //optional
    }
    [textView becomeFirstResponder];
}

- (void)textViewDidEndEditing:(UITextView *)textView
{
    if ([textView.text isEqualToString:@\"\"]) {
        textView.text = NSLocalizedString(@\"NEWITEMPLACEHOLDER\", nil);
        textView.textColor = [UIColor lightGrayColor]; //optional
    }
    [textView resignFirstResponder];
}

-(void)textViewDidChange:(UITextView *)textView
{
    int len = textView.text.length;
    charCount.text = [NSString stringWithFormat:@\"%@: %i\",  NSLocalizedString(@\"CHARCOUNT\", nil),len];
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    return YES;
}

回答1:


Try to call -sizeToFit after passing the text. This answer could be useful to Vertically align text within a UILabel.
[UPDATE]
I update this answer o make it more readable.
The issue is that from iOS7, container view controllers such as UINavigationController or UITabbarController can change the content insets of scroll views (or views that inherit from it), to avoid content overlapping. This happens only if the scrollview is the main view or the first subviews. To avoid that you should disable this behavior by setting automaticallyAdjustsScrollViewInsets to NO, or overriding this method to return NO.




回答2:


I got through the same kind of issue.

Solved it by disabling the automatic scrollView insets adjustement :

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")){
    self.automaticallyAdjustsScrollViewInsets = NO; // Avoid the top UITextView space, iOS7 (~bug?)
}



回答3:


This is a fairly common problem, so I would create a simple UITextView subclass, so that you can re-use it and use it in IB.

I would used the contentInset instead, making sure to gracefully handle the case where the contentSize is larger than the bounds of the textView

@interface BSVerticallyCenteredTextView : UITextView

@end

@implementation BSVerticallyCenteredTextView

- (id)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame])
    {
        [self addObserver:self forKeyPath:@"contentSize" options:  (NSKeyValueObservingOptionNew) context:NULL];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder])
    {
        [self addObserver:self forKeyPath:@"contentSize" options:  (NSKeyValueObservingOptionNew) context:NULL];
    }
    return self;
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"contentSize"])
    {
        UITextView *tv = object;
        CGFloat deadSpace = ([tv bounds].size.height - [tv contentSize].height);
        CGFloat inset = MAX(0, deadSpace/2.0);
        tv.contentInset = UIEdgeInsetsMake(inset, tv.contentInset.left, inset, tv.contentInset.right);
    }  
}

- (void)dealloc
{
    [self removeObserver:self forKeyPath:@"contentSize"];
}

@end



回答4:


use -observerForKeyPath with contentSize KeyPath

Look some code at My Blog (don't focus on Thai Language)

http://www.macbaszii.com/2012/10/ios-dev-uitextview-vertical-alignment.html




回答5:


Inspired by Kiattisak, I've implemented vertical alignment as a category over UITextView so that you can control the vertical alignment of legacy UITextView.

You can find it as a gist here.




回答6:


I had the same issue with iOS 8.1, and none of these suggestions worked.

What did work was to go into the Storyboard, and drag my UITableView or UITextView so that it was no longer the first subview of my screen's UIView.

http://www.codeproject.com/Tips/852308/Bug-in-XCode-Vertical-Gap-Above-UITableView

It seems to be linked to having a UIView embedded in a UINavigationController.

Bug ? Bug ? Did I say "bug" ...?

;-)




回答7:


Swift version of Tanguy.G's answer:

if(UIDevice.currentDevice().systemVersion >= "7.0") {
            self.automaticallyAdjustsScrollViewInsets = false; // Avoid the top UITextView space, iOS7 (~bug?)
  }



回答8:


Check top content inset of textView in -viewDidLoad:

NSLog(@"NSStringFromUIEdgeInsets(self.itemTextField.contentInset) = %@", NSStringFromUIEdgeInsets(self.itemTextField.contentInset));

Reset it in storyboard if it is not zero



来源:https://stackoverflow.com/questions/19468417/ios-7-uitextview-vertical-alignment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!