IOS 7 UITextView вертикальное выравнивание

Как возможно, что мой редактируемый UITextView (помещенный внутри простого UIViewController внутри UISplitView, который действует как делегат для UITextView), не показывает текст с самого начала, а после чего-то вроде 6-7 строк?

Screenshot

Я не установил какой-либо определенный автоспуск или что-то подобное, попытка удалить текст не поможет (так что никаких скрытых символов или чего-то еще).

Я использую iOS 7 на iPad, в раскадровке выглядит хорошо... Проблема на симуляторе iOS и реальных устройствах одинакова. Я злюсь: P

Вот какой код. Это 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
}

И вот переопределенные функции для UITextView Я использую какой-то код, который я нашел в StackOverflow, чтобы имитировать местозаполнитель для представления (тот же материал на iPhone версии раскадровки отлично работает)...

// 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

Попробуйте вызвать -sizeToFit после передачи текста. Этот ответ может быть полезен Вертикально выравнивать текст в UILabel.
[UPDATE]
Я обновляю этот ответ, чтобы сделать его более читаемым.
Проблема в том, что из iOS7 контроллеры представления контейнеров, такие как UINavigationController или UITabbarController, могут изменять вставки содержимого прокрутки (или представления, которые наследуются от нее), чтобы избежать перекрытия содержимого. Это происходит только в том случае, если scrollview является основным видом или первым подзоном. Чтобы избежать этого, вы должны отключить это поведение, установив automaticallyAdjustsScrollViewInsets в NO или переопределив этот метод, чтобы вернуть NO.

Ответ 2

У меня возникла такая же проблема.

Решено, отключив автоматическую настройку вложений scrollView:

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

Ответ 3

Это довольно распространенная проблема, поэтому я бы создал простой подкласс UITextView, чтобы вы могли повторно использовать его и использовать его в IB.

Вместо этого я использовал бы contentInset, убедившись, что изящно обработайте случай, когда contentSize больше, чем границы 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

Ответ 5

Вдохновленный Kiattisak, я выполнил вертикальное выравнивание как категорию над UITextView, чтобы вы могли контролировать вертикальное выравнивание устаревшего UITextView.

Вы можете найти здесь здесь.

Ответ 6

У меня была такая же проблема с iOS 8.1, и ни одно из этих предложений не работало.

Что нужно было сделать в Раскадке и перетащить мой UITableView или UITextView, чтобы он больше не был первым подзором моего экрана UIView.

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

Кажется, что он связан с наличием UIView, встроенного в UINavigationController.

Ошибка? Ошибка? Я сказал "ошибка"...?

; -)

Ответ 7

Быстрая версия ответа Tanguy.G:

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

Ответ 8

Проверьте верхнюю вставку содержимого textView в -viewDidLoad:

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

Reset он в раскадровке, если он не равен нулю