ios 在 UITextView 中垂直居中文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12591192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Center text vertically in a UITextView
提问by Sergey Grischyov
I want to center the text verticallyinside 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 verticallyright in the middle of UITextView
ifthe text is short, so there are no blank areas in the UITextView
.
Can this be done? Thanks in advance!
我想将文本垂直居中放置在UITextView
填充整个屏幕的大文本中- 这样当文本很少时,比如说几个词,它以高度为中心。这不是关于居中文本(可以在 IB 中找到的属性)的问题,而是关于如果文本很短则将文本垂直放在中间的问题,因此. 这能做到吗?提前致谢!UITextView
UITextView
采纳答案by CSolanaM
First add an observer for the contentSize
key value of the UITextView
when the view is loaded:
首先为视图加载时的contentSize
key值添加一个观察者UITextView
:
- (void) viewDidLoad {
[textField addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
[super viewDidLoad];
}
Then add this method to adjust the contentOffset
every time the contentSize
value changes:
然后添加此方法以在contentOffset
每次contentSize
值更改时进行调整:
-(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};
}
回答by Senseful
Because UIKit is not KVO compliant, I decided to implement this as a subclass of UITextView
which updates whenever the contentSize
changes.
因为UIKit 不是 KVO 兼容的,我决定将它作为一个子类来实现,UITextView
它会在contentSize
发生变化时更新。
It's a slightly modified version of Carlos's answerwhich 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.
这是Carlos 答案的略微修改版本,它设置contentInset
了contentOffset
. 除了与 iOS 9 兼容之外,它在 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)
}
}
}
回答by Beninho85
If you don't want to use KVO you can also manually adjust offset with exporting this code to a function like this :
如果您不想使用 KVO,您还可以通过将此代码导出到这样的函数来手动调整偏移量:
-(void)adjustContentSize:(UITextView*)tv{
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);
}
and calling it in
并调用它
-(void)textViewDidChange:(UITextView *)textView{
[self adjustContentSize:textView];
}
and every time you edit the text in the code. Don't forget to set the controller as the delegate
每次编辑代码中的文本时。不要忘记将控制器设置为委托
Swift 3 version:
斯威夫特 3 版本:
func adjustContentSize(tv: UITextView){
let deadSpace = tv.bounds.size.height - tv.contentSize.height
let inset = max(0, deadSpace/2.0)
tv.contentInset = UIEdgeInsetsMake(inset, tv.contentInset.left, inset, tv.contentInset.right)
}
func textViewDidChange(_ textView: UITextView) {
self.adjustContentSize(tv: textView)
}
回答by s.ka
For iOS 9.0.2. we'll need to set the contentInset instead. If we KVO the contentOffset, iOS 9.0.2 sets it to 0 at the last moment, overriding the changes to contentOffset.
对于 iOS 9.0.2。我们需要改为设置 contentInset。如果我们对 contentOffset 进行 KVO,iOS 9.0.2 在最后一刻将其设置为 0,覆盖对 contentOffset 的更改。
-(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 setContentInset:UIEdgeInsetsMake(topCorrect,0,0,0)];
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:NO];
[questionTextView addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
}
I used 0,0, and 0 for the left,bottom and right edge insets respectively. Make sure to calculate those as well for your use case.
我分别将 0,0 和 0 用于左侧、底部和右侧边缘插入。确保也为您的用例计算这些。
回答by Rudolf Adamkovi?
Here's a UITextView
extension that centers content vertically:
这是一个UITextView
垂直居中内容的扩展:
extension UITextView {
func centerVertically() {
let fittingSize = CGSize(width: bounds.width, height: CGFloat.max)
let size = sizeThatFits(fittingSize)
let topOffset = (bounds.size.height - size.height * zoomScale) / 2
let positiveTopOffset = max(0, topOffset)
contentOffset.y = -positiveTopOffset
}
}
回答by KOTIOS
You can set it up directly with only constraints:
您可以仅使用约束直接设置它:
There are 3 constraints i added to align text vertically and horizontally in constraints as below :
我添加了 3 个约束来在约束中垂直和水平对齐文本,如下所示:
- Make height 0 and add constraints greater than
- Add vertically align to parent constraints
- Add horizontally align to parent constraints
- 使高度为 0 并添加大于
- 添加垂直对齐到父约束
- 添加水平对齐到父约束
回答by user1687195
I have a textview that I'm using with autolayout and with setting the lineFragmentPadding
and textContainerInset
to zero. None of the solutions above worked in my situation. However, this works for me. Tested with iOS 9
我有一个TextView,我使用与自动布局与设置lineFragmentPadding
和textContainerInset
为零。上述解决方案都不适用于我的情况。但是,这对我有用。用 iOS 9 测试
@interface VerticallyCenteredTextView : UITextView
@end
@implementation VerticallyCenteredTextView
-(void)layoutSubviews{
[self recenter];
}
-(void)recenter{
// using self.contentSize doesn't work correctly, have to calculate content size
CGSize contentSize = [self sizeThatFits:CGSizeMake(self.bounds.size.width, CGFLOAT_MAX)];
CGFloat topCorrection = (self.bounds.size.height - contentSize.height * self.zoomScale) / 2.0;
self.contentOffset = CGPointMake(0, -topCorrection);
}
@end
回答by Tai Le
I just created a custom vertically centered text view in Swift 3:
我刚刚在 Swift 3 中创建了一个自定义的垂直居中文本视图:
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)
}
}
}
Ref: https://geek-is-stupid.github.io/2017-05-15-how-to-center-text-vertically-in-a-uitextview/
参考:https: //geek-is-stupid.github.io/2017-05-15-how-to-center-text-vertically-in-a-uitextview/
回答by arnaldito100
Swift 3:
斯威夫特 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)
}
回答by Ievgen
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)
}