2014-10-29 3 views
13

iOS 8에서는 UITextView의 하위보기로 UIImageView를 추가하려고합니다. 여기에 표시된 것과 비슷하지만 이미지 아래의 텍스트가 있습니다.전체 너비 및 텍스트 컨테이너의 상단에 위치하는 경우 UITextView textContainer 제외 경로가 실패합니다.

enter image description here

나는 다른 장치에, 나는 이미지가 다르게 화면의 크기에 따라 위치 수 있기 때문에 제외 경로를 사용하고 싶어.

그러나 제외 경로를 만드는 데 사용 된 CGRect의 Y 출발점이 0이고 textView의 전체 너비를 차지하는 경우 제외가 실패하고 텍스트가 제외 경로 내에 표시되므로 텍스트가 제외 경로에 표시됩니다. 그 스크린 샷에서 볼 수 있듯이 imageView 뒤에 표시됩니다.)

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // set up the textView 
    CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); 
    UITextView *textView = [[UITextView alloc] initWithFrame:frame]; 
    [textView setFont:[UIFont systemFontOfSize:36.0]]; 
    [self.view addSubview:textView]; 
    textView.text = @"I wish this text appeared below the exclusion rect and not within it."; 


    // add the photo 

    CGFloat textViewWidth = textView.frame.size.width; 

    // uncomment if you want to see that the exclusion path DOES work when not taking up the full width: 
    // textViewWidth = textViewWidth/2.0; 

    CGFloat originY = 0.0; 

    // uncomment if you want to see that the exclusion path DOES work if the Y origin isn't 0 
    // originY = 54.0; 

    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"photo_thumbnail"]]; 
    imageView.frame = CGRectMake(0, originY, textViewWidth, textViewWidth); 
    imageView.alpha = 0.7; // just so you can see that the text is within the exclusion path (behind photo) 
    [textView addSubview:imageView]; 


    // set the exclusion path (to the same rect as the imageView) 
    CGRect exclusionRect = [textView convertRect:imageView.bounds fromView:imageView]; 
    UIBezierPath *exclusionPath = [UIBezierPath bezierPathWithRect:exclusionRect]; 
    textView.textContainer.exclusionPaths = @[exclusionPath]; 
} 

가 나는 또한 NSTextContainer를 서브 클래스와 -lineFragmentRectForProposedRect 방법을 무시했지만, 거기 Y 원점을 조정 :

내가 다음으로는 "단일보기"엑스 코드 템플릿을 사용하여 간단한 응용 프로그램을 구축이를 테스트하려면 어느 쪽도 도움이되지 않는 것 같습니다.

사용자 정의 NSTextContainer을 사용하려면, 내가 UITextView가있는 viewDidLoad()에서이 같은 스택 설정 :

다음
// set up the textView stack 
NSTextStorage *textStorage = [[NSTextStorage alloc] init]; 

NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; 
[textStorage addLayoutManager:layoutManager]; 

CGSize containerSize = CGSizeMake(self.view.frame.size.width, CGFLOAT_MAX); 
CustomTextContainer *textContainer = [[CustomTextContainer alloc] initWithSize:containerSize]; 
[layoutManager addTextContainer:textContainer]; 

CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); 
UITextView *textView = [[UITextView alloc] initWithFrame:frame textContainer:textContainer]; 
[textView setFont:[UIFont systemFontOfSize:36.0]]; 
[self.view addSubview:textView]; 

textView.text = @"I wish this text appeared below the exclusion rect and not within it."; 

나는이 같은 CustomTextContainer의 Y 원점을 조정 ...하지만이 같은 화려 단지 실패 :

- (CGRect)lineFragmentRectForProposedRect:(CGRect)proposedRect atIndex:(NSUInteger)characterIndex writingDirection:(NSWritingDirection)baseWritingDirection remainingRect:(CGRect *)remainingRect { 

    CGRect correctedRect = proposedRect; 

    if (correctedRect.origin.y == 0) { 
     correctedRect.origin.y += 414.0; 
    } 

    correctedRect = [super lineFragmentRectForProposedRect:correctedRect atIndex:characterIndex writingDirection:baseWritingDirection remainingRect:remainingRect]; 

    NSLog(@"origin.y: %f | characterIndex: %lu", correctedRect.origin.y, (unsigned long)characterIndex); 

    return correctedRect; 
} 

난이 (내가 뭔가를 분명 누락하지 않는 한) 내가보고해야 애플 버그로 간주 될 수도있을 것 같군요하지만 아무도 해결 방법이 있다면 그것은 매우 감사하겠습니다.

+0

동일한 현상이 발생합니다 (iOS8). 이것은 나에게 애플 버그처럼 보인다. 성공한 해결 방법을 찾은 사람이 있으면 이야기하십시오! –

