Ser*_*yov 64 iphone xcode objective-c uitextview ios
我希望将文本垂直放在一个UITextView
填满整个屏幕的大的内部- 这样当几乎没有文字时,说几句话,它就是以高度为中心.这不是关于文本居中(可以在IB中找到的属性)的问题,而是关于如果文本很短则将文本垂直放在中间的问题,因此在文本中没有空白区域.可以这样做吗?提前致谢!UITextView
UITextView
CSo*_*naM 61
首先添加观察者,以获取加载视图时的contentSize
键值UITextView
:
- (void) viewDidLoad {
[textField addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
[super viewDidLoad];
}
Run Code Online (Sandbox Code Playgroud)
然后添加此方法以在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};
}
Run Code Online (Sandbox Code Playgroud)
Sen*_*ful 48
因为UIKit不符合KVO,所以我决定将其作为子类实现UITextView
,每当contentSize
更改时都会更新.
这是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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
Ben*_*o85 25
如果您不想使用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);
}
Run Code Online (Sandbox Code Playgroud)
并称之为
-(void)textViewDidChange:(UITextView *)textView{
[self adjustContentSize:textView];
}
Run Code Online (Sandbox Code Playgroud)
每次编辑代码中的文本.不要忘记将控制器设置为代理
Swift 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)
}
Run Code Online (Sandbox Code Playgroud)
s.k*_*.ka 20
适用于iOS 9.0.2.我们需要设置contentInset.如果我们KVO是contentOffset,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];
}
Run Code Online (Sandbox Code Playgroud)
我分别使用0,0和0作为左,右和右边缘插图.确保为您的用例计算这些.
mal*_*lex 17
NSLayoutManager
这是用于获取实际文本大小的简单任务NSTextContainer
class VerticallyCenteredTextView: UITextView {
override func layoutSubviews() {
super.layoutSubviews()
let rect = layoutManager.usedRect(for: textContainer)
let topInset = (bounds.size.height - rect.height) / 2.0
textContainerInset.top = max(0, topInset)
}
}
Run Code Online (Sandbox Code Playgroud)
不要在最终计算中使用contentSize
and 。contentInset
这是一个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
}
}
Run Code Online (Sandbox Code Playgroud)
我刚刚在 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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
参考:https : //geek-is-stupid.github.io/2017-05-15-how-to-center-text-vertically-in-a-uitextview/
您可以仅使用约束直接设置它:
我添加了3个约束来在约束中垂直和水平对齐文本,如下所示:
小智 5
我也有这个问题,我用 with 解决了UITableViewCell
它UITextView
。我在自定义UITableViewCell
子类属性中创建了方法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 };
Run Code Online (Sandbox Code Playgroud)
并在methods中调用这个方法:
- (void)textViewDidBeginEditing:(UITextView *)textView
- (void)textViewDidEndEditing:(UITextView *)textView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Run Code Online (Sandbox Code Playgroud)
这个解决方案对我来说没有问题,你可以尝试一下。
小智 5
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)
}
Run Code Online (Sandbox Code Playgroud)
我有一个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
Run Code Online (Sandbox Code Playgroud)
斯威夫特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)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
58297 次 |
最近记录: |