UITextView textContainer exclusion path fails if full width and positioned at top of textContainer

后端 未结 5 1322
余生分开走
余生分开走 2021-01-01 22:46

In iOS 8, I\'m trying to add a UIImageView as a subview of a UITextView, similar to what\'s shown here - but with the text below the image.

相关标签:
5条回答
  • 2021-01-01 23:08

    A quick workaround:

    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;
    }
    

    Your image will still draw the same and unless you're using a font with glyphs that are 1px wide (I'm not even sure that's possible given kerning, etc), your exclusionRect will be guaranteed to be smaller than the full width.

    I would be interested to know what kind of results you see if you allow your rect to be moved around in real-time. Attach a UIPanGestureRecognizer and update your exclusionRect as you pan around the screen. At what point does the text jump into the image?

    Edit: If you're seeing problems until it is able to fit at least one character, maybe try adjusting your text frame.

    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 讨论(0)
  • 2021-01-01 23:15

    I came across this problem as well. If you only need to exclude full width space at the top or bottom of the textView, you can use the textContainerInset.

    0 讨论(0)
  • 2021-01-01 23:21

    Workaround suggestion:

    Add a line break to your text.

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

    0 讨论(0)
  • 2021-01-01 23:23

    This is an old bug.In the book Pushing the Limits iOS 7 Programming ,the author wrote this in page 377:

    At the time of writing, Text Kit does not correctly handle some kinds of exclusion paths. In particular, if your exclusion paths would force some lines to be empty, the entire layout may fail. For example, if you attempt to lay out text in a circle this way, the top of the circle may be too small to include any text, and NSLayoutManager will silently fail. This limitation impacts all uses of NSTextContainer. Specifically, if lineFragmentRectForProposedRect:atIndex:writingDirection:remainingRect: ever returns an empty CGRect, the entire layout will fail.

    Maybe you can override lineFragmentRectForProposedRect:atIndex:writingDirection:remainingRect: of your custom NSTextContainer to workaround.

    0 讨论(0)
  • 2021-01-01 23:24

    I tried too hard toying with exclusion path.

    My problem was that top level exclusion path never worked, it pushed content towards the top instead of center, while bottom content had double the exclusion path margin.

    Here is what worked for me:

    1. Override UITextView
    2. Init it with your textcontainer by putting this inside init:

      super.init(frame: frame, textContainer: textContainer)

    3. As per Daniel's answer, put inside layoutSubviews:

      self.textContainerInset = UIEdgeInsets.init(top: t, left: l, bottom: b, right: r)

    4. Inside your UITextView subclass init() or in storyboard, disable scrolling.

      self.isScrollEnabled = false

    For more details, read this super-helpful thread.

    0 讨论(0)
提交回复
热议问题