Размещение кнопки в качестве подвида рядом с последним символом UILable/UITextView

Я использовал четыре UITextview для размещения каждого абзаца. Теперь я хочу добавить UIButton в качестве подвида для каждого UITextview.

Я понял, что создание подвида с фреймом CGRectMake(textview.frame.width-50,textview.frame.height-20,50,20) не является идеальным решением, потому что предложение может заканчиваться где угодно, я имею в виду, что последний символ любого абзаца может заканчиваться где угодно, хотя его позиция не постоянна.

Итак, суть в том, что я хочу добавить UIButton в UITextView рядом со словом lats. Как мне это сделать?

Любое решение будет высоко оценено. :)


person Master Stroke    schedule 16.01.2013    source источник


Ответы (3)


Это не так просто. С использованием:

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, у которого нет таких вставок контента.

person LombaX    schedule 18.01.2013
comment
Да, вам не нужен -16, если вы используете UILabel, в этом случае нет места на полях ;-) Рад слышать, что вы решили свою проблему! Удачного кодирования ;-) - person LombaX; 19.01.2013

Вам следует рассмотреть возможность использования UIWebView или некоторых сторонних текстовых представлений с атрибутами, которые поддерживают такие функции.

UITextView внутренне использует веб-представление, что делает нетривиальной задачей выяснить точное расположение текста.

person ZhangChn    schedule 16.01.2013

Я думаю, что лучше использовать tableView. Один абзац в одной ячейке. Сделайте ячейку без рамки и установите clearColor для фона ячейки. Таким образом, вы можете легко добавить кнопку.

person Yurec Antidipresant    schedule 18.01.2013