+0

또 다른 해결 방법은 스토리 보드 레이아웃을 사용하고 다른 화면 크기 클래스에 대해 이미지, 텍스트 및 제약 조건을 다르게 배치하는 것입니다. – Tim

+0

아니요, 버그가 아닙니다. exclusionPaths를 두 번 확인하고 rect가 textView.textContainer에 포함되어 있는지 확인하면됩니다. @GeoffH,'textview.textContainerInset' 및'textView.textContainer.lineFragmentPadding' 및'textView.contentInset'도 검사해야합니다. –

답변

2

빠른 해결 방법 :

CGRect exclusionRect = [textView convertRect:imageView.bounds fromView:imageView]; 
if (exclusionRect.origin.x <= 0 && exclusionRect.origin.y <= 0 && exclusionRect.size.width >= textView.bounds.size.width) { 
    exclusionRect.origin.x = 1; 
    exclusionRect.origin.y = 1; 
    exclusionRect.size.width -= 2; 
} 

이미지가 여전히 동일한을 그릴 것입니다 당신이 넓은 x 1 픽셀입니다 글리프와 함께 글꼴을 사용하지 않는 (나는 그 등을 할 수 주어진 커닝에도 확실하지 않다) exclusionRect은 전체 너비보다 작을 것으로 보장됩니다.

rect를 실시간으로 이동할 수있게하면 어떤 결과가 나타나는 지 알고 싶습니다. UIPanGestureRecognizer을 첨부하고 화면 주위를 두 드리면서 exclusionRect을 업데이트하십시오. 텍스트는 어느 시점에서 이미지로 점프합니까?

편집 : 적어도 하나의 문자를 넣을 수있을 때까지 문제가 발생하면 텍스트 프레임을 조정 해보십시오.

if (exclusionRect.origin.x <= 0 && exclusionRect.origin.y <= 0 && exclusionRect.size.width >= textView.bounds.size.width) { 
    frame.origin.y += CGRectGetMaxY(exclusionRect); 
    frame.size.height -= CGRectGetMaxY(exclusionRect); 
    [textView setFrame:frame]; 
} 
+0

불행히도 그것은 작동하지 않는 것 같습니다. origin.x 또는 origin.y를 조정하여 문자가 왼쪽 또는 위쪽을 따라 표시되기에 충분할만큼 (글꼴 크기에 따라) 충분히 똑같은 방식으로 실패합니다. –

+0

textView 프레임을 조정하려 시도했지만 imageView도 아래로 밀었습니다. 나는 또한 textContainer.size.height를 조정하려고 시도했지만 읽기 전용이기 때문에 할 수 없습니다. 못생긴 해결 방법은 imageView를 self.view의 하위 뷰 대신 제안 된대로 textView 프레임을 조정하는 것입니다. textView가 스크롤 될 때 imageView의 위치를 ​​조정하십시오. 확실하지 않은 나는 아직하고 싶지 않더라도. 어쨌든, 정말 제안을 주셔서 감사합니다. –

+0

또한 textView 프레임 조정을 시도한 다음 간단히 imageView의 Y 원점을 조정하여 (음의 Y 원점을 제공) 이동 시켰습니다. 그러나 대부분의 이미지가 있어야하는 빈 공백이 있습니다. –

1

해결 방법 제안 :

텍스트에 줄 바꿈을 추가합니다.

textView.text = "\n" + textView.text

3

이 오래된 버그입니다. 프로그래밍 한계 아이폰 OS 7을 누르면 책 에서, 저자는 377 페이지에 쓴 : 글을 쓰는 시점에서

, 텍스트 키트가 제대로 제외 경로의 일부 종류를 처리하지 않습니다. 특히, 제외 경로가 일부 행을 비게하는 경우 전체 레이아웃이 실패 할 수 있습니다. 예를 들어이 방법으로 원 안에 텍스트를 배치하려고하면 원의 상단이 너무 작아 텍스트를 포함 할 수 없으며 NSLayoutManager가 자동으로 실패합니다. 이 제한은 NSTextContainer의 모든 사용에 영향을 미칩니다. 특히 lineFragmentRectForProposedRect : atIndex : writingDirection : remainingRect : 빈 CGRect를 반환하면 전체 레이아웃이 실패합니다.

어쩌면 당신은 lineFragmentRectForProposedRect:atIndex:writingDirection:remainingRect을 무시할 수 있습니다 : 해결하기 위해 사용자 정의 NSTextContainer의 을.

+0

... 위 ... 나는이 문제에 대한 다른 접근법을 선택했다. – CQM

1

이 문제도 발생했습니다. textView의 상단 또는 하단에서 전체 너비 공간 만 제외해야하는 경우 textContainerInset을 사용할 수 있습니다.