【问题标题】:Placing button as subview just next to the UILable/UITextView's last character将按钮作为子视图放置在 UILabel/UITextView 最后一个字符旁边
【发布时间】:2026-01-27 21:50:02
【问题描述】:

我使用了四个 UITextview 来放置每个段落。现在我想添加一个 UIButton 作为每个 UITextview 的子视图。

我意识到创建带有框架CGRectMake(textview.frame.width-50,textview.frame.height-20,50,20) 的子视图并不是一个理想的解决方案,因为句子可能在任何地方结束,我的意思是任何段落的最后一个字符可能在任何地方结束,但它的位置不是恒定的。

所以底线是,我想在 UITextView 中添加 UIButton,就在 lats 单词旁边。我该怎么做?

任何解决方案将不胜感激。 :)

【问题讨论】:

    标签: iphone ios objective-c uitextview


    【解决方案1】:

    事情没那么简单。 使用:

    CGSize sizeOfString = [string sizeWithFont:self.aTextView.font constrainedToSize:self.aTextView.frame.size];
    

    您可以获得给定字符串的 CGSize。 但是,给出整个字符串,将导致大小等于您的 UITextView 大小(所以,右下角)

    你必须在每个 UITextField 的最后一行使用这个方法...这是困难的部分。自动换行由 CoreText 完成,UITextView 或 UILabel 不会为您提供有关单行、位置等的信息。

    你必须自己计算它做一些类似的事情(代码不是很干净,如果你有问题理解我会帮助你):

    NSAttributedString* text = self.aTextView.attributedText;
    CTFramesetterRef fs =
    CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)text);
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, CGRectMake(0,0,self.aTextView.frame.size.width - 16,100000));  // why the -16? the frame should be the REAL TEXT FRAME, not the UITextView frame. If you look, there is a space between the view margin and the text. This is the baseline. Probably there is a method to calculate it programatically, but I can't check now. In my case it seems like 8px (*2)
    CTFrameRef f = CTFramesetterCreateFrame(fs, CFRangeMake(0, 0), path, NULL);
    CTFrameDraw(f, NULL);
    
    NSRange lastRange;
    NSArray* lines = (__bridge NSArray*)CTFrameGetLines(f);
    
    id lastLineInArray = [lines lastObject];
    CTLineRef theLine = (__bridge CTLineRef)lastLineInArray;
    CFRange range = CTLineGetStringRange(theLine);
    lastRange.length = range.length;
    lastRange.location = range.location - 1;
    NSLog(@"%ld %ld", range.location, range.length);
    
    CGPathRelease(path);
    CFRelease(f);
    CFRelease(fs);
    
    // this is the last line
    NSString *lastLine = [self.aTextView.text substringWithRange:lastRange];
    

    现在,您可以使用:

    CGSize sizeOfString = [lastLine sizeWithFont:self.aTextView.font constrainedToSize:self.aTextView.frame.size];

    您将获得字符串的宽度和高度,然后是您的按钮的最终位置(对于 y 位置:取自行数数组的行数 * 字符串高度)

    编辑:关于 UITextView 中的左侧空间的注释(此行中有 -16 的原因)

    CGPathAddRect(path, NULL, CGRectMake(0,0,self.aTextView.frame.size.width - 16,100000));
    

    这是因为文本实际上并不在 UITextView 内,而是在它的一个子视图内:一个 UIWebDocumentView(私有类),它添加了一个插图。经过一番搜索,我找不到任何方法来(合法地)获取此插图的值,这是将正确的矩形传递给 CGPathAddRect() 函数所必需的。 您可以进行一些测试以确保它始终为 8pt :-) 或切换到没有该内容插入的 UILabel

    【讨论】:

    • 是的,如果您使用 UILabel,则不需要 -16,在这种情况下没有边距空间;-) 很高兴听到您解决了问题!快乐编码 ;-)
    【解决方案2】:

    您应该考虑使用 UIWebView 或一些支持此类功能的第三方属性文本视图。

    UITextView 在内部使用 Web 视图,这使得找出文本的确切布局成为一项不平凡的工作。

    【讨论】:

      【解决方案3】:

      我认为,使用 tableView 的更好方法。一个单元格中的一个段落。使单元格无边框并将 clearColor 设置为单元格背景。通过这种方式,您可以轻松添加按钮。

      【讨论】: