2015-07-21 52 views
1

我試圖做一些類似的WhatsApp爲具有調整大小基於contentsize並在右下角有日期的單元格的消息......問題是,我不知道該矩形被排除的路徑位置,因爲文字是動態的,我有這樣的事情,但僅適用於多條線路的作品,而不是一行:的UITextView exclusionPaths右下角

whatsapp messages window

NSString *[email protected]"I'm writing ";//a text renderer using Core Text, and I discovered I’ll need to wrap text around objects (such as is done in any DTP program). I couldn’t find any easy answers as to how to do this in the documentation, so having finally got it working I’ll share what I did. To lay out text in a custom shape in Core Text, you can pass a CGPath in when you create your CTFramesetterRef. Originally this only supported rectangular paths, but now it supports fully custom paths. My first thought was to see if I could subtract the region to wrap around from the path for my frame’s border, and pass the result in to Core Text as a path. It turns out firstly that subtracting one path from another in Core Graphics is not trivial. However, if you simply add two shapes to the same path, Core Graphics can use a winding rule to work out which areas to draw. Core Text, at least as of iOS 4.2, can also use this kind of algorithm. This will work for many cases: if you can guarantee that your object to be wrapped will be fully inside the frame (and not overlapping the edge), just go ahead and add its border to the same path as your frame, and Core"; // Text will do the rest."; 

txtText.text=txt; 

CGSize textFrame = [txtText sizeThatFits:CGSizeMake(235, MAXFLOAT)]; 

UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(textFrame.width-35, textFrame.height-20, 35, 20)]; 
txtText.textContainer.exclusionPaths = @[imgRect]; 

textFrame = [txtText sizeThatFits:CGSizeMake(235, MAXFLOAT)]; 

//int frameWidth=375; 

txtText.frame=CGRectIntegral(CGRectMake(10, 10, textFrame.width, textFrame.height)); 
lblHour.frame=CGRectIntegral(CGRectMake(textFrame.width-35, textFrame.height-15, 35, 20)); 

viewCanvasAround.frame=CGRectIntegral(CGRectMake(50, 100, textFrame.width+20, textFrame.height+20)); 
+0

@Catalin嗨,你有沒有發現一個適當的解 – adnako

+0

不,沒有,離開它像@adnako – Catalin

+1

一個聰明的傢伙告訴我,它的尾巴使用NSAttributed串用透明的矩形作爲具有相同大小的時間視圖框。它工作完美。 – adnako

回答

0

有一個很好的解決方案,我的同事發現在actor.im中。 https://github.com/actorapp/actor-platform/blob/master/actor-sdk/sdk-core-ios/ActorSDK/Sources/Controllers/Content/Conversation/Cell/AABubbleTextCell.swift#L312

let container = YYTextContainer(size: CGSizeMake(maxTextWidth, CGFloat.max)) 

    textLayout = YYTextLayout(container: container, text: attributedText)! 

    // print("Text Layouted") 

    // Measuring text and padded text heights 
    let textSize = textLayout.textBoundingSize 

    if textLayout.lines.count == 1 { 
     if textLayout.textBoundingSize.width < maxTextWidth - timeWidth { 
      // 
      // <line_0> <date> 
      // 
      bubbleSize = CGSize(width: textSize.width + timeWidth, height: textSize.height) 
     } else { 

      // 
      // <line_________0> 
      //   <date> 
      // 
      bubbleSize = CGSize(width: textSize.width, height: textSize.height + 16) 
     } 
    } else { 
     let maxWidth = textSize.width 
     let lastLine = textLayout.lines.last!.width 
     if lastLine + timeWidth < maxWidth { 
      // 
      // <line_________0> 
      // <line_________1> 
      // .. 
      // <line_n> <date> 
      // 
      bubbleSize = textSize 
     } else if lastLine + timeWidth < maxTextWidth { 
      // 
      // |------------------| 
      // <line______0> 
      // <line______1> 
      // .. 
      // <line______n> <date> 
      // 
      bubbleSize = CGSize(width: max(lastLine + timeWidth, maxWidth), height: textSize.height) 
     } else { 
      // 
      // <line_________0> 
      // <line_________1> 
      // .. 
      // <line_________n> 
      //   <date> 
      // 
      bubbleSize = CGSize(width: max(timeWidth, maxWidth), height: textSize.height + 16) 
     } 
    } 
0

我有同樣的問題(對我來說是在右上角一個按鈕),而且我怎麼解決它的辦法:

- (void)viewWillLayoutSubviews { 
    [super viewWillLayoutSubviews]; 
    [self updateTextExclusionPaths]; 
} 

- (void)updateTextExclusionPaths { 
    // Remove old exclusionPaths to calculate right rects of new 
    textView.textContainer.exclusionPaths = @[]; 
    // Force textView to layout the text without exclusionPaths 
    [textView.layoutManager glyphRangeForTextContainer:textView.textContainer]; 

    /// Because of some specifics of my implementation I had a problem with wrong frame of my button. So I calculated it manually 
    // Calculate new exclusionPaths 
    CGRect buttonFrameInTextView = [superViewOfTextView convertRect:button.frame toView:textView]; 

    // Calculate textView.text size without any exclusionPaths to calculate right button frame 
    CGSize textViewSize = [textView sizeThatFits:CGSizeMake(textView.frame.size.width, CGFLOAT_MAX)]; 
    // Update Y position of button 
    buttonFrameInTextView.origin.y = size.height - buttonFrameInTextView.size.height; 

    // Add new exclusionPaths 
    UIBezierPath *buttonRectBezierPath = [UIBezierPath bezierPathWithRect:buttonFrameInTextView]; 
    textView.textContainer.exclusionPaths = @[ buttonRectBezierPath ]; 
}