Я знаю, что это старый пост, но выравнивание текста по вертикали - ОГРОМНАЯ проблема (по крайней мере, для меня), и я решил, что должен поделиться этим решением, так как сам не смог его найти.
Использование drawRect немного дорого, на мой взгляд. Правильный способ заставить UILabel выровнять по вертикали - не использовать UILabel. Используйте UITextView (многострочное UITextField) и наблюдайте за свойством содержимого так:
- (UITextView*)textView{
if(!_textView){
UIEdgeInsets insets = UIEdgeInsetsMake(0, 50, 0, 5);
CGRect frame = CGRectMake(0.0f, 0.0f, 100.0f, 100.0f);
_textView = [[UITextView alloc]initWithFrame:UIEdgeInsetsInsetRect(frame, insets)];
_textView.delegate = self;
_textView.scrollEnabled = YES;
_textView.bounces = YES;
_textView.backgroundColor = [UIColor whiteColor];
[_textView setUserInteractionEnabled:NO];
[_textView addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
}
return _textView;
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change: (NSDictionary *)change context:(void *)context {
UITextView *tv = object;
CGFloat height = [tv bounds].size.height;
CGFloat contentheight;
#ifdef __IPHONE_7_0
contentheight = [tv sizeThatFits:CGSizeMake(tv.frame.size.width, FLT_MAX)].height;
#else
contentheight = [tv contentSize].height;
#endif
switch(self.verticalAlignment) {
case VerticalAlignmentBottom:{
CGFloat topCorrect = ([tv bounds].size.height - contentheight);
topCorrect = (topCorrect <0.0 ? 0.0 : topCorrect);
tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
}
break;
case VerticalAlignmentMiddle:{
CGFloat topCorrect = (height - contentheight * [tv zoomScale])/2.0;
topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
}
break;
case VerticalAlignmentTop:{
tv.contentOffset = (CGPoint){.x = 0, .y = 0 };
}
break;
default:
break;
}
}
В основном, что здесь происходит, мы устанавливаем класс, в котором мы находимся, в качестве наблюдателя, просматривая свойство contentSize с параметром NSKeyValueObservingOptionNew, чтобы при каждом изменении содержимого вызывался -(void)observeValueForKeyPath:ofObject:change:context:
, а затем вы могли вычислить смещение размер, чтобы выровнять текст соответствующим образом.
Я не могу взять кредит на себя, оригинальная идея пришла от здесь . Но это решение не работает на iOS7. Пройдя несколько часов по SO, я обнаружил следующее: Исправление вертикального выравнивания iOS 7 . Ключевая строка там contentheight = [tv sizeThatFits:CGSizeMake(tv.frame.size.width, FLT_MAX)].height;
. По какой-то причине в iOS 7 получение высоты contentSize не работает, но это исправляет. Ни одно из двух решений не сработало само по себе, но после небольшого изменения я смог объединить вышеприведенное решение.