UITextView에서 세로로 텍스트 가운데 맞춤
전체 화면을 채우는 큰 내부에 텍스트를 세로 로 가운데에 배치하여 텍스트 UITextView
가 거의 없을 때 (예 : 몇 단어) 높이를 기준으로 가운데에 배치합니다. 텍스트 (IB에서 찾을 수있는 속성)를 중앙 에 배치하는 것에 대한 질문이 아니라 텍스트가 짧은 경우 텍스트를 세로로 오른쪽에 배치 하여 . 할 수 있습니까? 미리 감사드립니다!UITextView
UITextView
먼저 뷰가로드 될 때의 contentSize
키 값에 대한 관찰자를 추가합니다 UITextView
.
- (void) viewDidLoad {
[textField addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
[super viewDidLoad];
}
그런 다음이 메서드를 추가 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};
}
UIKit은 KVO와 호환되지 않기 때문에 변경 UITextView
될 때마다 업데이트 되는 하위 클래스로 구현하기로 결정했습니다 contentSize
.
그것은 약간 수정 된 버전의 카를로스의 대답 세트 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)
}
}
}
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);
}
그리고 그것을 호출
-(void)textViewDidChange:(UITextView *)textView{
[self adjustContentSize:textView];
}
그리고 코드의 텍스트를 편집 할 때마다. 컨트롤러를 델리게이트로 설정하는 것을 잊지 마십시오
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)
}
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];
}
왼쪽, 아래쪽 및 오른쪽 가장자리 삽입에 각각 0,0 및 0을 사용했습니다. 사용 사례에 대해서도 계산하십시오.
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
}
}
제약 조건만으로 직접 설정할 수 있습니다.
다음과 같이 제약 조건에서 텍스트를 세로 및 가로로 정렬하기 위해 추가 한 3 개의 제약 조건이 있습니다.
- 높이를 0으로 만들고 다음보다 큰 제약 조건을 추가합니다.
- 상위 제약 조건에 수직 정렬 추가
- 부모 제약 조건에 수평 정렬 추가
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)
}
autolayout과 함께 사용하고 lineFragmentPadding
and textContainerInset
를 0 으로 설정하는 textview가 있습니다. 위의 솔루션 중 어느 것도 내 상황에서 작동하지 않았습니다. 그러나 이것은 나를 위해 작동합니다. 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
스위프트 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)
}
나는 또한이 문제를 가지고 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 };
그리고이 메서드를 메서드에서 호출합니다.
- (void)textViewDidBeginEditing:(UITextView *)textView
- (void)textViewDidEndEditing:(UITextView *)textView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
이 솔루션은 문제없이 저에게 효과적이었습니다. 시도해 볼 수 있습니다.
방금 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)
}
}
}
참고 : https://geek-is-stupid.github.io/2017-05-15-how-to-center-text-vertically-in-a-uitextview/
Carlos 답변에 추가하십시오. TV의 텍스트가 TV 크기보다 클 경우 텍스트를 최근에 올릴 필요가 없으므로 다음 코드를 변경하십시오.
tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
이에:
if ([tv contentSize].height < [tv bounds].size.height) {
tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
}
자동 레이아웃 솔루션 :
- UITextView의 컨테이너 역할을하는 UIView를 만듭니다.
- 다음 제약 조건을 추가합니다.
- TextView : 선행 공백 정렬 : 컨테이너
- TextView : 후행 공백 정렬 : 컨테이너
- TextView : 중앙 Y 정렬 : 컨테이너
- TextView: Equal Height to: Container, Relation: ≤
You can try below code, no observer mandatorily required. observer throws error sometimes when view deallocates. You can keep this code in viewDidLoad, viewWillAppear or in viewDidAppear anywhere.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^(void) {
UITextView *tv = txtviewDesc;
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};
});
});
I did it like this: first of all, I embedded the UITextView in an UIView (this should work for mac OS too). Then I pinned all four sides of the external UIView to the sides of its container, giving it a shape and size similar or equal to that of the UITextView. Thus I had a proper container for the UITextView. Then I pinned the left and right borders of the UITextView to the sides of the UIView, and gave the UITextView a height. Finally, I centered the UITextView vertically in the UIView. Bingo :) now the UITextView is vertically centered in the UIView, hence text inside the UITextView is vertically centered too.
I fixed this problem by creating extension to center height vertically.
SWIFT 5:
extension UITextView {
func centerContentVertically() {
let fitSize = CGSize(width: bounds.width, height: CGFloat.greatestFiniteMagnitude)
let size = sizeThatFits(fitSize)
let heightOffset = (bounds.size.height - size.height * zoomScale) / 2
let positiveTopOffset = max(0, heightOffset)
contentOffset.y = -positiveTopOffset
}
}
UITextView+VerticalAlignment.h
// UITextView+VerticalAlignment.h
// (c) The Internet 2015
#import <UIKit/UIKit.h>
@interface UITextView (VerticalAlignment)
- (void)alignToVerticalCenter;
- (void)disableAlignment;
@end
UITextView+VerticalAlignment.m
#import "UITextView+VerticalAlignment.h"
@implementation UITextView (VerticalAlignment)
- (void)alignToVerticalCenter {
[self addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:NULL];
}
- (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};
}
- (void)disableAlignment {
[self removeObserver:self forKeyPath:@"contentSize"];
}
@end
Solution for iOS10 in RubyMotion:
class VerticallyCenteredTextView < UITextView
def init
super
end
def layoutSubviews
self.recenter
end
def recenter
contentSize = self.sizeThatFits(CGSizeMake(self.bounds.size.width, Float::MAX))
topCorrection = (self.bounds.size.height - contentSize.height * self.zoomScale) / 2.0;
topCorrection = 0 if topCorrection < 0
self.contentInset = UIEdgeInsetsMake(topCorrection, 0, 0, 0)
end
end
참고 URL : https://stackoverflow.com/questions/12591192/center-text-vertically-in-a-uitextview
'Nice programing' 카테고리의 다른 글
Javascript의 사용자 입력에서 Date 객체로 시간을 구문 분석하는 가장 좋은 방법은 무엇입니까? (0) | 2020.11.22 |
---|---|
숨겨진 기능 IntelliJ IDEA (0) | 2020.11.22 |
PHP에서 후행 0을 제거하는 방법 (0) | 2020.11.22 |
문자열에서 마지막 문자 교체 (0) | 2020.11.22 |
.htaccess를 통해 http에서 https로 (0) | 2020.11.22 |